mirror of
https://github.com/CTCaer/RetroArch.git
synced 2024-12-16 07:16:36 +00:00
Update SDK/documentation
This commit is contained in:
parent
c72fdcf1c3
commit
2779298371
@ -749,6 +749,7 @@ void conv_argb8888_abgr8888(void *output_, const void *input_,
|
|||||||
#define YUV_MAT_U_B (113)
|
#define YUV_MAT_U_B (113)
|
||||||
#define YUV_MAT_V_R (90)
|
#define YUV_MAT_V_R (90)
|
||||||
#define YUV_MAT_V_G (-46)
|
#define YUV_MAT_V_G (-46)
|
||||||
|
|
||||||
#if defined(__SSE2__)
|
#if defined(__SSE2__)
|
||||||
void conv_yuyv_argb8888(void *output_, const void *input_,
|
void conv_yuyv_argb8888(void *output_, const void *input_,
|
||||||
int width, int height,
|
int width, int height,
|
||||||
@ -920,12 +921,12 @@ void conv_copy(void *output_, const void *input_,
|
|||||||
{
|
{
|
||||||
int h;
|
int h;
|
||||||
int copy_len = abs(out_stride);
|
int copy_len = abs(out_stride);
|
||||||
if (abs(in_stride) < copy_len)
|
|
||||||
copy_len = abs(in_stride);
|
|
||||||
|
|
||||||
const uint8_t *input = (const uint8_t*)input_;
|
const uint8_t *input = (const uint8_t*)input_;
|
||||||
uint8_t *output = (uint8_t*)output_;
|
uint8_t *output = (uint8_t*)output_;
|
||||||
|
|
||||||
|
if (abs(in_stride) < copy_len)
|
||||||
|
copy_len = abs(in_stride);
|
||||||
|
|
||||||
for (h = 0; h < height;
|
for (h = 0; h < height;
|
||||||
h++, output += out_stride, input += in_stride)
|
h++, output += out_stride, input += in_stride)
|
||||||
memcpy(output, input, copy_len);
|
memcpy(output, input, copy_len);
|
||||||
|
@ -38,7 +38,8 @@ static bool allocate_filters(struct scaler_ctx *ctx)
|
|||||||
return ctx->horiz.filter && ctx->vert.filter;
|
return ctx->horiz.filter && ctx->vert.filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gen_filter_point_sub(struct scaler_filter *filter, int len, int pos, int step)
|
static void gen_filter_point_sub(struct scaler_filter *filter,
|
||||||
|
int len, int pos, int step)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < len; i++, pos += step)
|
for (i = 0; i < len; i++, pos += step)
|
||||||
@ -50,6 +51,8 @@ static void gen_filter_point_sub(struct scaler_filter *filter, int len, int pos,
|
|||||||
|
|
||||||
static bool gen_filter_point(struct scaler_ctx *ctx)
|
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_len = 1;
|
||||||
ctx->horiz.filter_stride = 1;
|
ctx->horiz.filter_stride = 1;
|
||||||
ctx->vert.filter_len = 1;
|
ctx->vert.filter_len = 1;
|
||||||
@ -58,10 +61,10 @@ static bool gen_filter_point(struct scaler_ctx *ctx)
|
|||||||
if (!allocate_filters(ctx))
|
if (!allocate_filters(ctx))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
int x_pos = (1 << 15) * ctx->in_width / ctx->out_width - (1 << 15);
|
x_pos = (1 << 15) * ctx->in_width / ctx->out_width - (1 << 15);
|
||||||
int x_step = (1 << 16) * ctx->in_width / ctx->out_width;
|
x_step = (1 << 16) * ctx->in_width / ctx->out_width;
|
||||||
int y_pos = (1 << 15) * ctx->in_height / ctx->out_height - (1 << 15);
|
y_pos = (1 << 15) * ctx->in_height / ctx->out_height - (1 << 15);
|
||||||
int y_step = (1 << 16) * ctx->in_height / ctx->out_height;
|
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->horiz, ctx->out_width, x_pos, x_step);
|
||||||
gen_filter_point_sub(&ctx->vert, ctx->out_height, y_pos, y_step);
|
gen_filter_point_sub(&ctx->vert, ctx->out_height, y_pos, y_step);
|
||||||
@ -71,7 +74,8 @@ static bool gen_filter_point(struct scaler_ctx *ctx)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gen_filter_bilinear_sub(struct scaler_filter *filter, int len, int pos, int step)
|
static void gen_filter_bilinear_sub(struct scaler_filter *filter,
|
||||||
|
int len, int pos, int step)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < len; i++, pos += step)
|
for (i = 0; i < len; i++, pos += step)
|
||||||
@ -84,6 +88,8 @@ static void gen_filter_bilinear_sub(struct scaler_filter *filter, int len, int p
|
|||||||
|
|
||||||
static bool gen_filter_bilinear(struct scaler_ctx *ctx)
|
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_len = 2;
|
||||||
ctx->horiz.filter_stride = 2;
|
ctx->horiz.filter_stride = 2;
|
||||||
ctx->vert.filter_len = 2;
|
ctx->vert.filter_len = 2;
|
||||||
@ -92,10 +98,10 @@ static bool gen_filter_bilinear(struct scaler_ctx *ctx)
|
|||||||
if (!allocate_filters(ctx))
|
if (!allocate_filters(ctx))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
int x_pos = (1 << 15) * ctx->in_width / ctx->out_width - (1 << 15);
|
x_pos = (1 << 15) * ctx->in_width / ctx->out_width - (1 << 15);
|
||||||
int x_step = (1 << 16) * ctx->in_width / ctx->out_width;
|
x_step = (1 << 16) * ctx->in_width / ctx->out_width;
|
||||||
int y_pos = (1 << 15) * ctx->in_height / ctx->out_height - (1 << 15);
|
y_pos = (1 << 15) * ctx->in_height / ctx->out_height - (1 << 15);
|
||||||
int y_step = (1 << 16) * ctx->in_height / ctx->out_height;
|
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->horiz, ctx->out_width, x_pos, x_step);
|
||||||
gen_filter_bilinear_sub(&ctx->vert, ctx->out_height, y_pos, y_step);
|
gen_filter_bilinear_sub(&ctx->vert, ctx->out_height, y_pos, y_step);
|
||||||
@ -110,7 +116,8 @@ static inline double filter_sinc(double phase)
|
|||||||
return sin(phase) / phase;
|
return sin(phase) / phase;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gen_filter_sinc_sub(struct scaler_filter *filter, int len, int pos, int step, double phase_mul)
|
static void gen_filter_sinc_sub(struct scaler_filter *filter,
|
||||||
|
int len, int pos, int step, double phase_mul)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
const int sinc_size = filter->filter_len;
|
const int sinc_size = filter->filter_len;
|
||||||
@ -135,8 +142,13 @@ static void gen_filter_sinc_sub(struct scaler_filter *filter, int len, int pos,
|
|||||||
|
|
||||||
static bool gen_filter_sinc(struct scaler_ctx *ctx)
|
static bool gen_filter_sinc(struct scaler_ctx *ctx)
|
||||||
{
|
{
|
||||||
// Need to expand the filter when downsampling to get a proper low-pass effect.
|
int x_pos, x_step, y_pos, y_step;
|
||||||
const int sinc_size = 8 * (ctx->in_width > ctx->out_width ? next_pow2(ctx->in_width / ctx->out_width) : 1);
|
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_len = sinc_size;
|
||||||
ctx->horiz.filter_stride = sinc_size;
|
ctx->horiz.filter_stride = sinc_size;
|
||||||
ctx->vert.filter_len = sinc_size;
|
ctx->vert.filter_len = sinc_size;
|
||||||
@ -145,13 +157,13 @@ static bool gen_filter_sinc(struct scaler_ctx *ctx)
|
|||||||
if (!allocate_filters(ctx))
|
if (!allocate_filters(ctx))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
int x_pos = (1 << 15) * ctx->in_width / ctx->out_width - (1 << 15) - (sinc_size << 15);
|
x_pos = (1 << 15) * ctx->in_width / ctx->out_width - (1 << 15) - (sinc_size << 15);
|
||||||
int x_step = (1 << 16) * ctx->in_width / ctx->out_width;
|
x_step = (1 << 16) * ctx->in_width / ctx->out_width;
|
||||||
int y_pos = (1 << 15) * ctx->in_height / ctx->out_height - (1 << 15) - (sinc_size << 15);
|
y_pos = (1 << 15) * ctx->in_height / ctx->out_height - (1 << 15) - (sinc_size << 15);
|
||||||
int y_step = (1 << 16) * ctx->in_height / ctx->out_height;
|
y_step = (1 << 16) * ctx->in_height / ctx->out_height;
|
||||||
|
|
||||||
double phase_mul_horiz = ctx->in_width > ctx->out_width ? (double)ctx->out_width / ctx->in_width : 1.0;
|
phase_mul_horiz = ctx->in_width > ctx->out_width ? (double)ctx->out_width / ctx->in_width : 1.0;
|
||||||
double phase_mul_vert = ctx->in_height > ctx->out_height ? (double)ctx->out_height / ctx->in_height : 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->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);
|
gen_filter_sinc_sub(&ctx->vert, ctx->out_height, y_pos, y_step, phase_mul_vert);
|
||||||
@ -163,7 +175,9 @@ static bool gen_filter_sinc(struct scaler_ctx *ctx)
|
|||||||
static bool validate_filter(struct scaler_ctx *ctx)
|
static bool validate_filter(struct scaler_ctx *ctx)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
int max_h_pos;
|
||||||
int max_w_pos = ctx->in_width - ctx->horiz.filter_len;
|
int max_w_pos = ctx->in_width - ctx->horiz.filter_len;
|
||||||
|
|
||||||
for (i = 0; i < ctx->out_width; i++)
|
for (i = 0; i < ctx->out_width; i++)
|
||||||
{
|
{
|
||||||
if (ctx->horiz.filter_pos[i] > max_w_pos || ctx->horiz.filter_pos[i] < 0)
|
if (ctx->horiz.filter_pos[i] > max_w_pos || ctx->horiz.filter_pos[i] < 0)
|
||||||
@ -173,7 +187,8 @@ static bool validate_filter(struct scaler_ctx *ctx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int max_h_pos = ctx->in_height - ctx->vert.filter_len;
|
max_h_pos = ctx->in_height - ctx->vert.filter_len;
|
||||||
|
|
||||||
for (i = 0; i < ctx->out_height; i++)
|
for (i = 0; i < ctx->out_height; i++)
|
||||||
{
|
{
|
||||||
if (ctx->vert.filter_pos[i] > max_h_pos || ctx->vert.filter_pos[i] < 0)
|
if (ctx->vert.filter_pos[i] > max_h_pos || ctx->vert.filter_pos[i] < 0)
|
||||||
@ -198,36 +213,40 @@ static void fixup_filter_sub(struct scaler_filter *filter, int out_len, int in_l
|
|||||||
|
|
||||||
if (postsample > 0)
|
if (postsample > 0)
|
||||||
{
|
{
|
||||||
|
int16_t *base_filter = NULL;
|
||||||
filter->filter_pos[i] -= postsample;
|
filter->filter_pos[i] -= postsample;
|
||||||
|
|
||||||
int16_t *base_filter = filter->filter + i * filter->filter_stride;
|
base_filter = filter->filter + i * filter->filter_stride;
|
||||||
|
|
||||||
if (postsample > (int)filter->filter_len)
|
if (postsample > (int)filter->filter_len)
|
||||||
memset(base_filter, 0, filter->filter_len * sizeof(int16_t));
|
memset(base_filter, 0, filter->filter_len * sizeof(int16_t));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memmove(base_filter + postsample, base_filter, (filter->filter_len - postsample) * sizeof(int16_t));
|
memmove(base_filter + postsample, base_filter,
|
||||||
|
(filter->filter_len - postsample) * sizeof(int16_t));
|
||||||
memset(base_filter, 0, postsample * sizeof(int16_t));
|
memset(base_filter, 0, postsample * sizeof(int16_t));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (presample > 0)
|
if (presample > 0)
|
||||||
{
|
{
|
||||||
|
int16_t *base_filter = NULL;
|
||||||
filter->filter_pos[i] += presample;
|
filter->filter_pos[i] += presample;
|
||||||
int16_t *base_filter = filter->filter + i * filter->filter_stride;
|
base_filter = filter->filter + i * filter->filter_stride;
|
||||||
|
|
||||||
if (presample > (int)filter->filter_len)
|
if (presample > (int)filter->filter_len)
|
||||||
memset(base_filter, 0, filter->filter_len * sizeof(int16_t));
|
memset(base_filter, 0, filter->filter_len * sizeof(int16_t));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memmove(base_filter, base_filter + presample, (filter->filter_len - presample) * sizeof(int16_t));
|
memmove(base_filter, base_filter + presample,
|
||||||
|
(filter->filter_len - presample) * sizeof(int16_t));
|
||||||
memset(base_filter + (filter->filter_len - presample), 0, presample * sizeof(int16_t));
|
memset(base_filter + (filter->filter_len - presample), 0, presample * sizeof(int16_t));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Makes sure that we never sample outside our rectangle.
|
/* Makes sure that we never sample outside our rectangle. */
|
||||||
static void fixup_filter(struct scaler_ctx *ctx)
|
static void fixup_filter(struct scaler_ctx *ctx)
|
||||||
{
|
{
|
||||||
fixup_filter_sub(&ctx->horiz, ctx->out_width, ctx->in_width);
|
fixup_filter_sub(&ctx->horiz, ctx->out_width, ctx->in_width);
|
||||||
|
@ -251,20 +251,23 @@ void scaler_argb8888_point_special(const struct scaler_ctx *ctx,
|
|||||||
int in_width, int in_height,
|
int in_width, int in_height,
|
||||||
int out_stride, int in_stride)
|
int out_stride, int in_stride)
|
||||||
{
|
{
|
||||||
|
const uint32_t *input = NULL;
|
||||||
|
uint32_t *output = NULL;
|
||||||
int h, w;
|
int h, w;
|
||||||
(void)ctx;
|
|
||||||
int x_pos = (1 << 15) * in_width / out_width - (1 << 15);
|
int x_pos = (1 << 15) * in_width / out_width - (1 << 15);
|
||||||
int x_step = (1 << 16) * in_width / out_width;
|
int x_step = (1 << 16) * in_width / out_width;
|
||||||
int y_pos = (1 << 15) * in_height / out_height - (1 << 15);
|
int y_pos = (1 << 15) * in_height / out_height - (1 << 15);
|
||||||
int y_step = (1 << 16) * in_height / out_height;
|
int y_step = (1 << 16) * in_height / out_height;
|
||||||
|
|
||||||
|
(void)ctx;
|
||||||
|
|
||||||
if (x_pos < 0)
|
if (x_pos < 0)
|
||||||
x_pos = 0;
|
x_pos = 0;
|
||||||
if (y_pos < 0)
|
if (y_pos < 0)
|
||||||
y_pos = 0;
|
y_pos = 0;
|
||||||
|
|
||||||
const uint32_t *input = (const uint32_t*)input_;
|
input = (const uint32_t*)input_;
|
||||||
uint32_t *output = (uint32_t*)output_;
|
output = (uint32_t*)output_;
|
||||||
|
|
||||||
for (h = 0; h < out_height; h++, y_pos += y_step, output += out_stride >> 2)
|
for (h = 0; h < out_height; h++, y_pos += y_step, output += out_stride >> 2)
|
||||||
{
|
{
|
||||||
|
@ -111,12 +111,38 @@ struct scaler_ctx
|
|||||||
};
|
};
|
||||||
|
|
||||||
bool scaler_ctx_gen_filter(struct scaler_ctx *ctx);
|
bool scaler_ctx_gen_filter(struct scaler_ctx *ctx);
|
||||||
|
|
||||||
void scaler_ctx_gen_reset(struct scaler_ctx *ctx);
|
void scaler_ctx_gen_reset(struct scaler_ctx *ctx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* scaler_ctx_scale:
|
||||||
|
* @ctx : pointer to scaler context object.
|
||||||
|
* @output : pointer to output image.
|
||||||
|
* @input : pointer to input image.
|
||||||
|
*
|
||||||
|
* Scales an input image to an output image.
|
||||||
|
**/
|
||||||
void scaler_ctx_scale(struct scaler_ctx *ctx,
|
void scaler_ctx_scale(struct scaler_ctx *ctx,
|
||||||
void *output, const void *input);
|
void *output, const void *input);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* scaler_alloc:
|
||||||
|
* @elem_size : size of the elements to be used.
|
||||||
|
* @siz : size of the image that the scaler needs to handle.
|
||||||
|
*
|
||||||
|
* Allocate and returns a scaler object.
|
||||||
|
*
|
||||||
|
* Returns: pointer to a scaler object of type 'void *' on success,
|
||||||
|
* NULL in case of error. Has to be freed manually.
|
||||||
|
**/
|
||||||
void *scaler_alloc(size_t elem_size, size_t size);
|
void *scaler_alloc(size_t elem_size, size_t size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* scaler_free:
|
||||||
|
* @ptr : pointer to scaler object.
|
||||||
|
*
|
||||||
|
* Frees a scaler object.
|
||||||
|
**/
|
||||||
void scaler_free(void *ptr);
|
void scaler_free(void *ptr);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
Loading…
Reference in New Issue
Block a user