From 27792983714c81664aa32f60d8d996f665f5aa4a Mon Sep 17 00:00:00 2001 From: twinaphex Date: Thu, 8 Jan 2015 19:23:59 +0100 Subject: [PATCH] Update SDK/documentation --- libretro-sdk/gfx/scaler/pixconv.c | 7 +-- libretro-sdk/gfx/scaler/scaler_filter.c | 69 +++++++++++++++--------- libretro-sdk/gfx/scaler/scaler_int.c | 9 ++-- libretro-sdk/include/gfx/scaler/scaler.h | 26 +++++++++ 4 files changed, 80 insertions(+), 31 deletions(-) diff --git a/libretro-sdk/gfx/scaler/pixconv.c b/libretro-sdk/gfx/scaler/pixconv.c index 3dd244fc57..b4f7bc7c7a 100644 --- a/libretro-sdk/gfx/scaler/pixconv.c +++ b/libretro-sdk/gfx/scaler/pixconv.c @@ -749,6 +749,7 @@ void conv_argb8888_abgr8888(void *output_, const void *input_, #define YUV_MAT_U_B (113) #define YUV_MAT_V_R (90) #define YUV_MAT_V_G (-46) + #if defined(__SSE2__) void conv_yuyv_argb8888(void *output_, const void *input_, int width, int height, @@ -920,12 +921,12 @@ void conv_copy(void *output_, const void *input_, { int h; 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_; uint8_t *output = (uint8_t*)output_; + if (abs(in_stride) < copy_len) + copy_len = abs(in_stride); + for (h = 0; h < height; h++, output += out_stride, input += in_stride) memcpy(output, input, copy_len); diff --git a/libretro-sdk/gfx/scaler/scaler_filter.c b/libretro-sdk/gfx/scaler/scaler_filter.c index 0770f87f0a..67bc029045 100644 --- a/libretro-sdk/gfx/scaler/scaler_filter.c +++ b/libretro-sdk/gfx/scaler/scaler_filter.c @@ -38,7 +38,8 @@ static bool allocate_filters(struct scaler_ctx *ctx) 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; 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) { + int x_pos, x_step, y_pos, y_step; + ctx->horiz.filter_len = 1; ctx->horiz.filter_stride = 1; ctx->vert.filter_len = 1; @@ -58,10 +61,10 @@ static bool gen_filter_point(struct scaler_ctx *ctx) if (!allocate_filters(ctx)) return false; - int x_pos = (1 << 15) * ctx->in_width / ctx->out_width - (1 << 15); - int x_step = (1 << 16) * ctx->in_width / ctx->out_width; - int y_pos = (1 << 15) * ctx->in_height / ctx->out_height - (1 << 15); - int y_step = (1 << 16) * ctx->in_height / ctx->out_height; + 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); @@ -71,7 +74,8 @@ static bool gen_filter_point(struct scaler_ctx *ctx) 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; 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) { + int x_pos, x_step, y_pos, y_step; + ctx->horiz.filter_len = 2; ctx->horiz.filter_stride = 2; ctx->vert.filter_len = 2; @@ -92,10 +98,10 @@ static bool gen_filter_bilinear(struct scaler_ctx *ctx) if (!allocate_filters(ctx)) return false; - int x_pos = (1 << 15) * ctx->in_width / ctx->out_width - (1 << 15); - int x_step = (1 << 16) * ctx->in_width / ctx->out_width; - int y_pos = (1 << 15) * ctx->in_height / ctx->out_height - (1 << 15); - int y_step = (1 << 16) * ctx->in_height / ctx->out_height; + 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); @@ -110,7 +116,8 @@ static inline double filter_sinc(double 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; 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) { - // 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); + 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; @@ -145,13 +157,13 @@ static bool gen_filter_sinc(struct scaler_ctx *ctx) if (!allocate_filters(ctx)) return false; - int 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; - int 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; + 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; - double 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_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); @@ -163,7 +175,9 @@ static bool gen_filter_sinc(struct scaler_ctx *ctx) static bool validate_filter(struct scaler_ctx *ctx) { int i; + int max_h_pos; int max_w_pos = ctx->in_width - ctx->horiz.filter_len; + for (i = 0; i < ctx->out_width; i++) { 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++) { 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) { + int16_t *base_filter = NULL; 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) memset(base_filter, 0, filter->filter_len * sizeof(int16_t)); 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)); } } if (presample > 0) { + int16_t *base_filter = NULL; 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) memset(base_filter, 0, filter->filter_len * sizeof(int16_t)); 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)); } } } } -// 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) { fixup_filter_sub(&ctx->horiz, ctx->out_width, ctx->in_width); diff --git a/libretro-sdk/gfx/scaler/scaler_int.c b/libretro-sdk/gfx/scaler/scaler_int.c index 90818c923d..294458e67a 100644 --- a/libretro-sdk/gfx/scaler/scaler_int.c +++ b/libretro-sdk/gfx/scaler/scaler_int.c @@ -251,20 +251,23 @@ void scaler_argb8888_point_special(const struct scaler_ctx *ctx, int in_width, int in_height, int out_stride, int in_stride) { + const uint32_t *input = NULL; + uint32_t *output = NULL; int h, w; - (void)ctx; int x_pos = (1 << 15) * in_width / out_width - (1 << 15); int x_step = (1 << 16) * in_width / out_width; int y_pos = (1 << 15) * in_height / out_height - (1 << 15); int y_step = (1 << 16) * in_height / out_height; + (void)ctx; + if (x_pos < 0) x_pos = 0; if (y_pos < 0) y_pos = 0; - const uint32_t *input = (const uint32_t*)input_; - uint32_t *output = (uint32_t*)output_; + input = (const uint32_t*)input_; + output = (uint32_t*)output_; for (h = 0; h < out_height; h++, y_pos += y_step, output += out_stride >> 2) { diff --git a/libretro-sdk/include/gfx/scaler/scaler.h b/libretro-sdk/include/gfx/scaler/scaler.h index 247dc21dfb..73fc675c85 100644 --- a/libretro-sdk/include/gfx/scaler/scaler.h +++ b/libretro-sdk/include/gfx/scaler/scaler.h @@ -111,12 +111,38 @@ struct scaler_ctx }; bool scaler_ctx_gen_filter(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 *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); + +/** + * scaler_free: + * @ptr : pointer to scaler object. + * + * Frees a scaler object. + **/ void scaler_free(void *ptr); #ifdef __cplusplus