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#ifndef VP9_COMMON_VP9_SUBPELVAR_H_
12ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#define VP9_COMMON_VP9_SUBPELVAR_H_
13ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
141184aebb761cbeac9124c37189a80a1a58f04b6bhkuang#include "vp9/common/vp9_common.h"
151184aebb761cbeac9124c37189a80a1a58f04b6bhkuang#include "vp9/common/vp9_convolve.h"
16ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
17ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void variance(const uint8_t *src_ptr,
18ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                     int  source_stride,
19ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                     const uint8_t *ref_ptr,
20ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                     int  recon_stride,
21ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                     int  w,
22ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                     int  h,
23ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                     unsigned int *sse,
24ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                     int *sum) {
25ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int i, j;
26ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int diff;
27ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
28ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  *sum = 0;
29ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  *sse = 0;
30ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
31ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (i = 0; i < h; i++) {
32ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (j = 0; j < w; j++) {
33ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      diff = src_ptr[j] - ref_ptr[j];
34ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      *sum += diff;
35ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      *sse += diff * diff;
36ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
37ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
38ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    src_ptr += source_stride;
39ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ref_ptr += recon_stride;
40ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
41ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
42ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
43ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/****************************************************************************
44ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *
45ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  ROUTINE       : filter_block2d_bil_first_pass
46ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *
47ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  INPUTS        : uint8_t  *src_ptr          : Pointer to source block.
48ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  uint32_t src_pixels_per_line : Stride of input block.
49ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  uint32_t pixel_step        : Offset between filter input samples (see notes).
50ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  uint32_t output_height     : Input block height.
51ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  uint32_t output_width      : Input block width.
52ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  int32_t  *vp9_filter          : Array of 2 bi-linear filter taps.
53ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *
54ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  OUTPUTS       : int32_t *output_ptr        : Pointer to filtered block.
55ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *
56ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  RETURNS       : void
57ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *
58ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  FUNCTION      : Applies a 1-D 2-tap bi-linear filter to the source block in
59ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  either horizontal or vertical direction to produce the
60ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  filtered output block. Used to implement first-pass
61ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  of 2-D separable filter.
62ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *
63ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  SPECIAL NOTES : Produces int32_t output to retain precision for next pass.
64ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  Two filter taps should sum to VP9_FILTER_WEIGHT.
65ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  pixel_step defines whether the filter is applied
66ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  horizontally (pixel_step=1) or vertically (pixel_step=stride).
67ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  It defines the offset required to move from one input
68ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  to the next.
69ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *
70ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ****************************************************************************/
71ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void var_filter_block2d_bil_first_pass(const uint8_t *src_ptr,
72ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                              uint16_t *output_ptr,
73ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                              unsigned int src_pixels_per_line,
74ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                              int pixel_step,
75ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                              unsigned int output_height,
76ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                              unsigned int output_width,
77ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                              const int16_t *vp9_filter) {
78ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  unsigned int i, j;
79ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
80ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (i = 0; i < output_height; i++) {
81ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (j = 0; j < output_width; j++) {
821184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      output_ptr[j] = ROUND_POWER_OF_TWO((int)src_ptr[0] * vp9_filter[0] +
831184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                          (int)src_ptr[pixel_step] * vp9_filter[1],
841184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                          FILTER_BITS);
851184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
86ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      src_ptr++;
87ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
88ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
89ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Next row...
90ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    src_ptr    += src_pixels_per_line - output_width;
91ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    output_ptr += output_width;
92ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
93ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
94ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
95ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/****************************************************************************
96ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *
97ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  ROUTINE       : filter_block2d_bil_second_pass
98ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *
99ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  INPUTS        : int32_t  *src_ptr          : Pointer to source block.
100ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  uint32_t src_pixels_per_line : Stride of input block.
101ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  uint32_t pixel_step        : Offset between filter input samples (see notes).
102ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  uint32_t output_height     : Input block height.
103ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  uint32_t output_width      : Input block width.
104ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  int32_t  *vp9_filter          : Array of 2 bi-linear filter taps.
105ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *
106ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  OUTPUTS       : uint16_t *output_ptr       : Pointer to filtered block.
107ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *
108ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  RETURNS       : void
109ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *
110ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  FUNCTION      : Applies a 1-D 2-tap bi-linear filter to the source block in
111ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  either horizontal or vertical direction to produce the
112ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  filtered output block. Used to implement second-pass
113ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  of 2-D separable filter.
114ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *
115ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  SPECIAL NOTES : Requires 32-bit input as produced by filter_block2d_bil_first_pass.
116ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  Two filter taps should sum to VP9_FILTER_WEIGHT.
117ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  pixel_step defines whether the filter is applied
118ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  horizontally (pixel_step=1) or vertically (pixel_step=stride).
119ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  It defines the offset required to move from one input
120ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  to the next.
121ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *
122ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ****************************************************************************/
123ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void var_filter_block2d_bil_second_pass(const uint16_t *src_ptr,
124ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                               uint8_t *output_ptr,
125ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                               unsigned int src_pixels_per_line,
126ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                               unsigned int pixel_step,
127ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                               unsigned int output_height,
128ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                               unsigned int output_width,
129ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                               const int16_t *vp9_filter) {
130ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  unsigned int  i, j;
131ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
132ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (i = 0; i < output_height; i++) {
133ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (j = 0; j < output_width; j++) {
1341184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      output_ptr[j] = ROUND_POWER_OF_TWO((int)src_ptr[0] * vp9_filter[0] +
1351184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                          (int)src_ptr[pixel_step] * vp9_filter[1],
1361184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                          FILTER_BITS);
137ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      src_ptr++;
138ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
139ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1401184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    src_ptr += src_pixels_per_line - output_width;
141ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    output_ptr += output_width;
142ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
143ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
144ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
145ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#endif  // VP9_COMMON_VP9_SUBPELVAR_H_
146