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/****************************************************************************
1390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
1490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *   Module Title :     scale.c
1590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
1690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *   Description  :     Image scaling functions.
1790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
1890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber ***************************************************************************/
1990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
2090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/****************************************************************************
2190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber*  Header Files
2290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber****************************************************************************/
2390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#include "vpx_mem/vpx_mem.h"
2490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#include "vpx_scale/yv12config.h"
2590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#include "vpx_scale/scale_mode.h"
2690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
2790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/****************************************************************************
2890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber*  Exports
2990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber****************************************************************************/
3090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#ifndef VPX_NO_GLOBALS
3190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervoid (*vp8_vertical_band_4_5_scale)(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width) = 0;
3290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervoid (*vp8_last_vertical_band_4_5_scale)(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width) = 0;
3390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervoid (*vp8_vertical_band_2_3_scale)(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width) = 0;
3490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervoid (*vp8_last_vertical_band_2_3_scale)(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width) = 0;
3590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervoid (*vp8_vertical_band_3_5_scale)(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width) = 0;
3690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervoid (*vp8_last_vertical_band_3_5_scale)(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width) = 0;
3790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervoid (*vp8_vertical_band_3_4_scale)(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width) = 0;
3890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervoid (*vp8_last_vertical_band_3_4_scale)(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width) = 0;
3990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervoid (*vp8_horizontal_line_1_2_scale)(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width) = 0;
4090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervoid (*vp8_horizontal_line_3_5_scale)(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width) = 0;
4190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervoid (*vp8_horizontal_line_3_4_scale)(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width) = 0;
4290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervoid (*vp8_horizontal_line_2_3_scale)(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width) = 0;
4390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervoid (*vp8_horizontal_line_4_5_scale)(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width) = 0;
4490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervoid (*vp8_vertical_band_1_2_scale)(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width) = 0;
4590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervoid (*vp8_last_vertical_band_1_2_scale)(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width) = 0;
4690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
4790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervoid (*vp8_vertical_band_5_4_scale)(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width) = 0;
4890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervoid (*vp8_vertical_band_5_3_scale)(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width) = 0;
4990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervoid (*vp8_vertical_band_2_1_scale)(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width) = 0;
5090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervoid (*vp8_vertical_band_2_1_scale_i)(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width) = 0;
5190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervoid (*vp8_horizontal_line_2_1_scale)(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width) = 0;
5290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervoid (*vp8_horizontal_line_5_3_scale)(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width) = 0;
5390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervoid (*vp8_horizontal_line_5_4_scale)(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width) = 0;
5490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#else
5590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber# include "vpxscale_nofp.h"
5690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif
5790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
5890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubertypedef struct
5990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{
6090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int     expanded_frame_width;
6190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int     expanded_frame_height;
6290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
6390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int HScale;
6490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int HRatio;
6590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int VScale;
6690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int VRatio;
6790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
6890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    YV12_BUFFER_CONFIG *src_yuv_config;
6990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    YV12_BUFFER_CONFIG *dst_yuv_config;
7090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
7190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber} SCALE_VARS;
7290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
7390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/****************************************************************************
7490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
7590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  ROUTINE       :     horizontal_line_copy
7690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
7790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  INPUTS        :     None
7890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
7990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
8090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  OUTPUTS       :     None.
8190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
8290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  RETURNS       :     None
8390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
8490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  FUNCTION      :     1 to 1 scaling up for a horizontal line of pixles
8590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
8690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  SPECIAL NOTES :     None.
8790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
8890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  ERRORS        :     None.
8990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
9090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber ****************************************************************************/
9190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic
9290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervoid horizontal_line_copy(
9390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    const unsigned char *source,
9490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int source_width,
9590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned char *dest,
9690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int dest_width
9790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber)
9890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{
9990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    (void) dest_width;
10090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
10190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    duck_memcpy(dest, source, source_width);
10290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
10390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/****************************************************************************
10490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
10590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  ROUTINE       :     null_scale
10690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
10790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  INPUTS        :     None
10890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
10990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
11090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  OUTPUTS       :     None.
11190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
11290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  RETURNS       :     None
11390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
11490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  FUNCTION      :     1 to 1 scaling up for a vertical band
11590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
11690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  SPECIAL NOTES :     None.
11790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
11890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  ERRORS        :     None.
11990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
12090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber ****************************************************************************/
12190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic
12290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervoid null_scale(
12390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned char *dest,
12490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int dest_pitch,
12590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int dest_width
12690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber)
12790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{
12890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    (void) dest;
12990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    (void) dest_pitch;
13090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    (void) dest_width;
13190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
13290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    return;
13390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
13490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
13590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/****************************************************************************
13690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
13790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  ROUTINE       : scale1d_2t1_i
13890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
13990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  INPUTS        : const unsigned char *source : Pointer to data to be scaled.
14090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  int source_step              : Number of pixels to step on in source.
14190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  unsigned int source_scale    : Scale for source (UNUSED).
14290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  unsigned int source_length   : Length of source (UNUSED).
14390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  unsigned char *dest         : Pointer to output data array.
14490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  int dest_step                : Number of pixels to step on in destination.
14590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  unsigned int dest_scale      : Scale for destination (UNUSED).
14690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  unsigned int dest_length     : Length of destination.
14790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
14890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  OUTPUTS       : None.
14990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
15090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  RETURNS       : void
15190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
15290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  FUNCTION      : Performs 2-to-1 interpolated scaling.
15390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
15490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  SPECIAL NOTES : None.
15590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
15690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber ****************************************************************************/
15790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic
15890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervoid scale1d_2t1_i
15990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber(
16090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    const unsigned char *source,
16190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int source_step,
16290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int source_scale,
16390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int source_length,
16490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned char *dest,
16590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int dest_step,
16690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int dest_scale,
16790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int dest_length
16890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber)
16990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{
17090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int i, j;
17190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int temp;
17290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int source_pitch = source_step;
17390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    (void) source_length;
17490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    (void) source_scale;
17590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    (void) dest_scale;
17690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
17790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    source_step *= 2;
17890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    dest[0] = source[0];
17990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
18090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    for (i = dest_step, j = source_step; i < dest_length * dest_step; i += dest_step, j += source_step)
18190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
18290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        temp = 8;
18390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        temp += 3 * source[j-source_pitch];
18490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        temp += 10 * source[j];
18590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        temp += 3 * source[j+source_pitch];
18690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        temp >>= 4;
18790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        dest[i] = (char)(temp);
18890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
18990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
19090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
19190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/****************************************************************************
19290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
19390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  ROUTINE       : scale1d_2t1_ps
19490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
19590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  INPUTS        : const unsigned char *source : Pointer to data to be scaled.
19690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  int source_step              : Number of pixels to step on in source.
19790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  unsigned int source_scale    : Scale for source (UNUSED).
19890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  unsigned int source_length   : Length of source (UNUSED).
19990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  unsigned char *dest         : Pointer to output data array.
20090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  int dest_step                : Number of pixels to step on in destination.
20190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  unsigned int dest_scale      : Scale for destination (UNUSED).
20290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  unsigned int dest_length     : Length of destination.
20390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
20490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  OUTPUTS       : None.
20590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
20690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  RETURNS       : void
20790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
20890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  FUNCTION      : Performs 2-to-1 point subsampled scaling.
20990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
21090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  SPECIAL NOTES : None.
21190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
21290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber ****************************************************************************/
21390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic
21490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervoid scale1d_2t1_ps
21590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber(
21690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    const unsigned char *source,
21790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int source_step,
21890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int source_scale,
21990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int source_length,
22090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned char *dest,
22190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int dest_step,
22290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int dest_scale,
22390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int dest_length
22490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber)
22590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{
22690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int i, j;
22790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
22890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    (void) source_length;
22990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    (void) source_scale;
23090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    (void) dest_scale;
23190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
23290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    source_step *= 2;
23390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    j = 0;
23490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
23590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    for (i = 0; i < dest_length * dest_step; i += dest_step, j += source_step)
23690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        dest[i] = source[j];
23790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
23890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/****************************************************************************
23990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
24090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  ROUTINE       : scale1d_c
24190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
24290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  INPUTS        : const unsigned char *source : Pointer to data to be scaled.
24390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  int source_step              : Number of pixels to step on in source.
24490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  unsigned int source_scale    : Scale for source.
24590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  unsigned int source_length   : Length of source (UNUSED).
24690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  unsigned char *dest         : Pointer to output data array.
24790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  int dest_step                : Number of pixels to step on in destination.
24890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  unsigned int dest_scale      : Scale for destination.
24990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  unsigned int dest_length     : Length of destination.
25090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
25190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  OUTPUTS       : None.
25290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
25390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  RETURNS       : void
25490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
25590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  FUNCTION      : Performs linear interpolation in one dimension.
25690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
25790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  SPECIAL NOTES : None.
25890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
25990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber ****************************************************************************/
26090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic
26190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervoid scale1d_c
26290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber(
26390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    const unsigned char *source,
26490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int source_step,
26590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int source_scale,
26690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int source_length,
26790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned char *dest,
26890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int dest_step,
26990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int dest_scale,
27090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int dest_length
27190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber)
27290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{
27390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int i;
27490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int round_value = dest_scale / 2;
27590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int left_modifier = dest_scale;
27690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int right_modifier = 0;
27790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned char left_pixel = *source;
27890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned char right_pixel = *(source + source_step);
27990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
28090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    (void) source_length;
28190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
282538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    /* These asserts are needed if there are boundary issues... */
283538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    /*assert ( dest_scale > source_scale );*/
284538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    /*assert ( (source_length-1) * dest_scale >= (dest_length-1) * source_scale );*/
28590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
28690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    for (i = 0; i < dest_length * dest_step; i += dest_step)
28790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
28890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        dest[i] = (char)((left_modifier * left_pixel + right_modifier * right_pixel + round_value) / dest_scale);
28990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
29090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        right_modifier += source_scale;
29190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
29290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        while (right_modifier > dest_scale)
29390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        {
29490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            right_modifier -= dest_scale;
29590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            source += source_step;
29690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            left_pixel = *source;
29790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            right_pixel = *(source + source_step);
29890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
29990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
30090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        left_modifier = dest_scale - right_modifier;
30190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
30290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
30390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
30490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/****************************************************************************
30590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
30690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  ROUTINE       : Scale2D
30790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
30890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  INPUTS        : const unsigned char *source  : Pointer to data to be scaled.
30990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  int source_pitch              : Stride of source image.
31090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  unsigned int source_width     : Width of input image.
31190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  unsigned int source_height    : Height of input image.
31290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  unsigned char *dest          : Pointer to output data array.
31390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  int dest_pitch                : Stride of destination image.
31490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  unsigned int dest_width       : Width of destination image.
31590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  unsigned int dest_height      : Height of destination image.
31690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  unsigned char *temp_area      : Pointer to temp work area.
31790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  unsigned char temp_area_height : Height of temp work area.
31890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  unsigned int hscale          : Horizontal scale factor numerator.
31990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  unsigned int hratio          : Horizontal scale factor denominator.
32090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  unsigned int vscale          : Vertical scale factor numerator.
32190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  unsigned int vratio          : Vertical scale factor denominator.
32290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  unsigned int interlaced      : Interlace flag.
32390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
32490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  OUTPUTS       : None.
32590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
32690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  RETURNS       : void
32790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
32890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  FUNCTION      : Performs 2-tap linear interpolation in two dimensions.
32990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
33090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  SPECIAL NOTES : Expansion is performed one band at a time to help with
33190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  caching.
33290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
33390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber ****************************************************************************/
33490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic
33590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervoid Scale2D
33690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber(
337538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    /*const*/
33890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned char *source,
33990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int source_pitch,
34090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int source_width,
34190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int source_height,
34290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned char *dest,
34390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int dest_pitch,
34490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int dest_width,
34590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int dest_height,
34690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned char *temp_area,
34790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned char temp_area_height,
34890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int hscale,
34990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int hratio,
35090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int vscale,
35190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int vratio,
35290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int interlaced
35390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber)
35490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{
355538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    /*unsigned*/
35690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int i, j, k;
35790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int bands;
35890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int dest_band_height;
35990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int source_band_height;
36090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
36190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    typedef void (*Scale1D)(const unsigned char * source, int source_step, unsigned int source_scale, unsigned int source_length,
36290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            unsigned char * dest, int dest_step, unsigned int dest_scale, unsigned int dest_length);
36390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
36490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    Scale1D Scale1Dv = scale1d_c;
36590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    Scale1D Scale1Dh = scale1d_c;
36690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
36790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    void (*horiz_line_scale)(const unsigned char *, unsigned int, unsigned char *, unsigned int) = NULL;
36890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    void (*vert_band_scale)(unsigned char *, unsigned int, unsigned char *, unsigned int, unsigned int) = NULL;
36990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
37090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int ratio_scalable = 1;
37190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int interpolation = 0;
37290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
373538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    unsigned char *source_base; /* = (unsigned char *) ((source_pitch >= 0) ? source : (source + ((source_height-1) * source_pitch))); */
37490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned char *line_src;
37590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
37690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
37790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    source_base = (unsigned char *)source;
37890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
37990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    if (source_pitch < 0)
38090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
38190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        int offset;
38290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
38390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        offset = (source_height - 1);
38490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        offset *= source_pitch;
38590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
38690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        source_base += offset;
38790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
38890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
389538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    /* find out the ratio for each direction */
39090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    switch (hratio * 10 / hscale)
39190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
39290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    case 8:
393538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        /* 4-5 Scale in Width direction */
39490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        horiz_line_scale = vp8_horizontal_line_5_4_scale;
39590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        break;
39690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    case 6:
397538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        /* 3-5 Scale in Width direction */
39890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        horiz_line_scale = vp8_horizontal_line_5_3_scale;
39990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        break;
40090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    case 5:
401538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        /* 1-2 Scale in Width direction */
40290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        horiz_line_scale = vp8_horizontal_line_2_1_scale;
40390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        break;
40490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    default:
405538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        /* The ratio is not acceptable now */
406538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        /* throw("The ratio is not acceptable for now!"); */
40790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        ratio_scalable = 0;
40890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        break;
40990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
41090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
41190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    switch (vratio * 10 / vscale)
41290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
41390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    case 8:
414538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        /* 4-5 Scale in vertical direction */
41590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        vert_band_scale     = vp8_vertical_band_5_4_scale;
41690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        source_band_height  = 5;
41790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        dest_band_height    = 4;
41890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        break;
41990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    case 6:
420538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        /* 3-5 Scale in vertical direction */
42190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        vert_band_scale     = vp8_vertical_band_5_3_scale;
42290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        source_band_height  = 5;
42390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        dest_band_height    = 3;
42490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        break;
42590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    case 5:
426538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        /* 1-2 Scale in vertical direction */
42790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
42890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (interlaced)
42990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        {
430538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            /* if the content is interlaced, point sampling is used */
43190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            vert_band_scale     = vp8_vertical_band_2_1_scale;
43290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
43390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        else
43490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        {
43590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
43690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            interpolation = 1;
437538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            /* if the content is progressive, interplo */
43890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            vert_band_scale     = vp8_vertical_band_2_1_scale_i;
43990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
44090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
44190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
44290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        source_band_height  = 2;
44390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        dest_band_height    = 1;
44490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        break;
44590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    default:
446538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        /* The ratio is not acceptable now */
447538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        /* throw("The ratio is not acceptable for now!"); */
44890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        ratio_scalable = 0;
44990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        break;
45090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
45190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
45290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    if (ratio_scalable)
45390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
45490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (source_height == dest_height)
45590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        {
456538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            /* for each band of the image */
45790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            for (k = 0; k < (int)dest_height; k++)
45890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            {
45990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                horiz_line_scale(source, source_width, dest, dest_width);
46090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                source += source_pitch;
46190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                dest   += dest_pitch;
46290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
46390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
46490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            return;
46590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
46690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
46790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (interpolation)
46890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        {
46990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if (source < source_base)
47090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                source = source_base;
47190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
47290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            horiz_line_scale(source, source_width, temp_area, dest_width);
47390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
47490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
47590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        for (k = 0; k < (int)(dest_height + dest_band_height - 1) / dest_band_height; k++)
47690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        {
477538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            /* scale one band horizontally */
47890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            for (i = 0; i < source_band_height; i++)
47990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            {
480538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                /* Trap case where we could read off the base of the source buffer */
48190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
48290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                line_src = (unsigned char *)source + i * source_pitch;
48390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
48490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                if (line_src < source_base)
48590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    line_src = source_base;
48690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
48790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                horiz_line_scale(line_src, source_width,
48890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                 temp_area + (i + 1)*dest_pitch, dest_width);
48990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
49090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
491538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            /* Vertical scaling is in place */
49290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            vert_band_scale(temp_area + dest_pitch, dest_pitch, dest, dest_pitch, dest_width);
49390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
49490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if (interpolation)
49590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                vpx_memcpy(temp_area, temp_area + source_band_height * dest_pitch, dest_width);
49690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
497538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            /* Next band... */
49890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            source += (unsigned long) source_band_height  * source_pitch;
49990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            dest   += (unsigned long) dest_band_height * dest_pitch;
50090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
50190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
50290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        return;
50390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
50490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
50590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    if (hscale == 2 && hratio == 1)
50690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        Scale1Dh = scale1d_2t1_ps;
50790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
50890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    if (vscale == 2 && vratio == 1)
50990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
51090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (interlaced)
51190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            Scale1Dv = scale1d_2t1_ps;
51290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        else
51390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            Scale1Dv = scale1d_2t1_i;
51490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
51590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
51690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    if (source_height == dest_height)
51790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
518538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        /* for each band of the image */
51990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        for (k = 0; k < (int)dest_height; k++)
52090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        {
52190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            Scale1Dh(source, 1, hscale, source_width + 1, dest, 1, hratio, dest_width);
52290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            source += source_pitch;
52390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            dest   += dest_pitch;
52490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
52590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
52690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        return;
52790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
52890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
52990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    if (dest_height > source_height)
53090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
53190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        dest_band_height   = temp_area_height - 1;
53290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        source_band_height = dest_band_height * source_height / dest_height;
53390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
53490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    else
53590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
53690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        source_band_height = temp_area_height - 1;
53790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        dest_band_height   = source_band_height * vratio / vscale;
53890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
53990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
540538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    /* first row needs to be done so that we can stay one row ahead for vertical zoom */
54190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    Scale1Dh(source, 1, hscale, source_width + 1, temp_area, 1, hratio, dest_width);
54290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
543538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    /* for each band of the image */
54490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    bands = (dest_height + dest_band_height - 1) / dest_band_height;
54590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
54690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    for (k = 0; k < bands; k++)
54790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
548538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        /* scale one band horizontally */
54990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        for (i = 1; i < source_band_height + 1; i++)
55090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        {
55190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if (k * source_band_height + i < (int) source_height)
55290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            {
55390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                Scale1Dh(source + i * source_pitch, 1, hscale, source_width + 1,
55490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                         temp_area + i * dest_pitch, 1, hratio, dest_width);
55590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
556538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            else  /*  Duplicate the last row */
55790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            {
558538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                /* copy temp_area row 0 over from last row in the past */
55990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                duck_memcpy(temp_area + i * dest_pitch, temp_area + (i - 1)*dest_pitch, dest_pitch);
56090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
56190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
56290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
563538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        /* scale one band vertically */
56490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        for (j = 0; j < (int)dest_width; j++)
56590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        {
56690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            Scale1Dv(&temp_area[j], dest_pitch, vscale, source_band_height + 1,
56790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                     &dest[j], dest_pitch, vratio, dest_band_height);
56890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
56990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
570538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        /* copy temp_area row 0 over from last row in the past */
57190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        duck_memcpy(temp_area, temp_area + source_band_height * dest_pitch, dest_pitch);
57290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
573538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        /* move to the next band */
57490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        source += source_band_height * source_pitch;
57590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        dest   += dest_band_height * dest_pitch;
57690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
57790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
57890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
57990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/****************************************************************************
58090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
58190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  ROUTINE       :
58290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
58390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  INPUTS        : YV12_BUFFER_CONFIG *src       : Pointer to frame to be scaled.
58490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  YV12_BUFFER_CONFIG *dst       : Pointer to buffer to hold scaled frame.
58590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  unsigned char *temp_area      : Pointer to temp work area.
58690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  unsigned char temp_area_height : Height of temp work area.
58790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  unsigned int hscale          : Horizontal scale factor numerator.
58890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  unsigned int hratio          : Horizontal scale factor denominator.
58990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  unsigned int vscale          : Vertical scale factor numerator.
59090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  unsigned int vratio          : Vertical scale factor denominator.
59190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  unsigned int interlaced      : Interlace flag.
59290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
59390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  OUTPUTS       : None.
59490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
59590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  RETURNS       : void
59690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
59790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  FUNCTION      : Performs 2-tap linear interpolation in two dimensions.
59890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
59990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  SPECIAL NOTES : Expansion is performed one band at a time to help with
60090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  caching.
60190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
60290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber ****************************************************************************/
60390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervoid vp8_scale_frame
60490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber(
60590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    YV12_BUFFER_CONFIG *src,
60690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    YV12_BUFFER_CONFIG *dst,
60790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned char *temp_area,
60890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned char temp_height,
60990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int hscale,
61090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int hratio,
61190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int vscale,
61290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int vratio,
61390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int interlaced
61490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber)
61590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{
61690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int i;
61790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int dw = (hscale - 1 + src->y_width * hratio) / hscale;
61890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int dh = (vscale - 1 + src->y_height * vratio) / vscale;
61990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
620538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    /* call our internal scaling routines!! */
62190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    Scale2D((unsigned char *) src->y_buffer, src->y_stride, src->y_width, src->y_height,
62290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            (unsigned char *) dst->y_buffer, dst->y_stride, dw, dh,
62390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            temp_area, temp_height, hscale, hratio, vscale, vratio, interlaced);
62490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
62590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    if (dw < (int)dst->y_width)
62690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        for (i = 0; i < dh; i++)
62790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            duck_memset(dst->y_buffer + i * dst->y_stride + dw - 1, dst->y_buffer[i*dst->y_stride+dw-2], dst->y_width - dw + 1);
62890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
62990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    if (dh < (int)dst->y_height)
63090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        for (i = dh - 1; i < (int)dst->y_height; i++)
63190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            duck_memcpy(dst->y_buffer + i * dst->y_stride, dst->y_buffer + (dh - 2) * dst->y_stride, dst->y_width + 1);
63290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
63390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    Scale2D((unsigned char *) src->u_buffer, src->uv_stride, src->uv_width, src->uv_height,
63490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            (unsigned char *) dst->u_buffer, dst->uv_stride, dw / 2, dh / 2,
63590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            temp_area, temp_height, hscale, hratio, vscale, vratio, interlaced);
63690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
63790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    if (dw / 2 < (int)dst->uv_width)
63890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        for (i = 0; i < dst->uv_height; i++)
63990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            duck_memset(dst->u_buffer + i * dst->uv_stride + dw / 2 - 1, dst->u_buffer[i*dst->uv_stride+dw/2-2], dst->uv_width - dw / 2 + 1);
64090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
64190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    if (dh / 2 < (int)dst->uv_height)
64290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        for (i = dh / 2 - 1; i < (int)dst->y_height / 2; i++)
64390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            duck_memcpy(dst->u_buffer + i * dst->uv_stride, dst->u_buffer + (dh / 2 - 2)*dst->uv_stride, dst->uv_width);
64490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
64590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    Scale2D((unsigned char *) src->v_buffer, src->uv_stride, src->uv_width, src->uv_height,
64690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            (unsigned char *) dst->v_buffer, dst->uv_stride, dw / 2, dh / 2,
64790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            temp_area, temp_height, hscale, hratio, vscale, vratio, interlaced);
64890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
64990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    if (dw / 2 < (int)dst->uv_width)
65090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        for (i = 0; i < dst->uv_height; i++)
65190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            duck_memset(dst->v_buffer + i * dst->uv_stride + dw / 2 - 1, dst->v_buffer[i*dst->uv_stride+dw/2-2], dst->uv_width - dw / 2 + 1);
65290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
65390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    if (dh / 2 < (int) dst->uv_height)
65490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        for (i = dh / 2 - 1; i < (int)dst->y_height / 2; i++)
65590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            duck_memcpy(dst->v_buffer + i * dst->uv_stride, dst->v_buffer + (dh / 2 - 2)*dst->uv_stride, dst->uv_width);
65690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
65790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/****************************************************************************
65890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
65990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  ROUTINE       : any_ratio_2d_scale
66090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
66190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  INPUTS        : SCALE_INSTANCE *si      : Pointer to post-processor instance (NOT USED).
66290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  const unsigned char *source : Pointer to source image.
66390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  unsigned int source_pitch    : Stride of source image.
66490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  unsigned int source_width    : Width of source image.
66590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  unsigned int source_height   : Height of source image (NOT USED).
66690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  unsigned char *dest         : Pointer to destination image.
66790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  unsigned int dest_pitch      : Stride of destination image.
66890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  unsigned int dest_width      : Width of destination image.
66990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  unsigned int dest_height     : Height of destination image.
67090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
67190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  OUTPUTS       : None.
67290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
67390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  RETURNS       : int: 1 if image scaled, 0 if image could not be scaled.
67490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
67590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  FUNCTION      : Scale the image with changing apect ratio.
67690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
67790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  SPECIAL NOTES : This scaling is a bi-linear scaling. Need to re-work the
67890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  whole function for new scaling algorithm.
67990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
68090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber ****************************************************************************/
68190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic
68290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberint any_ratio_2d_scale
68390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber(
68490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    SCALE_VARS *si,
68590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    const unsigned char *source,
68690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int source_pitch,
68790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int source_width,
68890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int source_height,
68990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned char *dest,
69090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int dest_pitch,
69190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int dest_width,
69290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int dest_height
69390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber)
69490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{
69590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int i, k;
69690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int src_band_height  = 0;
69790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int dest_band_height = 0;
69890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
699538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    /* suggested scale factors */
70090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int hs = si->HScale;
70190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int hr = si->HRatio;
70290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int vs = si->VScale;
70390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int vr = si->VRatio;
70490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
705538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    /* assume the ratios are scalable instead of should be centered */
70690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int ratio_scalable = 1;
70790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
70890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    const unsigned char *source_base = ((source_pitch >= 0) ? source : (source + ((source_height - 1) * source_pitch)));
70990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    const unsigned char *line_src;
71090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
71190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    void (*horiz_line_scale)(const unsigned char *, unsigned int, unsigned char *, unsigned int) = NULL;
71290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    void (*vert_band_scale)(unsigned char *, unsigned int, unsigned int) = NULL;
71390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    void (*last_vert_band_scale)(unsigned char *, unsigned int, unsigned int) = NULL;
71490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
71590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    (void) si;
71690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
717538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    /* find out the ratio for each direction */
71890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    switch (hr * 30 / hs)
71990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
72090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    case 24:
721538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        /* 4-5 Scale in Width direction */
72290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        horiz_line_scale = vp8_horizontal_line_4_5_scale;
72390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        break;
72490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    case 22:
725538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        /* 3-4 Scale in Width direction */
72690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        horiz_line_scale = vp8_horizontal_line_3_4_scale;
72790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        break;
72890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
72990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    case 20:
730538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        /* 4-5 Scale in Width direction */
73190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        horiz_line_scale = vp8_horizontal_line_2_3_scale;
73290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        break;
73390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    case 18:
734538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        /* 3-5 Scale in Width direction */
73590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        horiz_line_scale = vp8_horizontal_line_3_5_scale;
73690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        break;
73790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    case 15:
738538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        /* 1-2 Scale in Width direction */
73990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        horiz_line_scale = vp8_horizontal_line_1_2_scale;
74090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        break;
74190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    case 30:
742538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        /* no scale in Width direction */
74390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        horiz_line_scale = horizontal_line_copy;
74490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        break;
74590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    default:
746538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        /* The ratio is not acceptable now */
747538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        /* throw("The ratio is not acceptable for now!"); */
74890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        ratio_scalable = 0;
74990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        break;
75090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
75190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
75290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    switch (vr * 30 / vs)
75390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
75490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    case 24:
755538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        /* 4-5 Scale in vertical direction */
75690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        vert_band_scale     = vp8_vertical_band_4_5_scale;
75790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        last_vert_band_scale = vp8_last_vertical_band_4_5_scale;
75890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        src_band_height     = 4;
75990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        dest_band_height    = 5;
76090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        break;
76190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    case 22:
762538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        /* 3-4 Scale in vertical direction */
76390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        vert_band_scale     = vp8_vertical_band_3_4_scale;
76490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        last_vert_band_scale = vp8_last_vertical_band_3_4_scale;
76590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        src_band_height     = 3;
76690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        dest_band_height    = 4;
76790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        break;
76890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    case 20:
769538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        /* 2-3 Scale in vertical direction */
77090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        vert_band_scale     = vp8_vertical_band_2_3_scale;
77190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        last_vert_band_scale = vp8_last_vertical_band_2_3_scale;
77290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        src_band_height     = 2;
77390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        dest_band_height    = 3;
77490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        break;
77590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    case 18:
776538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        /* 3-5 Scale in vertical direction */
77790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        vert_band_scale     = vp8_vertical_band_3_5_scale;
77890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        last_vert_band_scale = vp8_last_vertical_band_3_5_scale;
77990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        src_band_height     = 3;
78090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        dest_band_height    = 5;
78190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        break;
78290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    case 15:
783538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        /* 1-2 Scale in vertical direction */
78490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        vert_band_scale     = vp8_vertical_band_1_2_scale;
78590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        last_vert_band_scale = vp8_last_vertical_band_1_2_scale;
78690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        src_band_height     = 1;
78790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        dest_band_height    = 2;
78890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        break;
78990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    case 30:
790538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        /* no scale in Width direction */
79190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        vert_band_scale     = null_scale;
79290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        last_vert_band_scale = null_scale;
79390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        src_band_height     = 4;
79490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        dest_band_height    = 4;
79590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        break;
79690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    default:
797538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        /* The ratio is not acceptable now */
798538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        /* throw("The ratio is not acceptable for now!"); */
79990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        ratio_scalable = 0;
80090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        break;
80190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
80290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
80390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    if (ratio_scalable == 0)
80490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        return ratio_scalable;
80590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
80690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    horiz_line_scale(source, source_width, dest, dest_width);
80790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
808538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    /* except last band */
80990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    for (k = 0; k < (dest_height + dest_band_height - 1) / dest_band_height - 1; k++)
81090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
811538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        /* scale one band horizontally */
81290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        for (i = 1; i < src_band_height; i++)
81390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        {
814538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            /* Trap case where we could read off the base of the source buffer */
81590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            line_src = source + i * source_pitch;
81690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
81790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if (line_src < source_base)
81890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                line_src = source_base;
81990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
82090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            horiz_line_scale(line_src, source_width,
82190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                             dest + i * dest_pitch, dest_width);
82290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
82390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
824538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        /* first line of next band */
825538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        /* Trap case where we could read off the base of the source buffer */
82690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        line_src = source + src_band_height * source_pitch;
82790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
82890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (line_src < source_base)
82990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            line_src = source_base;
83090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
83190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        horiz_line_scale(line_src, source_width,
83290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                         dest + dest_band_height * dest_pitch,
83390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                         dest_width);
83490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
835538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        /* Vertical scaling is in place */
83690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        vert_band_scale(dest, dest_pitch, dest_width);
83790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
838538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        /* Next band... */
83990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        source += src_band_height  * source_pitch;
84090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        dest   += dest_band_height * dest_pitch;
84190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
84290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
843538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    /* scale one band horizontally */
84490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    for (i = 1; i < src_band_height; i++)
84590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
846538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        /* Trap case where we could read off the base of the source buffer */
84790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        line_src = source + i * source_pitch;
84890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
84990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (line_src < source_base)
85090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            line_src = source_base;
85190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
85290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        horiz_line_scale(line_src, source_width,
85390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                         dest + i * dest_pitch,
85490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                         dest_width);
85590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
85690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
857538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    /* Vertical scaling is in place */
85890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    last_vert_band_scale(dest, dest_pitch, dest_width);
85990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
86090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    return ratio_scalable;
86190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
86290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
86390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/****************************************************************************
86490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
86590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  ROUTINE       : any_ratio_frame_scale
86690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
86790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  INPUTS        : SCALE_INSTANCE *si       : Pointer to post-processor instance (NOT USED).
86890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  unsigned char *frame_buffer           : Pointer to source image.
86990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  int YOffset                : Offset from start of buffer to Y samples.
87090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *                  int UVOffset               : Offset from start of buffer to UV samples.
87190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
87290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  OUTPUTS       : None.
87390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
87490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  RETURNS       : int: 1 if image scaled, 0 if image could not be scaled.
87590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
87690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  FUNCTION      : Scale the image with changing apect ratio.
87790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
87890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  SPECIAL NOTES : None.
87990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
88090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber ****************************************************************************/
88190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic
88290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberint any_ratio_frame_scale(SCALE_VARS *scale_vars, int YOffset, int UVOffset)
88390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{
88490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int i;
88590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int ew;
88690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int eh;
88790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
888538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    /* suggested scale factors */
88990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int hs = scale_vars->HScale;
89090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int hr = scale_vars->HRatio;
89190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int vs = scale_vars->VScale;
89290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int vr = scale_vars->VRatio;
89390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
89490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int ratio_scalable = 1;
89590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
89690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int sw = (scale_vars->expanded_frame_width * hr + hs - 1) / hs;
89790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int sh = (scale_vars->expanded_frame_height * vr + vs - 1) / vs;
89890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int dw = scale_vars->expanded_frame_width;
89990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int dh = scale_vars->expanded_frame_height;
90090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    YV12_BUFFER_CONFIG *src_yuv_config = scale_vars->src_yuv_config;
90190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    YV12_BUFFER_CONFIG *dst_yuv_config = scale_vars->dst_yuv_config;
90290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
90390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    if (hr == 3)
90490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        ew = (sw + 2) / 3 * 3 * hs / hr;
90590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    else
90690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        ew = (sw + 7) / 8 * 8 * hs / hr;
90790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
90890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    if (vr == 3)
90990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        eh = (sh + 2) / 3 * 3 * vs / vr;
91090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    else
91190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        eh = (sh + 7) / 8 * 8 * vs / vr;
91290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
91390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    ratio_scalable = any_ratio_2d_scale(scale_vars,
91490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        (const unsigned char *)src_yuv_config->y_buffer,
91590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        src_yuv_config->y_stride, sw, sh,
91690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        (unsigned char *) dst_yuv_config->y_buffer + YOffset,
91790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        dst_yuv_config->y_stride, dw, dh);
91890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
91990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    for (i = 0; i < eh; i++)
92090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        duck_memset(dst_yuv_config->y_buffer + YOffset + i * dst_yuv_config->y_stride + dw, 0, ew - dw);
92190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
92290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    for (i = dh; i < eh; i++)
92390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        duck_memset(dst_yuv_config->y_buffer + YOffset + i * dst_yuv_config->y_stride, 0, ew);
92490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
92590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    if (ratio_scalable == 0)
92690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        return ratio_scalable;
92790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
92890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    sw = (sw + 1) >> 1;
92990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    sh = (sh + 1) >> 1;
93090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    dw = (dw + 1) >> 1;
93190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    dh = (dh + 1) >> 1;
93290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
93390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    any_ratio_2d_scale(scale_vars,
93490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                       (const unsigned char *)src_yuv_config->u_buffer,
93590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                       src_yuv_config->y_stride / 2, sw, sh,
93690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                       (unsigned char *)dst_yuv_config->u_buffer + UVOffset,
93790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                       dst_yuv_config->uv_stride, dw, dh);
93890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
93990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    any_ratio_2d_scale(scale_vars,
94090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                       (const unsigned char *)src_yuv_config->v_buffer,
94190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                       src_yuv_config->y_stride / 2, sw, sh,
94290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                       (unsigned char *)dst_yuv_config->v_buffer + UVOffset,
94390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                       dst_yuv_config->uv_stride, dw, dh);
94490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
94590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    return ratio_scalable;
94690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
94790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
94890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/****************************************************************************
94990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
95090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  ROUTINE       : center_image
95190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
95290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  INPUTS        : SCALE_INSTANCE *si       : Pointer to post-processor instance.
95390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
95490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  OUTPUTS       : None.
95590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
95690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  RETURNS       : void
95790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
95890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  FUNCTION      : Centers the image without scaling in the output buffer.
95990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
96090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  SPECIAL NOTES : None.
96190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
96290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber ****************************************************************************/
96390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic void
96490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubercenter_image(YV12_BUFFER_CONFIG *src_yuv_config, YV12_BUFFER_CONFIG *dst_yuv_config)
96590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{
96690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int i;
96790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int row_offset, col_offset;
96890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned char *src_data_pointer;
96990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned char *dst_data_pointer;
97090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
971538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    /* center values */
97290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    row_offset = (dst_yuv_config->y_height - src_yuv_config->y_height) / 2;
97390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    col_offset = (dst_yuv_config->y_width - src_yuv_config->y_width) / 2;
97490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
975538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    /* Y's */
97690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    src_data_pointer = src_yuv_config->y_buffer;
97790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    dst_data_pointer = (unsigned char *)dst_yuv_config->y_buffer + (row_offset * dst_yuv_config->y_stride) + col_offset;
97890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
97990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    for (i = 0; i < src_yuv_config->y_height; i++)
98090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
98190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        duck_memcpy(dst_data_pointer, src_data_pointer, src_yuv_config->y_width);
98290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        dst_data_pointer += dst_yuv_config->y_stride;
98390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        src_data_pointer += src_yuv_config->y_stride;
98490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
98590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
98690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    row_offset /= 2;
98790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    col_offset /= 2;
98890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
989538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    /* U's */
99090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    src_data_pointer = src_yuv_config->u_buffer;
99190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    dst_data_pointer = (unsigned char *)dst_yuv_config->u_buffer + (row_offset * dst_yuv_config->uv_stride) + col_offset;
99290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
99390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    for (i = 0; i < src_yuv_config->uv_height; i++)
99490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
99590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        duck_memcpy(dst_data_pointer, src_data_pointer, src_yuv_config->uv_width);
99690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        dst_data_pointer += dst_yuv_config->uv_stride;
99790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        src_data_pointer += src_yuv_config->uv_stride;
99890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
99990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1000538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    /* V's */
100190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    src_data_pointer = src_yuv_config->v_buffer;
100290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    dst_data_pointer = (unsigned char *)dst_yuv_config->v_buffer + (row_offset * dst_yuv_config->uv_stride) + col_offset;
100390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
100490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    for (i = 0; i < src_yuv_config->uv_height; i++)
100590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
100690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        duck_memcpy(dst_data_pointer, src_data_pointer, src_yuv_config->uv_width);
100790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        dst_data_pointer += dst_yuv_config->uv_stride;
100890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        src_data_pointer += src_yuv_config->uv_stride;
100990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
101090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
101190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
101290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/****************************************************************************
101390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
101490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  ROUTINE       : scale_or_center
101590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
101690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  INPUTS        : SCALE_INSTANCE *si       : Pointer to post-processor instance.
101790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
101890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
101990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
102090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  OUTPUTS       : None.
102190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
102290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  RETURNS       : void
102390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
102490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  FUNCTION      : Decides to scale or center image in scale buffer for blit
102590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
102690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  SPECIAL NOTES : None.
102790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
102890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber ****************************************************************************/
102990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervoid
103090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervp8_yv12_scale_or_center
103190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber(
103290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    YV12_BUFFER_CONFIG *src_yuv_config,
103390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    YV12_BUFFER_CONFIG *dst_yuv_config,
103490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int expanded_frame_width,
103590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int expanded_frame_height,
103690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int scaling_mode,
103790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int HScale,
103890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int HRatio,
103990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int VScale,
104090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int VRatio
104190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber)
104290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{
1043538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    /*if ( ppi->post_processing_level )
1044538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber          update_umvborder ( ppi, frame_buffer );*/
104590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
104690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
104790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    switch (scaling_mode)
104890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
104990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    case SCALE_TO_FIT:
105090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    case MAINTAIN_ASPECT_RATIO:
105190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
105290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        SCALE_VARS scale_vars;
1053538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        /* center values */
105490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#if 1
105590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        int row = (dst_yuv_config->y_height - expanded_frame_height) / 2;
105690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        int col = (dst_yuv_config->y_width  - expanded_frame_width) / 2;
1057538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        /*int YOffset  = row * dst_yuv_config->y_width + col;
1058538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        int UVOffset = (row>>1) * dst_yuv_config->uv_width + (col>>1);*/
105990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        int YOffset  = row * dst_yuv_config->y_stride + col;
106090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        int UVOffset = (row >> 1) * dst_yuv_config->uv_stride + (col >> 1);
106190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#else
106290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        int row = (src_yuv_config->y_height - expanded_frame_height) / 2;
106390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        int col = (src_yuv_config->y_width  - expanded_frame_width) / 2;
106490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        int YOffset  = row * src_yuv_config->y_width + col;
106590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        int UVOffset = (row >> 1) * src_yuv_config->uv_width + (col >> 1);
106690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif
106790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
106890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        scale_vars.dst_yuv_config = dst_yuv_config;
106990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        scale_vars.src_yuv_config = src_yuv_config;
107090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        scale_vars.HScale = HScale;
107190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        scale_vars.HRatio = HRatio;
107290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        scale_vars.VScale = VScale;
107390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        scale_vars.VRatio = VRatio;
107490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        scale_vars.expanded_frame_width = expanded_frame_width;
107590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        scale_vars.expanded_frame_height = expanded_frame_height;
107690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1077538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        /* perform center and scale */
107890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        any_ratio_frame_scale(&scale_vars, YOffset, UVOffset);
107990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
108090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        break;
108190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
108290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    case CENTER:
108390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        center_image(src_yuv_config, dst_yuv_config);
108490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        break;
108590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
108690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    default:
108790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        break;
108890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
108990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
1090