Simplify scaler_filter
This commit is contained in:
parent
0c5a87b1d7
commit
f21bb4d0dc
|
@ -32,17 +32,6 @@
|
|||
|
||||
#define FILTER_UNITY (1 << 14)
|
||||
|
||||
static bool allocate_filters(struct scaler_ctx *ctx)
|
||||
{
|
||||
ctx->horiz.filter = (int16_t*)calloc(sizeof(int16_t), ctx->horiz.filter_stride * ctx->out_width);
|
||||
ctx->horiz.filter_pos = (int*)calloc(sizeof(int), ctx->out_width);
|
||||
|
||||
ctx->vert.filter = (int16_t*)calloc(sizeof(int16_t), ctx->vert.filter_stride * ctx->out_height);
|
||||
ctx->vert.filter_pos = (int*)calloc(sizeof(int), ctx->out_height);
|
||||
|
||||
return ctx->horiz.filter && ctx->vert.filter;
|
||||
}
|
||||
|
||||
static INLINE void gen_filter_point_sub(struct scaler_filter *filter,
|
||||
int len, int pos, int step)
|
||||
{
|
||||
|
@ -54,31 +43,6 @@ static INLINE void gen_filter_point_sub(struct scaler_filter *filter,
|
|||
}
|
||||
}
|
||||
|
||||
static bool gen_filter_point(struct scaler_ctx *ctx)
|
||||
{
|
||||
int x_pos, x_step, y_pos, y_step;
|
||||
|
||||
ctx->horiz.filter_len = 1;
|
||||
ctx->horiz.filter_stride = 1;
|
||||
ctx->vert.filter_len = 1;
|
||||
ctx->vert.filter_stride = 1;
|
||||
|
||||
if (!allocate_filters(ctx))
|
||||
return false;
|
||||
|
||||
x_pos = (1 << 15) * ctx->in_width / ctx->out_width - (1 << 15);
|
||||
x_step = (1 << 16) * ctx->in_width / ctx->out_width;
|
||||
y_pos = (1 << 15) * ctx->in_height / ctx->out_height - (1 << 15);
|
||||
y_step = (1 << 16) * ctx->in_height / ctx->out_height;
|
||||
|
||||
gen_filter_point_sub(&ctx->horiz, ctx->out_width, x_pos, x_step);
|
||||
gen_filter_point_sub(&ctx->vert, ctx->out_height, y_pos, y_step);
|
||||
|
||||
ctx->scaler_special = scaler_argb8888_point_special;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static INLINE void gen_filter_bilinear_sub(struct scaler_filter *filter,
|
||||
int len, int pos, int step)
|
||||
{
|
||||
|
@ -91,29 +55,6 @@ static INLINE void gen_filter_bilinear_sub(struct scaler_filter *filter,
|
|||
}
|
||||
}
|
||||
|
||||
static bool gen_filter_bilinear(struct scaler_ctx *ctx)
|
||||
{
|
||||
int x_pos, x_step, y_pos, y_step;
|
||||
|
||||
ctx->horiz.filter_len = 2;
|
||||
ctx->horiz.filter_stride = 2;
|
||||
ctx->vert.filter_len = 2;
|
||||
ctx->vert.filter_stride = 2;
|
||||
|
||||
if (!allocate_filters(ctx))
|
||||
return false;
|
||||
|
||||
x_pos = (1 << 15) * ctx->in_width / ctx->out_width - (1 << 15);
|
||||
x_step = (1 << 16) * ctx->in_width / ctx->out_width;
|
||||
y_pos = (1 << 15) * ctx->in_height / ctx->out_height - (1 << 15);
|
||||
y_step = (1 << 16) * ctx->in_height / ctx->out_height;
|
||||
|
||||
gen_filter_bilinear_sub(&ctx->horiz, ctx->out_width, x_pos, x_step);
|
||||
gen_filter_bilinear_sub(&ctx->vert, ctx->out_height, y_pos, y_step);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static INLINE void gen_filter_sinc_sub(struct scaler_filter *filter,
|
||||
int len, int pos, int step, double phase_mul)
|
||||
{
|
||||
|
@ -135,37 +76,6 @@ static INLINE void gen_filter_sinc_sub(struct scaler_filter *filter,
|
|||
}
|
||||
}
|
||||
|
||||
static bool gen_filter_sinc(struct scaler_ctx *ctx)
|
||||
{
|
||||
int x_pos, x_step, y_pos, y_step;
|
||||
double phase_mul_horiz, phase_mul_vert;
|
||||
/* Need to expand the filter when downsampling
|
||||
* to get a proper low-pass effect. */
|
||||
const int sinc_size = 8 * ((ctx->in_width > ctx->out_width)
|
||||
? next_pow2(ctx->in_width / ctx->out_width) : 1);
|
||||
|
||||
ctx->horiz.filter_len = sinc_size;
|
||||
ctx->horiz.filter_stride = sinc_size;
|
||||
ctx->vert.filter_len = sinc_size;
|
||||
ctx->vert.filter_stride = sinc_size;
|
||||
|
||||
if (!allocate_filters(ctx))
|
||||
return false;
|
||||
|
||||
x_pos = (1 << 15) * ctx->in_width / ctx->out_width - (1 << 15) - (sinc_size << 15);
|
||||
x_step = (1 << 16) * ctx->in_width / ctx->out_width;
|
||||
y_pos = (1 << 15) * ctx->in_height / ctx->out_height - (1 << 15) - (sinc_size << 15);
|
||||
y_step = (1 << 16) * ctx->in_height / ctx->out_height;
|
||||
|
||||
phase_mul_horiz = ctx->in_width > ctx->out_width ? (double)ctx->out_width / ctx->in_width : 1.0;
|
||||
phase_mul_vert = ctx->in_height > ctx->out_height ? (double)ctx->out_height / ctx->in_height : 1.0;
|
||||
|
||||
gen_filter_sinc_sub(&ctx->horiz, ctx->out_width, x_pos, x_step, phase_mul_horiz);
|
||||
gen_filter_sinc_sub(&ctx->vert, ctx->out_height, y_pos, y_step, phase_mul_vert);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool validate_filter(struct scaler_ctx *ctx)
|
||||
{
|
||||
int i;
|
||||
|
@ -241,25 +151,82 @@ static void fixup_filter_sub(struct scaler_filter *filter,
|
|||
|
||||
bool scaler_gen_filter(struct scaler_ctx *ctx)
|
||||
{
|
||||
int x_pos, x_step, y_pos, y_step, sinc_size;
|
||||
|
||||
switch (ctx->scaler_type)
|
||||
{
|
||||
case SCALER_TYPE_POINT:
|
||||
if (!gen_filter_point(ctx))
|
||||
return false;
|
||||
ctx->horiz.filter_len = 1;
|
||||
ctx->horiz.filter_stride = 1;
|
||||
ctx->vert.filter_len = 1;
|
||||
ctx->vert.filter_stride = 1;
|
||||
break;
|
||||
case SCALER_TYPE_BILINEAR:
|
||||
ctx->horiz.filter_len = 2;
|
||||
ctx->horiz.filter_stride = 2;
|
||||
ctx->vert.filter_len = 2;
|
||||
ctx->vert.filter_stride = 2;
|
||||
break;
|
||||
case SCALER_TYPE_SINC:
|
||||
sinc_size = 8 * ((ctx->in_width > ctx->out_width)
|
||||
? next_pow2(ctx->in_width / ctx->out_width) : 1);
|
||||
ctx->horiz.filter_len = sinc_size;
|
||||
ctx->horiz.filter_stride = sinc_size;
|
||||
ctx->vert.filter_len = sinc_size;
|
||||
ctx->vert.filter_stride = sinc_size;
|
||||
break;
|
||||
case SCALER_TYPE_UNKNOWN:
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
ctx->horiz.filter = (int16_t*)calloc(sizeof(int16_t), ctx->horiz.filter_stride * ctx->out_width);
|
||||
ctx->horiz.filter_pos = (int*)calloc(sizeof(int), ctx->out_width);
|
||||
|
||||
ctx->vert.filter = (int16_t*)calloc(sizeof(int16_t), ctx->vert.filter_stride * ctx->out_height);
|
||||
ctx->vert.filter_pos = (int*)calloc(sizeof(int), ctx->out_height);
|
||||
|
||||
if (!ctx->horiz.filter || !ctx->vert.filter)
|
||||
return false;
|
||||
|
||||
x_step = (1 << 16) * ctx->in_width / ctx->out_width;
|
||||
y_step = (1 << 16) * ctx->in_height / ctx->out_height;
|
||||
|
||||
switch (ctx->scaler_type)
|
||||
{
|
||||
case SCALER_TYPE_POINT:
|
||||
x_pos = (1 << 15) * ctx->in_width / ctx->out_width - (1 << 15);
|
||||
y_pos = (1 << 15) * ctx->in_height / ctx->out_height - (1 << 15);
|
||||
|
||||
gen_filter_point_sub(&ctx->horiz, ctx->out_width, x_pos, x_step);
|
||||
gen_filter_point_sub(&ctx->vert, ctx->out_height, y_pos, y_step);
|
||||
|
||||
ctx->scaler_special = scaler_argb8888_point_special;
|
||||
break;
|
||||
|
||||
case SCALER_TYPE_BILINEAR:
|
||||
if (!gen_filter_bilinear(ctx))
|
||||
return false;
|
||||
x_pos = (1 << 15) * ctx->in_width / ctx->out_width - (1 << 15);
|
||||
y_pos = (1 << 15) * ctx->in_height / ctx->out_height - (1 << 15);
|
||||
|
||||
gen_filter_bilinear_sub(&ctx->horiz, ctx->out_width, x_pos, x_step);
|
||||
gen_filter_bilinear_sub(&ctx->vert, ctx->out_height, y_pos, y_step);
|
||||
break;
|
||||
|
||||
case SCALER_TYPE_SINC:
|
||||
if (!gen_filter_sinc(ctx))
|
||||
return false;
|
||||
break;
|
||||
/* Need to expand the filter when downsampling
|
||||
* to get a proper low-pass effect. */
|
||||
|
||||
default:
|
||||
return false;
|
||||
x_pos = (1 << 15) * ctx->in_width / ctx->out_width - (1 << 15) - (sinc_size << 15);
|
||||
y_pos = (1 << 15) * ctx->in_height / ctx->out_height - (1 << 15) - (sinc_size << 15);
|
||||
|
||||
gen_filter_sinc_sub(&ctx->horiz, ctx->out_width, x_pos, x_step,
|
||||
ctx->in_width > ctx->out_width ? (double)ctx->out_width / ctx->in_width : 1.0);
|
||||
gen_filter_sinc_sub(&ctx->vert, ctx->out_height, y_pos, y_step,
|
||||
ctx->in_height > ctx->out_height ? (double)ctx->out_height / ctx->in_height : 1.0
|
||||
);
|
||||
break;
|
||||
case SCALER_TYPE_UNKNOWN:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Makes sure that we never sample outside our rectangle. */
|
||||
|
|
Loading…
Reference in New Issue