1ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/* 2ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * Copyright (c) 2010 The WebM project authors. All Rights Reserved. 3ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 4ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * Use of this source code is governed by a BSD-style license 5ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * that can be found in the LICENSE file in the root of the source 6ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * tree. An additional intellectual property rights grant can be found 7ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * in the file PATENTS. All contributing project authors may 8ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * be found in the AUTHORS file in the root of the source tree. 9ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang */ 10ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 11ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 12ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/**************************************************************************** 13ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 14ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * Module Title : scale.c 15ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 16ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * Description : Image scaling functions. 17ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 18ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ***************************************************************************/ 19ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 20ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/**************************************************************************** 21ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang* Header Files 22ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang****************************************************************************/ 23ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "./vpx_scale_rtcd.h" 24ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vpx_mem/vpx_mem.h" 25ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vpx_scale/yv12config.h" 26ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 27ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangtypedef struct { 28ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int expanded_frame_width; 29ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int expanded_frame_height; 30ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 31ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int HScale; 32ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int HRatio; 33ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int VScale; 34ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int VRatio; 35ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 36ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang YV12_BUFFER_CONFIG *src_yuv_config; 37ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang YV12_BUFFER_CONFIG *dst_yuv_config; 38ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 39ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} SCALE_VARS; 40ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 41ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/**************************************************************************** 42ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 43ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * ROUTINE : scale1d_2t1_i 44ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 45ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * INPUTS : const unsigned char *source : Pointer to data to be scaled. 46ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * int source_step : Number of pixels to step on in source. 47ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * unsigned int source_scale : Scale for source (UNUSED). 48ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * unsigned int source_length : Length of source (UNUSED). 49ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * unsigned char *dest : Pointer to output data array. 50ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * int dest_step : Number of pixels to step on in destination. 51ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * unsigned int dest_scale : Scale for destination (UNUSED). 52ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * unsigned int dest_length : Length of destination. 53ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 54ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * OUTPUTS : None. 55ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 56ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * RETURNS : void 57ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 58ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * FUNCTION : Performs 2-to-1 interpolated scaling. 59ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 60ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * SPECIAL NOTES : None. 61ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 62ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ****************************************************************************/ 63ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic 64ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangvoid scale1d_2t1_i 65ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang( 66ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang const unsigned char *source, 67ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int source_step, 68ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int source_scale, 69ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int source_length, 70ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned char *dest, 71ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int dest_step, 72ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int dest_scale, 73ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int dest_length 74ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang) { 75ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int i, j; 76ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int temp; 77ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int source_pitch = source_step; 78ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang (void) source_length; 79ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang (void) source_scale; 80ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang (void) dest_scale; 81ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 82ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang source_step *= 2; 83ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang dest[0] = source[0]; 84ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 85ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for (i = dest_step, j = source_step; i < dest_length * dest_step; i += dest_step, j += source_step) { 86ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang temp = 8; 87ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang temp += 3 * source[j - source_pitch]; 88ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang temp += 10 * source[j]; 89ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang temp += 3 * source[j + source_pitch]; 90ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang temp >>= 4; 91ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang dest[i] = (char)(temp); 92ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 93ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} 94ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 95ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/**************************************************************************** 96ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 97ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * ROUTINE : scale1d_2t1_ps 98ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 99ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * INPUTS : const unsigned char *source : Pointer to data to be scaled. 100ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * int source_step : Number of pixels to step on in source. 101ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * unsigned int source_scale : Scale for source (UNUSED). 102ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * unsigned int source_length : Length of source (UNUSED). 103ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * unsigned char *dest : Pointer to output data array. 104ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * int dest_step : Number of pixels to step on in destination. 105ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * unsigned int dest_scale : Scale for destination (UNUSED). 106ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * unsigned int dest_length : Length of destination. 107ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 108ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * OUTPUTS : None. 109ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 110ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * RETURNS : void 111ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 112ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * FUNCTION : Performs 2-to-1 point subsampled scaling. 113ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 114ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * SPECIAL NOTES : None. 115ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 116ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ****************************************************************************/ 117ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic 118ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangvoid scale1d_2t1_ps 119ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang( 120ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang const unsigned char *source, 121ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int source_step, 122ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int source_scale, 123ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int source_length, 124ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned char *dest, 125ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int dest_step, 126ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int dest_scale, 127ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int dest_length 128ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang) { 129ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int i, j; 130ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 131ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang (void) source_length; 132ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang (void) source_scale; 133ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang (void) dest_scale; 134ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 135ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang source_step *= 2; 136ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang j = 0; 137ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 138ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for (i = 0; i < dest_length * dest_step; i += dest_step, j += source_step) 139ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang dest[i] = source[j]; 140ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} 141ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/**************************************************************************** 142ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 143ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * ROUTINE : scale1d_c 144ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 145ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * INPUTS : const unsigned char *source : Pointer to data to be scaled. 146ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * int source_step : Number of pixels to step on in source. 147ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * unsigned int source_scale : Scale for source. 148ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * unsigned int source_length : Length of source (UNUSED). 149ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * unsigned char *dest : Pointer to output data array. 150ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * int dest_step : Number of pixels to step on in destination. 151ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * unsigned int dest_scale : Scale for destination. 152ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * unsigned int dest_length : Length of destination. 153ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 154ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * OUTPUTS : None. 155ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 156ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * RETURNS : void 157ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 158ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * FUNCTION : Performs linear interpolation in one dimension. 159ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 160ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * SPECIAL NOTES : None. 161ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 162ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ****************************************************************************/ 163ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic 164ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangvoid scale1d_c 165ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang( 166ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang const unsigned char *source, 167ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int source_step, 168ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int source_scale, 169ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int source_length, 170ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned char *dest, 171ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int dest_step, 172ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int dest_scale, 173ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int dest_length 174ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang) { 175ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int i; 176ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int round_value = dest_scale / 2; 177ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int left_modifier = dest_scale; 178ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int right_modifier = 0; 179ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned char left_pixel = *source; 180ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned char right_pixel = *(source + source_step); 181ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 182ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang (void) source_length; 183ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 184ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* These asserts are needed if there are boundary issues... */ 185ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /*assert ( dest_scale > source_scale );*/ 186ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /*assert ( (source_length-1) * dest_scale >= (dest_length-1) * source_scale );*/ 187ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 188ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for (i = 0; i < dest_length * dest_step; i += dest_step) { 189ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang dest[i] = (char)((left_modifier * left_pixel + right_modifier * right_pixel + round_value) / dest_scale); 190ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 191ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang right_modifier += source_scale; 192ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 193ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang while (right_modifier > dest_scale) { 194ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang right_modifier -= dest_scale; 195ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang source += source_step; 196ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang left_pixel = *source; 197ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang right_pixel = *(source + source_step); 198ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 199ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 200ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang left_modifier = dest_scale - right_modifier; 201ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 202ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} 203ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 204ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/**************************************************************************** 205ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 206ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * ROUTINE : Scale2D 207ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 208ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * INPUTS : const unsigned char *source : Pointer to data to be scaled. 209ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * int source_pitch : Stride of source image. 210ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * unsigned int source_width : Width of input image. 211ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * unsigned int source_height : Height of input image. 212ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * unsigned char *dest : Pointer to output data array. 213ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * int dest_pitch : Stride of destination image. 214ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * unsigned int dest_width : Width of destination image. 215ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * unsigned int dest_height : Height of destination image. 216ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * unsigned char *temp_area : Pointer to temp work area. 217ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * unsigned char temp_area_height : Height of temp work area. 218ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * unsigned int hscale : Horizontal scale factor numerator. 219ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * unsigned int hratio : Horizontal scale factor denominator. 220ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * unsigned int vscale : Vertical scale factor numerator. 221ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * unsigned int vratio : Vertical scale factor denominator. 222ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * unsigned int interlaced : Interlace flag. 223ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 224ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * OUTPUTS : None. 225ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 226ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * RETURNS : void 227ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 228ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * FUNCTION : Performs 2-tap linear interpolation in two dimensions. 229ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 230ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * SPECIAL NOTES : Expansion is performed one band at a time to help with 231ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * caching. 232ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 233ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ****************************************************************************/ 234ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic 235ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangvoid Scale2D 236ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang( 237ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /*const*/ 238ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned char *source, 239ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int source_pitch, 240ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int source_width, 241ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int source_height, 242ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned char *dest, 243ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int dest_pitch, 244ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int dest_width, 245ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int dest_height, 246ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned char *temp_area, 247ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned char temp_area_height, 248ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int hscale, 249ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int hratio, 250ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int vscale, 251ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int vratio, 252ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int interlaced 253ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang) { 254ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /*unsigned*/ 255ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int i, j, k; 256ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int bands; 257ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int dest_band_height; 258ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int source_band_height; 259ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 260ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang typedef void (*Scale1D)(const unsigned char * source, int source_step, unsigned int source_scale, unsigned int source_length, 261ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned char * dest, int dest_step, unsigned int dest_scale, unsigned int dest_length); 262ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 263ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Scale1D Scale1Dv = scale1d_c; 264ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Scale1D Scale1Dh = scale1d_c; 265ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 266ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang void (*horiz_line_scale)(const unsigned char *, unsigned int, unsigned char *, unsigned int) = NULL; 267ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang void (*vert_band_scale)(unsigned char *, unsigned int, unsigned char *, unsigned int, unsigned int) = NULL; 268ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 269ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int ratio_scalable = 1; 270ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int interpolation = 0; 271ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 272ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned char *source_base; /* = (unsigned char *) ((source_pitch >= 0) ? source : (source + ((source_height-1) * source_pitch))); */ 273ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned char *line_src; 274ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 275ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 276ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang source_base = (unsigned char *)source; 277ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 278ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (source_pitch < 0) { 279ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int offset; 280ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 281ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang offset = (source_height - 1); 282ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang offset *= source_pitch; 283ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 284ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang source_base += offset; 285ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 286ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 287ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* find out the ratio for each direction */ 288ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang switch (hratio * 10 / hscale) { 289ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang case 8: 290ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* 4-5 Scale in Width direction */ 291ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang horiz_line_scale = vp8_horizontal_line_5_4_scale; 292ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang break; 293ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang case 6: 294ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* 3-5 Scale in Width direction */ 295ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang horiz_line_scale = vp8_horizontal_line_5_3_scale; 296ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang break; 297ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang case 5: 298ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* 1-2 Scale in Width direction */ 299ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang horiz_line_scale = vp8_horizontal_line_2_1_scale; 300ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang break; 301ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang default: 302ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* The ratio is not acceptable now */ 303ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* throw("The ratio is not acceptable for now!"); */ 304ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ratio_scalable = 0; 305ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang break; 306ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 307ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 308ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang switch (vratio * 10 / vscale) { 309ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang case 8: 310ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* 4-5 Scale in vertical direction */ 311ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang vert_band_scale = vp8_vertical_band_5_4_scale; 312ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang source_band_height = 5; 313ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang dest_band_height = 4; 314ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang break; 315ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang case 6: 316ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* 3-5 Scale in vertical direction */ 317ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang vert_band_scale = vp8_vertical_band_5_3_scale; 318ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang source_band_height = 5; 319ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang dest_band_height = 3; 320ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang break; 321ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang case 5: 322ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* 1-2 Scale in vertical direction */ 323ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 324ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (interlaced) { 325ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* if the content is interlaced, point sampling is used */ 326ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang vert_band_scale = vp8_vertical_band_2_1_scale; 327ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } else { 328ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 329ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang interpolation = 1; 330ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* if the content is progressive, interplo */ 331ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang vert_band_scale = vp8_vertical_band_2_1_scale_i; 332ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 333ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 334ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 335ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang source_band_height = 2; 336ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang dest_band_height = 1; 337ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang break; 338ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang default: 339ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* The ratio is not acceptable now */ 340ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* throw("The ratio is not acceptable for now!"); */ 341ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ratio_scalable = 0; 342ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang break; 343ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 344ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 345ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (ratio_scalable) { 346ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (source_height == dest_height) { 347ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* for each band of the image */ 348ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for (k = 0; k < (int)dest_height; k++) { 349ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang horiz_line_scale(source, source_width, dest, dest_width); 350ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang source += source_pitch; 351ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang dest += dest_pitch; 352ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 353ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 354ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return; 355ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 356ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 357ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (interpolation) { 358ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (source < source_base) 359ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang source = source_base; 360ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 361ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang horiz_line_scale(source, source_width, temp_area, dest_width); 362ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 363ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 364ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for (k = 0; k < (int)(dest_height + dest_band_height - 1) / dest_band_height; k++) { 365ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* scale one band horizontally */ 366ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for (i = 0; i < source_band_height; i++) { 367ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* Trap case where we could read off the base of the source buffer */ 368ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 369ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line_src = (unsigned char *)source + i * source_pitch; 370ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 371ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (line_src < source_base) 372ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line_src = source_base; 373ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 374ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang horiz_line_scale(line_src, source_width, 375ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang temp_area + (i + 1)*dest_pitch, dest_width); 376ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 377ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 378ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* Vertical scaling is in place */ 379ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang vert_band_scale(temp_area + dest_pitch, dest_pitch, dest, dest_pitch, dest_width); 380ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 381ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (interpolation) 382ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang vpx_memcpy(temp_area, temp_area + source_band_height * dest_pitch, dest_width); 383ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 384ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* Next band... */ 385ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang source += (unsigned long) source_band_height * source_pitch; 386ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang dest += (unsigned long) dest_band_height * dest_pitch; 387ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 388ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 389ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return; 390ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 391ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 392ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (hscale == 2 && hratio == 1) 393ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Scale1Dh = scale1d_2t1_ps; 394ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 395ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (vscale == 2 && vratio == 1) { 396ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (interlaced) 397ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Scale1Dv = scale1d_2t1_ps; 398ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else 399ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Scale1Dv = scale1d_2t1_i; 400ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 401ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 402ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (source_height == dest_height) { 403ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* for each band of the image */ 404ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for (k = 0; k < (int)dest_height; k++) { 405ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Scale1Dh(source, 1, hscale, source_width + 1, dest, 1, hratio, dest_width); 406ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang source += source_pitch; 407ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang dest += dest_pitch; 408ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 409ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 410ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return; 411ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 412ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 413ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (dest_height > source_height) { 414ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang dest_band_height = temp_area_height - 1; 415ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang source_band_height = dest_band_height * source_height / dest_height; 416ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } else { 417ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang source_band_height = temp_area_height - 1; 418ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang dest_band_height = source_band_height * vratio / vscale; 419ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 420ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 421ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* first row needs to be done so that we can stay one row ahead for vertical zoom */ 422ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Scale1Dh(source, 1, hscale, source_width + 1, temp_area, 1, hratio, dest_width); 423ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 424ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* for each band of the image */ 425ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang bands = (dest_height + dest_band_height - 1) / dest_band_height; 426ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 427ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for (k = 0; k < bands; k++) { 428ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* scale one band horizontally */ 429ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for (i = 1; i < source_band_height + 1; i++) { 430ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (k * source_band_height + i < (int) source_height) { 431ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Scale1Dh(source + i * source_pitch, 1, hscale, source_width + 1, 432ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang temp_area + i * dest_pitch, 1, hratio, dest_width); 433ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } else { /* Duplicate the last row */ 434ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* copy temp_area row 0 over from last row in the past */ 435ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang vpx_memcpy(temp_area + i * dest_pitch, temp_area + (i - 1)*dest_pitch, dest_pitch); 436ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 437ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 438ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 439ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* scale one band vertically */ 440ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for (j = 0; j < (int)dest_width; j++) { 441ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Scale1Dv(&temp_area[j], dest_pitch, vscale, source_band_height + 1, 442ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang &dest[j], dest_pitch, vratio, dest_band_height); 443ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 444ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 445ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* copy temp_area row 0 over from last row in the past */ 446ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang vpx_memcpy(temp_area, temp_area + source_band_height * dest_pitch, dest_pitch); 447ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 448ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* move to the next band */ 449ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang source += source_band_height * source_pitch; 450ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang dest += dest_band_height * dest_pitch; 451ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 452ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} 453ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 454ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/**************************************************************************** 455ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 456ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * ROUTINE : vpx_scale_frame 457ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 458ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * INPUTS : YV12_BUFFER_CONFIG *src : Pointer to frame to be scaled. 459ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * YV12_BUFFER_CONFIG *dst : Pointer to buffer to hold scaled frame. 460ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * unsigned char *temp_area : Pointer to temp work area. 461ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * unsigned char temp_area_height : Height of temp work area. 462ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * unsigned int hscale : Horizontal scale factor numerator. 463ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * unsigned int hratio : Horizontal scale factor denominator. 464ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * unsigned int vscale : Vertical scale factor numerator. 465ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * unsigned int vratio : Vertical scale factor denominator. 466ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * unsigned int interlaced : Interlace flag. 467ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 468ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * OUTPUTS : None. 469ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 470ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * RETURNS : void 471ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 472ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * FUNCTION : Performs 2-tap linear interpolation in two dimensions. 473ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 474ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * SPECIAL NOTES : Expansion is performed one band at a time to help with 475ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * caching. 476ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 477ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ****************************************************************************/ 478ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangvoid vpx_scale_frame 479ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang( 480ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang YV12_BUFFER_CONFIG *src, 481ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang YV12_BUFFER_CONFIG *dst, 482ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned char *temp_area, 483ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned char temp_height, 484ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int hscale, 485ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int hratio, 486ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int vscale, 487ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int vratio, 488ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int interlaced 489ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang) { 490ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int i; 491ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int dw = (hscale - 1 + src->y_width * hratio) / hscale; 492ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int dh = (vscale - 1 + src->y_height * vratio) / vscale; 493ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 494ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* call our internal scaling routines!! */ 495ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Scale2D((unsigned char *) src->y_buffer, src->y_stride, src->y_width, src->y_height, 496ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang (unsigned char *) dst->y_buffer, dst->y_stride, dw, dh, 497ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang temp_area, temp_height, hscale, hratio, vscale, vratio, interlaced); 498ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 499ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (dw < (int)dst->y_width) 500ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for (i = 0; i < dh; i++) 501ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang vpx_memset(dst->y_buffer + i * dst->y_stride + dw - 1, dst->y_buffer[i * dst->y_stride + dw - 2], dst->y_width - dw + 1); 502ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 503ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (dh < (int)dst->y_height) 504ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for (i = dh - 1; i < (int)dst->y_height; i++) 505ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang vpx_memcpy(dst->y_buffer + i * dst->y_stride, dst->y_buffer + (dh - 2) * dst->y_stride, dst->y_width + 1); 506ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 507ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Scale2D((unsigned char *) src->u_buffer, src->uv_stride, src->uv_width, src->uv_height, 508ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang (unsigned char *) dst->u_buffer, dst->uv_stride, dw / 2, dh / 2, 509ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang temp_area, temp_height, hscale, hratio, vscale, vratio, interlaced); 510ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 511ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (dw / 2 < (int)dst->uv_width) 512ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for (i = 0; i < dst->uv_height; i++) 513ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang vpx_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); 514ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 515ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (dh / 2 < (int)dst->uv_height) 516ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for (i = dh / 2 - 1; i < (int)dst->y_height / 2; i++) 517ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang vpx_memcpy(dst->u_buffer + i * dst->uv_stride, dst->u_buffer + (dh / 2 - 2)*dst->uv_stride, dst->uv_width); 518ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 519ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Scale2D((unsigned char *) src->v_buffer, src->uv_stride, src->uv_width, src->uv_height, 520ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang (unsigned char *) dst->v_buffer, dst->uv_stride, dw / 2, dh / 2, 521ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang temp_area, temp_height, hscale, hratio, vscale, vratio, interlaced); 522ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 523ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (dw / 2 < (int)dst->uv_width) 524ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for (i = 0; i < dst->uv_height; i++) 525ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang vpx_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); 526ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 527ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (dh / 2 < (int) dst->uv_height) 528ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for (i = dh / 2 - 1; i < (int)dst->y_height / 2; i++) 529ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang vpx_memcpy(dst->v_buffer + i * dst->uv_stride, dst->v_buffer + (dh / 2 - 2)*dst->uv_stride, dst->uv_width); 530ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} 531