Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
BC
public
external
libvpx
Commits
d138262a
Commit
d138262a
authored
Dec 04, 2012
by
Johann
Committed by
Gerrit Code Review
Dec 04, 2012
Browse files
Merge "Begin to refactor vpx_scale usage in VP9" into experimental
parents
806d05e1
c6bd29e2
Changes
17
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
10 additions
and
3195 deletions
+10
-3195
vp9/common/vp9_postproc.c
vp9/common/vp9_postproc.c
+1
-0
vp9/common/vp9_rtcd_defs.sh
vp9/common/vp9_rtcd_defs.sh
+0
-36
vp9/decoder/vp9_onyxd_if.c
vp9/decoder/vp9_onyxd_if.c
+1
-0
vp9/encoder/vp9_firstpass.c
vp9/encoder/vp9_firstpass.c
+1
-0
vp9/encoder/vp9_onyx_if.c
vp9/encoder/vp9_onyx_if.c
+1
-0
vp9/encoder/vp9_picklpf.c
vp9/encoder/vp9_picklpf.c
+1
-0
vpx_scale/generic/bicubic_scaler.c
vpx_scale/generic/bicubic_scaler.c
+0
-569
vpx_scale/generic/gen_scalers.c
vpx_scale/generic/gen_scalers.c
+0
-682
vpx_scale/generic/vpxscale.c
vpx_scale/generic/vpxscale.c
+0
-480
vpx_scale/include/generic/vpxscale_arbitrary.h
vpx_scale/include/generic/vpxscale_arbitrary.h
+0
-55
vpx_scale/include/generic/vpxscale_depricated.h
vpx_scale/include/generic/vpxscale_depricated.h
+0
-34
vpx_scale/scale_mode.h
vpx_scale/scale_mode.h
+0
-28
vpx_scale/vpx_scale.mk
vpx_scale/vpx_scale.mk
+0
-1
vpx_scale/vpx_scale_rtcd.sh
vpx_scale/vpx_scale_rtcd.sh
+0
-15
vpx_scale/vpxscale.h
vpx_scale/vpxscale.h
+0
-10
vpx_scale/win32/scaleopt.c
vpx_scale/win32/scaleopt.c
+5
-1198
vpx_scale/win32/scalesystemdependent.c
vpx_scale/win32/scalesystemdependent.c
+0
-87
No files found.
vp9/common/vp9_postproc.c
View file @
d138262a
...
...
@@ -16,6 +16,7 @@
#include "vpx_scale/vpxscale.h"
#include "vp9/common/vp9_systemdependent.h"
#include "./vp9_rtcd.h"
#include "./vpx_scale_rtcd.h"
#include <math.h>
...
...
vp9/common/vp9_rtcd_defs.sh
View file @
d138262a
...
...
@@ -677,39 +677,3 @@ specialize vp9_yv12_copy_partial_frame
fi
# end encoder functions
# Scaler functions
if
[
"
$CONFIG_SPATIAL_RESAMPLING
"
=
"yes"
]
;
then
prototype void vp8_horizontal_line_4_5_scale
"const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width"
prototype void vp8_vertical_band_4_5_scale
"unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width"
prototype void vp8_last_vertical_band_4_5_scale
"unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width"
prototype void vp8_horizontal_line_2_3_scale
"const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width"
prototype void vp8_vertical_band_2_3_scale
"unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width"
prototype void vp8_last_vertical_band_2_3_scale
"unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width"
prototype void vp8_horizontal_line_3_5_scale
"const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width"
prototype void vp8_vertical_band_3_5_scale
"unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width"
prototype void vp8_last_vertical_band_3_5_scale
"unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width"
prototype void vp8_horizontal_line_3_4_scale
"const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width"
prototype void vp8_vertical_band_3_4_scale
"unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width"
prototype void vp8_last_vertical_band_3_4_scale
"unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width"
prototype void vp8_horizontal_line_1_2_scale
"const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width"
prototype void vp8_vertical_band_1_2_scale
"unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width"
prototype void vp8_last_vertical_band_1_2_scale
"unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width"
prototype void vp8_horizontal_line_5_4_scale
"const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width"
prototype void vp8_vertical_band_5_4_scale
"unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width"
prototype void vp8_horizontal_line_5_3_scale
"const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width"
prototype void vp8_vertical_band_5_3_scale
"unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width"
prototype void vp8_horizontal_line_2_1_scale
"const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width"
prototype void vp8_vertical_band_2_1_scale
"unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width"
prototype void 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"
fi
prototype void vp8_yv12_extend_frame_borders
"struct yv12_buffer_config *ybf"
specialize vp8_yv12_extend_frame_borders
prototype void vp8_yv12_copy_frame
"struct yv12_buffer_config *src_ybc, struct yv12_buffer_config *dst_ybc"
specialize vp8_yv12_copy_frame
prototype void vp8_yv12_copy_y
"struct yv12_buffer_config *src_ybc, struct yv12_buffer_config *dst_ybc"
specialize vp8_yv12_copy_y
vp9/decoder/vp9_onyxd_if.c
View file @
d138262a
...
...
@@ -28,6 +28,7 @@
#include "vpx_ports/vpx_timer.h"
#include "vp9/decoder/vp9_decodframe.h"
#include "vp9/decoder/vp9_detokenize.h"
#include "./vpx_scale_rtcd.h"
static
int
get_free_fb
(
VP9_COMMON
*
cm
);
static
void
ref_cnt_fb
(
int
*
buf
,
int
*
idx
,
int
new_idx
);
...
...
vp9/encoder/vp9_firstpass.c
View file @
d138262a
...
...
@@ -31,6 +31,7 @@
#include "vp9/common/vp9_quant_common.h"
#include "vp9/common/vp9_entropymv.h"
#include "vp9/encoder/vp9_encodemv.h"
#include "./vpx_scale_rtcd.h"
#define OUTPUT_FPF 0
...
...
vp9/encoder/vp9_onyx_if.c
View file @
d138262a
...
...
@@ -24,6 +24,7 @@
#include "vp9/common/vp9_quant_common.h"
#include "vp9/encoder/vp9_segmentation.h"
#include "./vp9_rtcd.h"
#include "./vpx_scale_rtcd.h"
#if CONFIG_POSTPROC
#include "vp9/common/vp9_postproc.h"
#endif
...
...
vp9/encoder/vp9_picklpf.c
View file @
d138262a
...
...
@@ -17,6 +17,7 @@
#include "vpx_scale/vpxscale.h"
#include "vp9/common/vp9_alloccommon.h"
#include "vp9/common/vp9_loopfilter.h"
#include "./vpx_scale_rtcd.h"
void
vp9_yv12_copy_partial_frame_c
(
YV12_BUFFER_CONFIG
*
src_ybc
,
YV12_BUFFER_CONFIG
*
dst_ybc
,
int
Fraction
)
{
...
...
vpx_scale/generic/bicubic_scaler.c
deleted
100644 → 0
View file @
806d05e1
/*
* Copyright (c) 2010 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include <float.h>
#include <math.h>
#include <stdio.h>
#include "vpx_mem/vpx_mem.h"
#include "vpxscale_arbitrary.h"
#define FIXED_POINT
#define MAX_IN_WIDTH 800
#define MAX_IN_HEIGHT 600
#define MAX_OUT_WIDTH 800
#define MAX_OUT_HEIGHT 600
#define MAX_OUT_DIMENSION ((MAX_OUT_WIDTH > MAX_OUT_HEIGHT) ? \
MAX_OUT_WIDTH : MAX_OUT_HEIGHT)
BICUBIC_SCALER_STRUCT
g_b_scaler
;
static
int
g_first_time
=
1
;
#pragma DATA_SECTION(g_hbuf, "VP6_HEAP")
#pragma DATA_ALIGN (g_hbuf, 32);
unsigned
char
g_hbuf
[
MAX_OUT_DIMENSION
];
#pragma DATA_SECTION(g_hbuf_uv, "VP6_HEAP")
#pragma DATA_ALIGN (g_hbuf_uv, 32);
unsigned
char
g_hbuf_uv
[
MAX_OUT_DIMENSION
];
#ifdef FIXED_POINT
static
int
a_i
=
0
.
6
*
65536
;
#else
static
float
a
=
-
0
.
6
;
#endif
#ifdef FIXED_POINT
// 3 2
// C0 = a*t - a*t
//
static
short
c0_fixed
(
unsigned
int
t
)
{
// put t in Q16 notation
unsigned
short
v1
,
v2
;
// Q16
v1
=
(
a_i
*
t
)
>>
16
;
v1
=
(
v1
*
t
)
>>
16
;
// Q16
v2
=
(
a_i
*
t
)
>>
16
;
v2
=
(
v2
*
t
)
>>
16
;
v2
=
(
v2
*
t
)
>>
16
;
// Q12
return
-
((
v1
-
v2
)
>>
4
);
}
// 2 3
// C1 = a*t + (3-2*a)*t - (2-a)*t
//
static
short
c1_fixed
(
unsigned
int
t
)
{
unsigned
short
v1
,
v2
,
v3
;
unsigned
short
two
,
three
;
// Q16
v1
=
(
a_i
*
t
)
>>
16
;
// Q13
two
=
2
<<
13
;
v2
=
two
-
(
a_i
>>
3
);
v2
=
(
v2
*
t
)
>>
16
;
v2
=
(
v2
*
t
)
>>
16
;
v2
=
(
v2
*
t
)
>>
16
;
// Q13
three
=
3
<<
13
;
v3
=
three
-
(
2
*
(
a_i
>>
3
));
v3
=
(
v3
*
t
)
>>
16
;
v3
=
(
v3
*
t
)
>>
16
;
// Q12
return
(((
v1
>>
3
)
-
v2
+
v3
)
>>
1
);
}
// 2 3
// C2 = 1 - (3-a)*t + (2-a)*t
//
static
short
c2_fixed
(
unsigned
int
t
)
{
unsigned
short
v1
,
v2
,
v3
;
unsigned
short
two
,
three
;
// Q13
v1
=
1
<<
13
;
// Q13
three
=
3
<<
13
;
v2
=
three
-
(
a_i
>>
3
);
v2
=
(
v2
*
t
)
>>
16
;
v2
=
(
v2
*
t
)
>>
16
;
// Q13
two
=
2
<<
13
;
v3
=
two
-
(
a_i
>>
3
);
v3
=
(
v3
*
t
)
>>
16
;
v3
=
(
v3
*
t
)
>>
16
;
v3
=
(
v3
*
t
)
>>
16
;
// Q12
return
(
v1
-
v2
+
v3
)
>>
1
;
}
// 2 3
// C3 = a*t - 2*a*t + a*t
//
static
short
c3_fixed
(
unsigned
int
t
)
{
int
v1
,
v2
,
v3
;
// Q16
v1
=
(
a_i
*
t
)
>>
16
;
// Q15
v2
=
2
*
(
a_i
>>
1
);
v2
=
(
v2
*
t
)
>>
16
;
v2
=
(
v2
*
t
)
>>
16
;
// Q16
v3
=
(
a_i
*
t
)
>>
16
;
v3
=
(
v3
*
t
)
>>
16
;
v3
=
(
v3
*
t
)
>>
16
;
// Q12
return
((
v2
-
(
v1
>>
1
)
-
(
v3
>>
1
))
>>
3
);
}
#else
// 3 2
// C0 = -a*t + a*t
//
float
C0
(
float
t
)
{
return
-
a
*
t
*
t
*
t
+
a
*
t
*
t
;
}
// 2 3
// C1 = -a*t + (2*a+3)*t - (a+2)*t
//
float
C1
(
float
t
)
{
return
-
(
a
+
2
.
0
f
)
*
t
*
t
*
t
+
(
2
.
0
f
*
a
+
3
.
0
f
)
*
t
*
t
-
a
*
t
;
}
// 2 3
// C2 = 1 - (a+3)*t + (a+2)*t
//
float
C2
(
float
t
)
{
return
(
a
+
2
.
0
f
)
*
t
*
t
*
t
-
(
a
+
3
.
0
f
)
*
t
*
t
+
1
.
0
f
;
}
// 2 3
// C3 = a*t - 2*a*t + a*t
//
float
C3
(
float
t
)
{
return
a
*
t
*
t
*
t
-
2
.
0
f
*
a
*
t
*
t
+
a
*
t
;
}
#endif
#if 0
int compare_real_fixed() {
int i, errors = 0;
float mult = 1.0 / 10000.0;
unsigned int fixed_mult = mult * 4294967296;// 65536;
unsigned int phase_offset_int;
float phase_offset_real;
for (i = 0; i < 10000; i++) {
int fixed0, fixed1, fixed2, fixed3, fixed_total;
int real0, real1, real2, real3, real_total;
phase_offset_real = (float)i * mult;
phase_offset_int = (fixed_mult * i) >> 16;
// phase_offset_int = phase_offset_real * 65536;
fixed0 = c0_fixed(phase_offset_int);
real0 = C0(phase_offset_real) * 4096.0;
if ((abs(fixed0) > (abs(real0) + 1)) || (abs(fixed0) < (abs(real0) - 1)))
errors++;
fixed1 = c1_fixed(phase_offset_int);
real1 = C1(phase_offset_real) * 4096.0;
if ((abs(fixed1) > (abs(real1) + 1)) || (abs(fixed1) < (abs(real1) - 1)))
errors++;
fixed2 = c2_fixed(phase_offset_int);
real2 = C2(phase_offset_real) * 4096.0;
if ((abs(fixed2) > (abs(real2) + 1)) || (abs(fixed2) < (abs(real2) - 1)))
errors++;
fixed3 = c3_fixed(phase_offset_int);
real3 = C3(phase_offset_real) * 4096.0;
if ((abs(fixed3) > (abs(real3) + 1)) || (abs(fixed3) < (abs(real3) - 1)))
errors++;
fixed_total = fixed0 + fixed1 + fixed2 + fixed3;
real_total = real0 + real1 + real2 + real3;
if ((fixed_total > 4097) || (fixed_total < 4094))
errors++;
if ((real_total > 4097) || (real_total < 4095))
errors++;
}
return errors;
}
#endif
// Find greatest common denominator between two integers. Method used here is
// slow compared to Euclid's algorithm, but does not require any division.
int
gcd
(
int
a
,
int
b
)
{
// Problem with this algorithm is that if a or b = 0 this function
// will never exit. Don't want to return 0 because any computation
// that was based on a common denoninator and tried to reduce by
// dividing by 0 would fail. Best solution that could be thought of
// would to be fail by returing a 1;
if
(
a
<=
0
||
b
<=
0
)
return
1
;
while
(
a
!=
b
)
{
if
(
b
>
a
)
b
=
b
-
a
;
else
{
int
tmp
=
a
;
// swap large and
a
=
b
;
// small
b
=
tmp
;
}
}
return
b
;
}
void
bicubic_coefficient_init
()
{
vpx_memset
(
&
g_b_scaler
,
0
,
sizeof
(
BICUBIC_SCALER_STRUCT
));
g_first_time
=
0
;
}
void
bicubic_coefficient_destroy
()
{
if
(
!
g_first_time
)
{
vpx_free
(
g_b_scaler
.
l_w
);
vpx_free
(
g_b_scaler
.
l_h
);
vpx_free
(
g_b_scaler
.
l_h_uv
);
vpx_free
(
g_b_scaler
.
c_w
);
vpx_free
(
g_b_scaler
.
c_h
);
vpx_free
(
g_b_scaler
.
c_h_uv
);
vpx_memset
(
&
g_b_scaler
,
0
,
sizeof
(
BICUBIC_SCALER_STRUCT
));
}
}
// Create the coeffients that will be used for the cubic interpolation.
// Because scaling does not have to be equal in the vertical and horizontal
// regimes the phase offsets will be different. There are 4 coefficents
// for each point, two on each side. The layout is that there are the
// 4 coefficents for each phase in the array and then the next phase.
int
bicubic_coefficient_setup
(
int
in_width
,
int
in_height
,
int
out_width
,
int
out_height
)
{
int
i
;
#ifdef FIXED_POINT
int
phase_offset_int
;
unsigned
int
fixed_mult
;
int
product_val
=
0
;
#else
float
phase_offset
;
#endif
int
gcd_w
,
gcd_h
,
gcd_h_uv
,
d_w
,
d_h
,
d_h_uv
;
if
(
g_first_time
)
bicubic_coefficient_init
();
// check to see if the coefficents have already been set up correctly
if
((
in_width
==
g_b_scaler
.
in_width
)
&&
(
in_height
==
g_b_scaler
.
in_height
)
&&
(
out_width
==
g_b_scaler
.
out_width
)
&&
(
out_height
==
g_b_scaler
.
out_height
))
return
0
;
g_b_scaler
.
in_width
=
in_width
;
g_b_scaler
.
in_height
=
in_height
;
g_b_scaler
.
out_width
=
out_width
;
g_b_scaler
.
out_height
=
out_height
;
// Don't want to allow crazy scaling, just try and prevent a catastrophic
// failure here. Want to fail after setting the member functions so if
// if the scaler is called the member functions will not scale.
if
(
out_width
<=
0
||
out_height
<=
0
)
return
-
1
;
// reduce in/out width and height ratios using the gcd
gcd_w
=
gcd
(
out_width
,
in_width
);
gcd_h
=
gcd
(
out_height
,
in_height
);
gcd_h_uv
=
gcd
(
out_height
,
in_height
/
2
);
// the numerator width and height are to be saved in
// globals so they can be used during the scaling process
// without having to be recalculated.
g_b_scaler
.
nw
=
out_width
/
gcd_w
;
d_w
=
in_width
/
gcd_w
;
g_b_scaler
.
nh
=
out_height
/
gcd_h
;
d_h
=
in_height
/
gcd_h
;
g_b_scaler
.
nh_uv
=
out_height
/
gcd_h_uv
;
d_h_uv
=
(
in_height
/
2
)
/
gcd_h_uv
;
// allocate memory for the coefficents
vpx_free
(
g_b_scaler
.
l_w
);
vpx_free
(
g_b_scaler
.
l_h
);
vpx_free
(
g_b_scaler
.
l_h_uv
);
g_b_scaler
.
l_w
=
(
short
*
)
vpx_memalign
(
32
,
out_width
*
2
);
g_b_scaler
.
l_h
=
(
short
*
)
vpx_memalign
(
32
,
out_height
*
2
);
g_b_scaler
.
l_h_uv
=
(
short
*
)
vpx_memalign
(
32
,
out_height
*
2
);
vpx_free
(
g_b_scaler
.
c_w
);
vpx_free
(
g_b_scaler
.
c_h
);
vpx_free
(
g_b_scaler
.
c_h_uv
);
g_b_scaler
.
c_w
=
(
short
*
)
vpx_memalign
(
32
,
g_b_scaler
.
nw
*
4
*
2
);
g_b_scaler
.
c_h
=
(
short
*
)
vpx_memalign
(
32
,
g_b_scaler
.
nh
*
4
*
2
);
g_b_scaler
.
c_h_uv
=
(
short
*
)
vpx_memalign
(
32
,
g_b_scaler
.
nh_uv
*
4
*
2
);
g_b_scaler
.
hbuf
=
g_hbuf
;
g_b_scaler
.
hbuf_uv
=
g_hbuf_uv
;
// Set up polyphase filter taps. This needs to be done before
// the scaling because of the floating point math required. The
// coefficients are multiplied by 2^12 so that fixed point math
// can be used in the main scaling loop.
#ifdef FIXED_POINT
fixed_mult
=
(
1
.
0
/
(
float
)
g_b_scaler
.
nw
)
*
4294967296
;
product_val
=
0
;
for
(
i
=
0
;
i
<
g_b_scaler
.
nw
;
i
++
)
{
if
(
product_val
>
g_b_scaler
.
nw
)
product_val
-=
g_b_scaler
.
nw
;
phase_offset_int
=
(
fixed_mult
*
product_val
)
>>
16
;
g_b_scaler
.
c_w
[
i
*
4
]
=
c3_fixed
(
phase_offset_int
);
g_b_scaler
.
c_w
[
i
*
4
+
1
]
=
c2_fixed
(
phase_offset_int
);
g_b_scaler
.
c_w
[
i
*
4
+
2
]
=
c1_fixed
(
phase_offset_int
);
g_b_scaler
.
c_w
[
i
*
4
+
3
]
=
c0_fixed
(
phase_offset_int
);
product_val
+=
d_w
;
}
fixed_mult
=
(
1
.
0
/
(
float
)
g_b_scaler
.
nh
)
*
4294967296
;
product_val
=
0
;
for
(
i
=
0
;
i
<
g_b_scaler
.
nh
;
i
++
)
{
if
(
product_val
>
g_b_scaler
.
nh
)
product_val
-=
g_b_scaler
.
nh
;
phase_offset_int
=
(
fixed_mult
*
product_val
)
>>
16
;
g_b_scaler
.
c_h
[
i
*
4
]
=
c0_fixed
(
phase_offset_int
);
g_b_scaler
.
c_h
[
i
*
4
+
1
]
=
c1_fixed
(
phase_offset_int
);
g_b_scaler
.
c_h
[
i
*
4
+
2
]
=
c2_fixed
(
phase_offset_int
);
g_b_scaler
.
c_h
[
i
*
4
+
3
]
=
c3_fixed
(
phase_offset_int
);
product_val
+=
d_h
;
}
fixed_mult
=
(
1
.
0
/
(
float
)
g_b_scaler
.
nh_uv
)
*
4294967296
;
product_val
=
0
;
for
(
i
=
0
;
i
<
g_b_scaler
.
nh_uv
;
i
++
)
{
if
(
product_val
>
g_b_scaler
.
nh_uv
)
product_val
-=
g_b_scaler
.
nh_uv
;
phase_offset_int
=
(
fixed_mult
*
product_val
)
>>
16
;
g_b_scaler
.
c_h_uv
[
i
*
4
]
=
c0_fixed
(
phase_offset_int
);
g_b_scaler
.
c_h_uv
[
i
*
4
+
1
]
=
c1_fixed
(
phase_offset_int
);
g_b_scaler
.
c_h_uv
[
i
*
4
+
2
]
=
c2_fixed
(
phase_offset_int
);
g_b_scaler
.
c_h_uv
[
i
*
4
+
3
]
=
c3_fixed
(
phase_offset_int
);
product_val
+=
d_h_uv
;
}
#else
for
(
i
=
0
;
i
<
g_nw
;
i
++
)
{
phase_offset
=
(
float
)((
i
*
d_w
)
%
g_nw
)
/
(
float
)
g_nw
;
g_c_w
[
i
*
4
]
=
(
C3
(
phase_offset
)
*
4096
.
0
);
g_c_w
[
i
*
4
+
1
]
=
(
C2
(
phase_offset
)
*
4096
.
0
);
g_c_w
[
i
*
4
+
2
]
=
(
C1
(
phase_offset
)
*
4096
.
0
);
g_c_w
[
i
*
4
+
3
]
=
(
C0
(
phase_offset
)
*
4096
.
0
);
}
for
(
i
=
0
;
i
<
g_nh
;
i
++
)
{
phase_offset
=
(
float
)((
i
*
d_h
)
%
g_nh
)
/
(
float
)
g_nh
;
g_c_h
[
i
*
4
]
=
(
C0
(
phase_offset
)
*
4096
.
0
);
g_c_h
[
i
*
4
+
1
]
=
(
C1
(
phase_offset
)
*
4096
.
0
);
g_c_h
[
i
*
4
+
2
]
=
(
C2
(
phase_offset
)
*
4096
.
0
);
g_c_h
[
i
*
4
+
3
]
=
(
C3
(
phase_offset
)
*
4096
.
0
);
}
for
(
i
=
0
;
i
<
g_nh_uv
;
i
++
)
{
phase_offset
=
(
float
)((
i
*
d_h_uv
)
%
g_nh_uv
)
/
(
float
)
g_nh_uv
;
g_c_h_uv
[
i
*
4
]
=
(
C0
(
phase_offset
)
*
4096
.
0
);
g_c_h_uv
[
i
*
4
+
1
]
=
(
C1
(
phase_offset
)
*
4096
.
0
);
g_c_h_uv
[
i
*
4
+
2
]
=
(
C2
(
phase_offset
)
*
4096
.
0
);
g_c_h_uv
[
i
*
4
+
3
]
=
(
C3
(
phase_offset
)
*
4096
.
0
);
}
#endif
// Create an array that corresponds input lines to output lines.
// This doesn't require floating point math, but it does require
// a division and because hardware division is not present that
// is a call.
for
(
i
=
0
;
i
<
out_width
;
i
++
)
{
g_b_scaler
.
l_w
[
i
]
=
(
i
*
d_w
)
/
g_b_scaler
.
nw
;
if
((
g_b_scaler
.
l_w
[
i
]
+
2
)
<=
in_width
)
g_b_scaler
.
max_usable_out_width
=
i
;
}
for
(
i
=
0
;
i
<
out_height
+
1
;
i
++
)
{
g_b_scaler
.
l_h
[
i
]
=
(
i
*
d_h
)
/
g_b_scaler
.
nh
;
g_b_scaler
.
l_h_uv
[
i
]
=
(
i
*
d_h_uv
)
/
g_b_scaler
.
nh_uv
;
}
return
0
;
}
int
bicubic_scale
(
int
in_width
,
int
in_height
,
int
in_stride
,
int
out_width
,
int
out_height
,
int
out_stride
,
unsigned
char
*
input_image
,
unsigned
char
*
output_image
)
{
short
*
RESTRICT
l_w
,
*
RESTRICT
l_h
;
short
*
RESTRICT
c_w
,
*
RESTRICT
c_h
;
unsigned
char
*
RESTRICT
ip
,
*
RESTRICT
op
;
unsigned
char
*
RESTRICT
hbuf
;
int
h
,
w
,
lw
,
lh
;
int
temp_sum
;
int
phase_offset_w
,
phase_offset_h
;
c_w
=
g_b_scaler
.
c_w
;
c_h
=
g_b_scaler
.
c_h
;
op
=
output_image
;
l_w
=
g_b_scaler
.
l_w
;
l_h
=
g_b_scaler
.
l_h
;
phase_offset_h
=
0
;
for
(
h
=
0
;
h
<
out_height
;
h
++
)
{
// select the row to work on
lh
=
l_h
[
h
];
ip
=
input_image
+
(
in_stride
*
lh
);
// vp8_filter the row vertically into an temporary buffer.
// If the phase offset == 0 then all the multiplication
// is going to result in the output equalling the input.
// So instead point the temporary buffer to the input.
// Also handle the boundry condition of not being able to
// filter that last lines.
if
(
phase_offset_h
&&
(
lh
<
in_height
-
2
))
{
hbuf
=
g_b_scaler
.
hbuf
;
for
(
w
=
0
;
w
<
in_width
;
w
++
)
{
temp_sum
=
c_h
[
phase_offset_h
*
4
+
3
]
*
ip
[
w
-
in_stride
];
temp_sum
+=
c_h
[
phase_offset_h
*
4
+
2
]
*
ip
[
w
];
temp_sum
+=
c_h
[
phase_offset_h
*
4
+
1
]
*
ip
[
w
+
in_stride
];
temp_sum
+=
c_h
[
phase_offset_h
*
4
]
*
ip
[
w
+
2
*
in_stride
];
hbuf
[
w
]
=
temp_sum
>>
12
;
}
}
else
hbuf
=
ip
;
// increase the phase offset for the next time around.
if
(
++
phase_offset_h
>=
g_b_scaler
.
nh
)
phase_offset_h
=
0
;
// now filter and expand it horizontally into the final
// output buffer
phase_offset_w
=
0
;