(Softfilter plugs) Identing cleanups

This commit is contained in:
twinaphex 2014-09-09 04:53:24 +02:00
parent f4332eebbd
commit 9ee74bb5a2
9 changed files with 415 additions and 239 deletions

View File

@ -33,8 +33,6 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// Compile: gcc -o twoxbr.so -shared twoxbr.c -std=c99 -O3 -Wall -pedantic -fPIC
#include "softfilter.h"
#include <stdlib.h>
#include <string.h>
@ -233,7 +231,8 @@ static void *twoxbr_generic_create(const struct softfilter_config *config,
struct filter_data *filt = (struct filter_data*)calloc(1, sizeof(*filt));
if (!filt)
return NULL;
filt->workers = (struct softfilter_thread_data*)calloc(threads, sizeof(struct softfilter_thread_data));
filt->workers = (struct softfilter_thread_data*)
calloc(threads, sizeof(struct softfilter_thread_data));
filt->threads = threads;
filt->in_fmt = in_fmt;
if (!filt->workers)
@ -247,7 +246,8 @@ static void *twoxbr_generic_create(const struct softfilter_config *config,
return filt;
}
static void twoxbr_generic_output(void *data, unsigned *out_width, unsigned *out_height,
static void twoxbr_generic_output(void *data,
unsigned *out_width, unsigned *out_height,
unsigned width, unsigned height)
{
*out_width = width * TWOXBR_SCALE;
@ -261,12 +261,6 @@ static void twoxbr_generic_destroy(void *data)
free(filt);
}
//---------------------------------------------------------------------------------------------------------------------------
#define ALPHA_BLEND_128_W(dst, src) dst = ((src & pg_lbmask) >> 1) + ((dst & pg_lbmask) >> 1)
#define ALPHA_BLEND_32_W(dst, src) \
@ -418,7 +412,8 @@ static void twoxbr_generic_destroy(void *data)
float df8(uint32_t A, uint32_t B, uint32_t pg_red_mask, uint32_t pg_green_mask, uint32_t pg_blue_mask)
float df8(uint32_t A, uint32_t B,
uint32_t pg_red_mask, uint32_t pg_green_mask, uint32_t pg_blue_mask)
{
uint32_t r, g, b;
uint32_t y, u, v;
@ -440,7 +435,8 @@ float df8(uint32_t A, uint32_t B, uint32_t pg_red_mask, uint32_t pg_green_mask,
return 48*y + 7*u + 6*v;
}
int eq8(uint32_t A, uint32_t B, uint32_t pg_red_mask, uint32_t pg_green_mask, uint32_t pg_blue_mask)
int eq8(uint32_t A, uint32_t B,
uint32_t pg_red_mask, uint32_t pg_green_mask, uint32_t pg_blue_mask)
{
uint32_t r, g, b;
uint32_t y, u, v;
@ -600,12 +596,13 @@ static void twoxbr_generic_xrgb8888(void *data, unsigned width, unsigned height,
{
twoxbr_declare_variables(uint32_t, in, nextline);
//---------------------------------------
// Map of the pixels: A1 B1 C1
// A0 PA PB PC C4
// D0 PD PE PF F4
// G0 PG PH PI I4
// G5 H5 I5
/*
* Map of the pixels: A1 B1 C1
* A0 PA PB PC C4
* D0 PD PE PF F4
* G0 PG PH PI I4
* G5 H5 I5
*/
twoxbr_function(FILTRO_RGB8888, filt);
}
@ -639,12 +636,13 @@ static void twoxbr_generic_rgb565(void *data, unsigned width, unsigned height,
{
twoxbr_declare_variables(uint16_t, in, nextline);
//---------------------------------------
// Map of the pixels: A1 B1 C1
// A0 PA PB PC C4
// D0 PD PE PF F4
// G0 PG PH PI I4
// G5 H5 I5
/*
* Map of the pixels: A1 B1 C1
* A0 PA PB PC C4
* D0 PD PE PF F4
* G0 PG PH PI I4
* G5 H5 I5
*/
twoxbr_function(FILTRO_RGB565, filt);
}
@ -656,56 +654,68 @@ static void twoxbr_generic_rgb565(void *data, unsigned width, unsigned height,
static void twoxbr_work_cb_rgb565(void *data, void *thread_data)
{
struct softfilter_thread_data *thr = (struct softfilter_thread_data*)thread_data;
struct softfilter_thread_data *thr =
(struct softfilter_thread_data*)thread_data;
uint16_t *input = (uint16_t*)thr->in_data;
uint16_t *output = (uint16_t*)thr->out_data;
unsigned width = thr->width;
unsigned height = thr->height;
twoxbr_generic_rgb565(data, width, height,
thr->first, thr->last, input, thr->in_pitch / SOFTFILTER_BPP_RGB565, output, thr->out_pitch / SOFTFILTER_BPP_RGB565);
thr->first, thr->last, input,
thr->in_pitch / SOFTFILTER_BPP_RGB565, output,
thr->out_pitch / SOFTFILTER_BPP_RGB565);
}
static void twoxbr_work_cb_xrgb8888(void *data, void *thread_data)
{
struct softfilter_thread_data *thr = (struct softfilter_thread_data*)thread_data;
struct softfilter_thread_data *thr =
(struct softfilter_thread_data*)thread_data;
uint32_t *input = (uint32_t*)thr->in_data;
uint32_t *output = (uint32_t*)thr->out_data;
unsigned width = thr->width;
unsigned height = thr->height;
twoxbr_generic_xrgb8888(data, width, height,
thr->first, thr->last, input, thr->in_pitch / SOFTFILTER_BPP_XRGB8888, output, thr->out_pitch / SOFTFILTER_BPP_XRGB8888);
thr->first, thr->last, input,
thr->in_pitch / SOFTFILTER_BPP_XRGB8888, output,
thr->out_pitch / SOFTFILTER_BPP_XRGB8888);
}
static void twoxbr_generic_packets(void *data,
struct softfilter_work_packet *packets,
void *output, size_t output_stride,
const void *input, unsigned width, unsigned height, size_t input_stride)
const void *input, unsigned width,
unsigned height, size_t input_stride)
{
struct filter_data *filt = (struct filter_data*)data;
unsigned i;
for (i = 0; i < filt->threads; i++)
{
struct softfilter_thread_data *thr = (struct softfilter_thread_data*)&filt->workers[i];
struct softfilter_thread_data *thr =
(struct softfilter_thread_data*)&filt->workers[i];
unsigned y_start = (height * i) / filt->threads;
unsigned y_end = (height * (i + 1)) / filt->threads;
thr->out_data = (uint8_t*)output + y_start * TWOXBR_SCALE * output_stride;
thr->out_data = (uint8_t*)output + y_start *
TWOXBR_SCALE * output_stride;
thr->in_data = (const uint8_t*)input + y_start * input_stride;
thr->out_pitch = output_stride;
thr->in_pitch = input_stride;
thr->width = width;
thr->height = y_end - y_start;
// Workers need to know if they can access pixels outside their given buffer.
/* Workers need to know if they can access
* pixels outside their given buffer. */
thr->first = y_start;
thr->last = y_end == height;
if (filt->in_fmt == SOFTFILTER_FMT_RGB565)
packets[i].work = twoxbr_work_cb_rgb565;
//else if (filt->in_fmt == SOFTFILTER_FMT_RGB4444)
//packets[i].work = twoxbr_work_cb_rgb4444;
#if 0
else if (filt->in_fmt == SOFTFILTER_FMT_RGB4444)
packets[i].work = twoxbr_work_cb_rgb4444;
#endif
else if (filt->in_fmt == SOFTFILTER_FMT_XRGB8888)
packets[i].work = twoxbr_work_cb_xrgb8888;
packets[i].thread_data = thr;
@ -727,7 +737,8 @@ static const struct softfilter_implementation twoxbr_generic = {
"2xbr",
};
const struct softfilter_implementation *softfilter_get_implementation(softfilter_simd_mask_t simd)
const struct softfilter_implementation *softfilter_get_implementation(
softfilter_simd_mask_t simd)
{
(void)simd;
return &twoxbr_generic;

View File

@ -14,8 +14,6 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
// Compile: gcc -o twoxsai.so -shared twoxsai.c -std=c99 -O3 -Wall -pedantic -fPIC
#include "softfilter.h"
#include <stdlib.h>
#include <string.h>
@ -76,7 +74,8 @@ static void *twoxsai_generic_create(const struct softfilter_config *config,
struct filter_data *filt = (struct filter_data*)calloc(1, sizeof(*filt));
if (!filt)
return NULL;
filt->workers = (struct softfilter_thread_data*)calloc(threads, sizeof(struct softfilter_thread_data));
filt->workers = (struct softfilter_thread_data*)
calloc(threads, sizeof(struct softfilter_thread_data));
filt->threads = threads;
filt->in_fmt = in_fmt;
if (!filt->workers)
@ -87,7 +86,8 @@ static void *twoxsai_generic_create(const struct softfilter_config *config,
return filt;
}
static void twoxsai_generic_output(void *data, unsigned *out_width, unsigned *out_height,
static void twoxsai_generic_output(void *data,
unsigned *out_width, unsigned *out_height,
unsigned width, unsigned height)
{
*out_width = width * TWOXSAI_SCALE;
@ -130,8 +130,7 @@ static void twoxsai_generic_destroy(void *data)
typename_t colorL = *(in + nextline + 2); \
typename_t colorM = *(in + nextline + nextline - 1); \
typename_t colorN = *(in + nextline + nextline + 0); \
typename_t colorO = *(in + nextline + nextline + 1); \
//typename_t colorP = *(in + nextline + nextline + 2);
typename_t colorO = *(in + nextline + nextline + 1);
#ifndef twoxsai_function
#define twoxsai_function(result_cb, interpolate_cb, interpolate2_cb) \
@ -237,13 +236,15 @@ static void twoxsai_generic_xrgb8888(unsigned width, unsigned height,
{
twoxsai_declare_variables(uint32_t, in, nextline);
//---------------------------------------
// Map of the pixels: I|E F|J
// G|A B|K
// H|C D|L
// M|N O|P
/*
* Map of the pixels: I|E F|J
* G|A B|K
* H|C D|L
* M|N O|P
*/
twoxsai_function(twoxsai_result, twoxsai_interpolate_xrgb8888, twoxsai_interpolate2_xrgb8888);
twoxsai_function(twoxsai_result, twoxsai_interpolate_xrgb8888,
twoxsai_interpolate2_xrgb8888);
}
src += src_stride;
@ -267,13 +268,15 @@ static void twoxsai_generic_rgb565(unsigned width, unsigned height,
{
twoxsai_declare_variables(uint16_t, in, nextline);
//---------------------------------------
// Map of the pixels: I|E F|J
// G|A B|K
// H|C D|L
// M|N O|P
/*
* Map of the pixels: I|E F|J
* G|A B|K
* H|C D|L
* M|N O|P
*/
twoxsai_function(twoxsai_result, twoxsai_interpolate_rgb565, twoxsai_interpolate2_rgb565);
twoxsai_function(twoxsai_result, twoxsai_interpolate_rgb565,
twoxsai_interpolate2_rgb565);
}
src += src_stride;
@ -283,56 +286,71 @@ static void twoxsai_generic_rgb565(unsigned width, unsigned height,
static void twoxsai_work_cb_rgb565(void *data, void *thread_data)
{
struct softfilter_thread_data *thr = (struct softfilter_thread_data*)thread_data;
struct softfilter_thread_data *thr =
(struct softfilter_thread_data*)thread_data;
uint16_t *input = (uint16_t*)thr->in_data;
uint16_t *output = (uint16_t*)thr->out_data;
unsigned width = thr->width;
unsigned height = thr->height;
twoxsai_generic_rgb565(width, height,
thr->first, thr->last, input, thr->in_pitch / SOFTFILTER_BPP_RGB565, output, thr->out_pitch / SOFTFILTER_BPP_RGB565);
thr->first, thr->last, input,
thr->in_pitch / SOFTFILTER_BPP_RGB565,
output,
thr->out_pitch / SOFTFILTER_BPP_RGB565);
}
static void twoxsai_work_cb_xrgb8888(void *data, void *thread_data)
{
struct softfilter_thread_data *thr = (struct softfilter_thread_data*)thread_data;
struct softfilter_thread_data *thr =
(struct softfilter_thread_data*)thread_data;
uint32_t *input = (uint32_t*)thr->in_data;
uint32_t *output = (uint32_t*)thr->out_data;
unsigned width = thr->width;
unsigned height = thr->height;
twoxsai_generic_xrgb8888(width, height,
thr->first, thr->last, input, thr->in_pitch / SOFTFILTER_BPP_XRGB8888, output, thr->out_pitch / SOFTFILTER_BPP_XRGB8888);
thr->first, thr->last, input,
thr->in_pitch / SOFTFILTER_BPP_XRGB8888,
output,
thr->out_pitch / SOFTFILTER_BPP_XRGB8888);
}
static void twoxsai_generic_packets(void *data,
struct softfilter_work_packet *packets,
void *output, size_t output_stride,
const void *input, unsigned width, unsigned height, size_t input_stride)
const void *input, unsigned width,
unsigned height, size_t input_stride)
{
struct filter_data *filt = (struct filter_data*)data;
unsigned i;
for (i = 0; i < filt->threads; i++)
{
struct softfilter_thread_data *thr = (struct softfilter_thread_data*)&filt->workers[i];
struct softfilter_thread_data *thr =
(struct softfilter_thread_data*)&filt->workers[i];
unsigned y_start = (height * i) / filt->threads;
unsigned y_end = (height * (i + 1)) / filt->threads;
thr->out_data = (uint8_t*)output + y_start * TWOXSAI_SCALE * output_stride;
thr->out_data = (uint8_t*)output + y_start *
TWOXSAI_SCALE * output_stride;
thr->in_data = (const uint8_t*)input + y_start * input_stride;
thr->out_pitch = output_stride;
thr->in_pitch = input_stride;
thr->width = width;
thr->height = y_end - y_start;
// Workers need to know if they can access pixels outside their given buffer.
/* Workers need to know if they can access pixels
* outside their given buffer.
*/
thr->first = y_start;
thr->last = y_end == height;
if (filt->in_fmt == SOFTFILTER_FMT_RGB565)
packets[i].work = twoxsai_work_cb_rgb565;
//else if (filt->in_fmt == SOFTFILTER_FMT_RGB4444)
//packets[i].work = twoxsai_work_cb_rgb4444;
#if 0
else if (filt->in_fmt == SOFTFILTER_FMT_RGB4444)
packets[i].work = twoxsai_work_cb_rgb4444;
#endif
else if (filt->in_fmt == SOFTFILTER_FMT_XRGB8888)
packets[i].work = twoxsai_work_cb_xrgb8888;
packets[i].thread_data = thr;
@ -354,7 +372,8 @@ static const struct softfilter_implementation twoxsai_generic = {
"2xsai",
};
const struct softfilter_implementation *softfilter_get_implementation(softfilter_simd_mask_t simd)
const struct softfilter_implementation *softfilter_get_implementation(
softfilter_simd_mask_t simd)
{
(void)simd;
return &twoxsai_generic;

View File

@ -126,7 +126,8 @@ static void *blargg_ntsc_snes_generic_create(const struct softfilter_config *con
struct filter_data *filt = (struct filter_data*)calloc(1, sizeof(*filt));
if (!filt)
return NULL;
filt->workers = (struct softfilter_thread_data*)calloc(threads, sizeof(struct softfilter_thread_data));
filt->workers = (struct softfilter_thread_data*)
calloc(threads, sizeof(struct softfilter_thread_data));
filt->threads = threads;
filt->in_fmt = in_fmt;
if (!filt->workers)
@ -141,7 +142,8 @@ static void *blargg_ntsc_snes_generic_create(const struct softfilter_config *con
}
static void blargg_ntsc_snes_generic_output(void *data, unsigned *out_width, unsigned *out_height,
static void blargg_ntsc_snes_generic_output(void *data,
unsigned *out_width, unsigned *out_height,
unsigned width, unsigned height)
{
*out_width = SNES_NTSC_OUT_WIDTH(width);
@ -165,9 +167,11 @@ static void blargg_ntsc_snes_render_rgb565(void *data, int width, int height,
{
struct filter_data *filt = (struct filter_data*)data;
if(width <= 256)
snes_ntsc_blit(filt->ntsc, input, pitch, filt->burst, width, height, output, outpitch * 2, first, last);
snes_ntsc_blit(filt->ntsc, input, pitch, filt->burst,
width, height, output, outpitch * 2, first, last);
else
snes_ntsc_blit_hires(filt->ntsc, input, pitch, filt->burst, width, height, output, outpitch * 2, first, last);
snes_ntsc_blit_hires(filt->ntsc, input, pitch, filt->burst,
width, height, output, outpitch * 2, first, last);
filt->burst ^= filt->burst_toggle;
}
@ -185,14 +189,18 @@ static void blargg_ntsc_snes_rgb565(void *data, unsigned width, unsigned height,
static void blargg_ntsc_snes_work_cb_rgb565(void *data, void *thread_data)
{
struct softfilter_thread_data *thr = (struct softfilter_thread_data*)thread_data;
struct softfilter_thread_data *thr =
(struct softfilter_thread_data*)thread_data;
uint16_t *input = (uint16_t*)thr->in_data;
uint16_t *output = (uint16_t*)thr->out_data;
unsigned width = thr->width;
unsigned height = thr->height;
blargg_ntsc_snes_rgb565(data, width, height,
thr->first, thr->last, input, thr->in_pitch / SOFTFILTER_BPP_RGB565, output, thr->out_pitch / SOFTFILTER_BPP_RGB565);
thr->first, thr->last, input,
thr->in_pitch / SOFTFILTER_BPP_RGB565,
output,
thr->out_pitch / SOFTFILTER_BPP_RGB565);
}
static void blargg_ntsc_snes_generic_packets(void *data,
@ -204,7 +212,8 @@ static void blargg_ntsc_snes_generic_packets(void *data,
unsigned i;
for (i = 0; i < filt->threads; i++)
{
struct softfilter_thread_data *thr = (struct softfilter_thread_data*)&filt->workers[i];
struct softfilter_thread_data *thr =
(struct softfilter_thread_data*)&filt->workers[i];
unsigned y_start = (height * i) / filt->threads;
unsigned y_end = (height * (i + 1)) / filt->threads;
@ -215,7 +224,8 @@ static void blargg_ntsc_snes_generic_packets(void *data,
thr->width = width;
thr->height = y_end - y_start;
// Workers need to know if they can access pixels outside their given buffer.
/* Workers need to know if they can
* access pixels outside their given buffer. */
thr->first = y_start;
thr->last = y_end == height;
@ -240,7 +250,8 @@ static const struct softfilter_implementation blargg_ntsc_snes_generic = {
"blargg_ntsc_snes",
};
const struct softfilter_implementation *softfilter_get_implementation(softfilter_simd_mask_t simd)
const struct softfilter_implementation *softfilter_get_implementation(
softfilter_simd_mask_t simd)
{
(void)simd;
return &blargg_ntsc_snes_generic;

View File

@ -14,9 +14,7 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
// Compile: gcc -o darken.so -shared darken.c -std=c99 -O3 -Wall -pedantic -fPIC
// Useless filter, just nice as a reference for other filters.
/* Useless filter, just nice as a reference for other filters. */
#include "softfilter.h"
#include <stdlib.h>
@ -75,7 +73,8 @@ static void *darken_create(const struct softfilter_config *config,
struct filter_data *filt = (struct filter_data*)calloc(1, sizeof(*filt));
if (!filt)
return NULL;
filt->workers = (struct softfilter_thread_data*)calloc(threads, sizeof(struct softfilter_thread_data));
filt->workers = (struct softfilter_thread_data*)
calloc(threads, sizeof(struct softfilter_thread_data));
filt->threads = threads;
filt->in_fmt = in_fmt;
if (!filt->workers)
@ -102,28 +101,32 @@ static void darken_destroy(void *data)
static void darken_work_cb_xrgb8888(void *data, void *thread_data)
{
struct softfilter_thread_data *thr = (struct softfilter_thread_data*)thread_data;
struct softfilter_thread_data *thr =
(struct softfilter_thread_data*)thread_data;
const uint32_t *input = (const uint32_t*)thr->in_data;
uint32_t *output = (uint32_t*)thr->out_data;
unsigned width = thr->width;
unsigned height = thr->height;
unsigned x, y;
for (y = 0; y < height; y++, input += thr->in_pitch >> 2, output += thr->out_pitch >> 2)
for (y = 0; y < height;
y++, input += thr->in_pitch >> 2, output += thr->out_pitch >> 2)
for (x = 0; x < width; x++)
output[x] = (input[x] >> 2) & (0x3f * 0x01010101);
}
static void darken_work_cb_rgb565(void *data, void *thread_data)
{
struct softfilter_thread_data *thr = (struct softfilter_thread_data*)thread_data;
struct softfilter_thread_data *thr =
(struct softfilter_thread_data*)thread_data;
const uint16_t *input = (const uint16_t*)thr->in_data;
uint16_t *output = (uint16_t*)thr->out_data;
unsigned width = thr->width;
unsigned height = thr->height;
unsigned x, y;
for (y = 0; y < height; y++, input += thr->in_pitch >> 1, output += thr->out_pitch >> 1)
for (y = 0; y < height;
y++, input += thr->in_pitch >> 1, output += thr->out_pitch >> 1)
for (x = 0; x < width; x++)
output[x] = (input[x] >> 2) & ((0x7 << 0) | (0xf << 5) | (0x7 << 11));
}
@ -137,7 +140,8 @@ static void darken_packets(void *data,
struct filter_data *filt = (struct filter_data*)data;
for (i = 0; i < filt->threads; i++)
{
struct softfilter_thread_data *thr = (struct softfilter_thread_data*)&filt->workers[i];
struct softfilter_thread_data *thr =
(struct softfilter_thread_data*)&filt->workers[i];
unsigned y_start = (height * i) / filt->threads;
unsigned y_end = (height * (i + 1)) / filt->threads;
thr->out_data = (uint8_t*)output + y_start * output_stride;
@ -170,7 +174,8 @@ static const struct softfilter_implementation darken = {
"darken",
};
const struct softfilter_implementation *softfilter_get_implementation(softfilter_simd_mask_t simd)
const struct softfilter_implementation *softfilter_get_implementation(
softfilter_simd_mask_t simd)
{
(void)simd;
return &darken;

View File

@ -14,8 +14,6 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
// Compile: gcc -o epx.so -shared epx.c -std=c99 -O3 -Wall -pedantic -fPIC
#include "softfilter.h"
#include <stdlib.h>
@ -75,7 +73,8 @@ static void *epx_generic_create(const struct softfilter_config *config,
struct filter_data *filt = (struct filter_data*)calloc(1, sizeof(*filt));
if (!filt)
return NULL;
filt->workers = (struct softfilter_thread_data*)calloc(threads, sizeof(struct softfilter_thread_data));
filt->workers = (struct softfilter_thread_data*)
calloc(threads, sizeof(struct softfilter_thread_data));
filt->threads = threads;
filt->in_fmt = in_fmt;
if (!filt->workers)
@ -86,7 +85,8 @@ static void *epx_generic_create(const struct softfilter_config *config,
return filt;
}
static void epx_generic_output(void *data, unsigned *out_width, unsigned *out_height,
static void epx_generic_output(void *data,
unsigned *out_width, unsigned *out_height,
unsigned width, unsigned height)
{
*out_width = width * EPX_SCALE;
@ -113,11 +113,12 @@ static void EPX_16 (int width, int height,
height -= 2;
// D
// A X C
// B
/* D
* A X C
* B
*/
// top edge
/* top edge */
sP = (uint16_t *)(src - prevline);
lP = (uint16_t *) (src + src_stride);
@ -159,10 +160,12 @@ static void EPX_16 (int width, int height,
{
#ifdef MSB_FIRST
*dP1 = (colorX << 16) + colorX;
*dP2 = (((colorA == colorB) ? colorA : colorX) << 16) + ((colorB == colorC) ? colorB : colorX);
*dP2 = (((colorA == colorB) ? colorA : colorX) << 16) +
((colorB == colorC) ? colorB : colorX);
#else
*dP1 = colorX + (colorX << 16);
*dP2 = ((colorA == colorB) ? colorA : colorX) + (((colorB == colorC) ? colorB : colorX) << 16);
*dP2 = ((colorA == colorB) ? colorA : colorX) +
(((colorB == colorC) ? colorB : colorX) << 16);
#endif
}
else
@ -172,7 +175,7 @@ static void EPX_16 (int width, int height,
dP2++;
}
// right edge
/* right edge */
colorA = colorX;
colorX = colorC;
@ -194,8 +197,6 @@ static void EPX_16 (int width, int height,
src += src_stride;
dst += dst_stride << 1;
//
for (; height; height--)
{
sP = (uint16_t *) src;
@ -204,7 +205,7 @@ static void EPX_16 (int width, int height,
dP1 = (uint32_t *) dst;
dP2 = (uint32_t *) (dst + dst_stride);
// left edge
/* left edge */
colorX = *sP;
colorC = *++sP;
@ -227,8 +228,6 @@ static void EPX_16 (int width, int height,
dP1++;
dP2++;
//
for (w = width - 2; w; w--)
{
colorA = colorX;
@ -240,11 +239,15 @@ static void EPX_16 (int width, int height,
if ((colorA != colorC) && (colorB != colorD))
{
#ifdef MSB_FIRST
*dP1 = (((colorD == colorA) ? colorD : colorX) << 16) + ((colorC == colorD) ? colorC : colorX);
*dP2 = (((colorA == colorB) ? colorA : colorX) << 16) + ((colorB == colorC) ? colorB : colorX);
*dP1 = (((colorD == colorA) ? colorD : colorX) << 16) +
((colorC == colorD) ? colorC : colorX);
*dP2 = (((colorA == colorB) ? colorA : colorX) << 16) +
((colorB == colorC) ? colorB : colorX);
#else
*dP1 = ((colorD == colorA) ? colorD : colorX) + (((colorC == colorD) ? colorC : colorX) << 16);
*dP2 = ((colorA == colorB) ? colorA : colorX) + (((colorB == colorC) ? colorB : colorX) << 16);
*dP1 = ((colorD == colorA) ? colorD : colorX) +
(((colorC == colorD) ? colorC : colorX) << 16);
*dP2 = ((colorA == colorB) ? colorA : colorX) +
(((colorB == colorC) ? colorB : colorX) << 16);
#endif
}
else
@ -254,7 +257,7 @@ static void EPX_16 (int width, int height,
dP2++;
}
// right edge
/* right edge */
colorA = colorX;
colorX = colorC;
@ -278,14 +281,14 @@ static void EPX_16 (int width, int height,
dst += dst_stride << 1;
}
// bottom edge
/* bottom edge */
sP = (uint16_t *) src;
uP = (uint16_t *) (src - src_stride);
dP1 = (uint32_t *) dst;
dP2 = (uint32_t *) (dst + dst_stride);
// left edge
/* left edge */
colorX = *sP;
colorC = *++sP;
@ -307,8 +310,6 @@ static void EPX_16 (int width, int height,
dP1++;
dP2++;
//
for (w = width - 2; w; w--)
{
colorA = colorX;
@ -319,10 +320,12 @@ static void EPX_16 (int width, int height,
if ((colorA != colorC) && (colorX != colorD))
{
#ifdef MSB_FIRST
*dP1 = (((colorD == colorA) ? colorD : colorX) << 16) + ((colorC == colorD) ? colorC : colorX);
*dP1 = (((colorD == colorA) ? colorD : colorX) << 16) +
((colorC == colorD) ? colorC : colorX);
*dP2 = (colorX << 16) + colorX;
#else
*dP1 = ((colorD == colorA) ? colorD : colorX) + (((colorC == colorD) ? colorC : colorX) << 16);
*dP1 = ((colorD == colorA) ? colorD : colorX) +
(((colorC == colorD) ? colorC : colorX) << 16);
*dP2 = colorX + (colorX << 16);
#endif
}
@ -333,7 +336,7 @@ static void EPX_16 (int width, int height,
dP2++;
}
// right edge
/* right edge */
colorA = colorX;
colorX = colorC;
@ -366,14 +369,18 @@ static void epx_generic_rgb565(unsigned width, unsigned height,
static void epx_work_cb_rgb565(void *data, void *thread_data)
{
struct softfilter_thread_data *thr = (struct softfilter_thread_data*)thread_data;
struct softfilter_thread_data *thr =
(struct softfilter_thread_data*)thread_data;
uint16_t *input = (uint16_t*)thr->in_data;
uint16_t *output = (uint16_t*)thr->out_data;
unsigned width = thr->width;
unsigned height = thr->height;
epx_generic_rgb565(width, height,
thr->first, thr->last, input, thr->in_pitch / SOFTFILTER_BPP_RGB565, output, thr->out_pitch / SOFTFILTER_BPP_RGB565);
thr->first, thr->last, input,
thr->in_pitch / SOFTFILTER_BPP_RGB565,
output,
thr->out_pitch / SOFTFILTER_BPP_RGB565);
}
@ -386,7 +393,8 @@ static void epx_generic_packets(void *data,
unsigned i;
for (i = 0; i < filt->threads; i++)
{
struct softfilter_thread_data *thr = (struct softfilter_thread_data*)&filt->workers[i];
struct softfilter_thread_data *thr =
(struct softfilter_thread_data*)&filt->workers[i];
unsigned y_start = (height * i) / filt->threads;
unsigned y_end = (height * (i + 1)) / filt->threads;
@ -397,7 +405,8 @@ static void epx_generic_packets(void *data,
thr->width = width;
thr->height = y_end - y_start;
// Workers need to know if they can access pixels outside their given buffer.
/* Workers need to know if they can
* access pixels outside their given buffer. */
thr->first = y_start;
thr->last = y_end == height;
@ -422,7 +431,8 @@ static const struct softfilter_implementation epx_generic = {
"epx",
};
const struct softfilter_implementation *softfilter_get_implementation(softfilter_simd_mask_t simd)
const struct softfilter_implementation *softfilter_get_implementation(
softfilter_simd_mask_t simd)
{
(void)simd;
return &epx_generic;

View File

@ -14,8 +14,6 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
// Compile: gcc -o lq2x.so -shared lq2x.c -std=c99 -O3 -Wall -pedantic -fPIC
#include "softfilter.h"
#include <stdlib.h>
@ -75,7 +73,8 @@ static void *lq2x_generic_create(const struct softfilter_config *config,
struct filter_data *filt = (struct filter_data*)calloc(1, sizeof(*filt));
if (!filt)
return NULL;
filt->workers = (struct softfilter_thread_data*)calloc(threads, sizeof(struct softfilter_thread_data));
filt->workers = (struct softfilter_thread_data*)
calloc(threads, sizeof(struct softfilter_thread_data));
filt->threads = threads;
filt->in_fmt = in_fmt;
if (!filt->workers)
@ -86,7 +85,8 @@ static void *lq2x_generic_create(const struct softfilter_config *config,
return filt;
}
static void lq2x_generic_output(void *data, unsigned *out_width, unsigned *out_height,
static void lq2x_generic_output(void *data,
unsigned *out_width, unsigned *out_height,
unsigned width, unsigned height)
{
*out_width = width * LQ2X_SCALE;
@ -194,19 +194,24 @@ static void lq2x_generic_xrgb8888(unsigned width, unsigned height,
static void lq2x_work_cb_rgb565(void *data, void *thread_data)
{
struct softfilter_thread_data *thr = (struct softfilter_thread_data*)thread_data;
struct softfilter_thread_data *thr =
(struct softfilter_thread_data*)thread_data;
uint16_t *input = (uint16_t*)thr->in_data;
uint16_t *output = (uint16_t*)thr->out_data;
unsigned width = thr->width;
unsigned height = thr->height;
lq2x_generic_rgb565(width, height,
thr->first, thr->last, input, thr->in_pitch / SOFTFILTER_BPP_RGB565, output, thr->out_pitch / SOFTFILTER_BPP_RGB565);
thr->first, thr->last, input,
thr->in_pitch / SOFTFILTER_BPP_RGB565,
output,
thr->out_pitch / SOFTFILTER_BPP_RGB565);
}
static void lq2x_work_cb_xrgb8888(void *data, void *thread_data)
{
struct softfilter_thread_data *thr = (struct softfilter_thread_data*)thread_data;
struct softfilter_thread_data *thr =
(struct softfilter_thread_data*)thread_data;
uint32_t *input = (uint32_t*)thr->in_data;
uint32_t *output = (uint32_t*)thr->out_data;
unsigned width = thr->width;
@ -215,19 +220,24 @@ static void lq2x_work_cb_xrgb8888(void *data, void *thread_data)
(void)data;
lq2x_generic_xrgb8888(width, height,
thr->first, thr->last, input, thr->in_pitch / SOFTFILTER_BPP_XRGB8888, output, thr->out_pitch / SOFTFILTER_BPP_XRGB8888);
thr->first, thr->last, input,
thr->in_pitch / SOFTFILTER_BPP_XRGB8888,
output,
thr->out_pitch / SOFTFILTER_BPP_XRGB8888);
}
static void lq2x_generic_packets(void *data,
struct softfilter_work_packet *packets,
void *output, size_t output_stride,
const void *input, unsigned width, unsigned height, size_t input_stride)
const void *input, unsigned width,
unsigned height, size_t input_stride)
{
struct filter_data *filt = (struct filter_data*)data;
unsigned i;
for (i = 0; i < filt->threads; i++)
{
struct softfilter_thread_data *thr = (struct softfilter_thread_data*)&filt->workers[i];
struct softfilter_thread_data *thr =
(struct softfilter_thread_data*)&filt->workers[i];
unsigned y_start = (height * i) / filt->threads;
unsigned y_end = (height * (i + 1)) / filt->threads;
@ -238,14 +248,17 @@ static void lq2x_generic_packets(void *data,
thr->width = width;
thr->height = y_end - y_start;
// Workers need to know if they can access pixels outside their given buffer.
/* Workers need to know if they can access pixels
* outside their given buffer. */
thr->first = y_start;
thr->last = y_end == height;
if (filt->in_fmt == SOFTFILTER_FMT_RGB565)
packets[i].work = lq2x_work_cb_rgb565;
//else if (filt->in_fmt == SOFTFILTER_FMT_RGB4444)
//packets[i].work = lq2x_work_cb_rgb4444;
#if 0
else if (filt->in_fmt == SOFTFILTER_FMT_RGB4444)
packets[i].work = lq2x_work_cb_rgb4444;
#endif
else if (filt->in_fmt == SOFTFILTER_FMT_XRGB8888)
packets[i].work = lq2x_work_cb_xrgb8888;
packets[i].thread_data = thr;
@ -267,7 +280,8 @@ static const struct softfilter_implementation lq2x_generic = {
"lq2x",
};
const struct softfilter_implementation *softfilter_get_implementation(softfilter_simd_mask_t simd)
const struct softfilter_implementation *softfilter_get_implementation(
softfilter_simd_mask_t simd)
{
(void)simd;
return &lq2x_generic;

View File

@ -14,8 +14,6 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
// Compile: gcc -o phosphor2x.so -shared phosphor2x.c -std=c99 -O3 -Wall -pedantic -fPIC
#include "softfilter.h"
#include "boolean.h"
#include <stdlib.h>
@ -106,96 +104,111 @@ static inline unsigned max_component_rgb565(uint32_t color)
return max;
}
static void blit_linear_line_xrgb8888(uint32_t * out, const uint32_t *in, unsigned width)
static void blit_linear_line_xrgb8888(uint32_t * out,
const uint32_t *in, unsigned width)
{
unsigned i;
// Splat pixels out on the line.
/* Splat pixels out on the line. */
for (i = 0; i < width; i++)
out[i << 1] = in[i];
// Blend in-between pixels.
/* Blend in-between pixels. */
for (i = 1; i < (width << 1) - 1; i += 2)
out[i] = blend_pixels_xrgb8888(out[i - 1], out[i + 1]);
// Blend edge pixels against black.
/* Blend edge pixels against black. */
out[0] = blend_pixels_xrgb8888(out[0], 0);
out[(width << 1) - 1] = blend_pixels_xrgb8888(out[(width << 1) - 1], 0);
out[(width << 1) - 1] =
blend_pixels_xrgb8888(out[(width << 1) - 1], 0);
}
static void blit_linear_line_rgb565(uint16_t * out, const uint16_t *in, unsigned width)
static void blit_linear_line_rgb565(uint16_t * out,
const uint16_t *in, unsigned width)
{
unsigned i;
// Splat pixels out on the line.
/* Splat pixels out on the line. */
for (i = 0; i < width; i++)
out[i << 1] = in[i];
// Blend in-between pixels.
/* Blend in-between pixels. */
for (i = 1; i < (width << 1) - 1; i += 2)
out[i] = blend_pixels_rgb565(out[i - 1], out[i + 1]);
out[i] =
blend_pixels_rgb565(out[i - 1], out[i + 1]);
// Blend edge pixels against black.
/* Blend edge pixels against black. */
out[0] = blend_pixels_rgb565(out[0], 0);
out[(width << 1) - 1] = blend_pixels_rgb565(out[(width << 1) - 1], 0);
out[(width << 1) - 1] =
blend_pixels_rgb565(out[(width << 1) - 1], 0);
}
static void bleed_phosphors_xrgb8888(void *data, uint32_t *scanline, unsigned width)
static void bleed_phosphors_xrgb8888(void *data,
uint32_t *scanline, unsigned width)
{
unsigned x;
struct filter_data *filt = (struct filter_data*)data;
// Red phosphor
/* Red phosphor */
for (x = 0; x < width; x += 2)
{
unsigned r = red_xrgb8888(scanline[x]);
unsigned r_set = clamp8(r * filt->phosphor_bleed * filt->phosphor_bloom_8888[r]);
unsigned r_set = clamp8(r * filt->phosphor_bleed *
filt->phosphor_bloom_8888[r]);
set_red_xrgb8888(scanline[x + 1], r_set);
}
// Green phosphor
/* Green phosphor */
for (x = 0; x < width; x++)
{
unsigned g = green_xrgb8888(scanline[x]);
unsigned g_set = clamp8((g >> 1) + 0.5 * g * filt->phosphor_bleed * filt->phosphor_bloom_8888[g]);
unsigned g_set = clamp8((g >> 1) + 0.5 * g *
filt->phosphor_bleed * filt->phosphor_bloom_8888[g]);
set_green_xrgb8888(scanline[x], g_set);
}
// Blue phosphor
/* Blue phosphor */
set_blue_xrgb8888(scanline[0], 0);
for (x = 1; x < width; x += 2)
{
unsigned b = blue_xrgb8888(scanline[x]);
unsigned b_set = clamp8(b * filt->phosphor_bleed * filt->phosphor_bloom_8888[b]);
unsigned b_set = clamp8(b * filt->phosphor_bleed *
filt->phosphor_bloom_8888[b]);
set_blue_xrgb8888(scanline[x + 1], b_set);
}
}
static void bleed_phosphors_rgb565(void *data, uint16_t *scanline, unsigned width)
static void bleed_phosphors_rgb565(void *data,
uint16_t *scanline, unsigned width)
{
unsigned x;
struct filter_data *filt = (struct filter_data*)data;
// Red phosphor
/* Red phosphor */
for (x = 0; x < width; x += 2)
{
unsigned r = red_rgb565(scanline[x]);
unsigned r_set = clamp6(r * filt->phosphor_bleed * filt->phosphor_bloom_565[r]);
unsigned r_set = clamp6(r * filt->phosphor_bleed *
filt->phosphor_bloom_565[r]);
set_red_rgb565(scanline[x + 1], r_set);
}
// Green phosphor
/* Green phosphor */
for (x = 0; x < width; x++)
{
unsigned g = green_rgb565(scanline[x]);
unsigned g_set = clamp6((g >> 1) + 0.5 * g * filt->phosphor_bleed * filt->phosphor_bloom_565[g]);
unsigned g_set = clamp6((g >> 1) + 0.5 * g *
filt->phosphor_bleed * filt->phosphor_bloom_565[g]);
set_green_rgb565(scanline[x], g_set);
}
// Blue phosphor
/* Blue phosphor */
set_blue_rgb565(scanline[0], 0);
for (x = 1; x < width; x += 2)
{
unsigned b = blue_rgb565(scanline[x]);
unsigned b_set = clamp6(b * filt->phosphor_bleed * filt->phosphor_bloom_565[b]);
unsigned b_set = clamp6(b * filt->phosphor_bleed *
filt->phosphor_bloom_565[b]);
set_blue_rgb565(scanline[x + 1], b_set);
}
}
@ -233,7 +246,8 @@ static void *phosphor2x_generic_create(const struct softfilter_config *config,
if (!filt)
return NULL;
filt->workers = (struct softfilter_thread_data*)calloc(threads, sizeof(struct softfilter_thread_data));
filt->workers = (struct softfilter_thread_data*)
calloc(threads, sizeof(struct softfilter_thread_data));
filt->threads = threads;
filt->in_fmt = in_fmt;
if (!filt->workers)
@ -248,24 +262,36 @@ static void *phosphor2x_generic_create(const struct softfilter_config *config,
filt->scanrange_low = 0.5;
filt->scanrange_high = 0.65;
// Init lookup tables:
// phosphorBloom = (scaleTimes .* linspace(0, 1, 255) .^ (1/2.2)) + scaleAdd;
// Not exactly sure of order of operations here ...
#if 0
/* Initialize lookup tables: */
phosphorBloom = (scaleTimes .*
linspace(0, 1, 255) .^ (1/2.2)) + scaleAdd;
/* Not exactly sure of order of operations here ... */
#endif
for (i = 0; i < 256; i++)
{
filt->phosphor_bloom_8888[i] = filt->scale_times * powf((float)i / 255.0f, 1.0f/2.2f) + filt->scale_add;
filt->scan_range_8888[i] = filt->scanrange_low + i * (filt->scanrange_high - filt->scanrange_low) / 255.0f;
filt->phosphor_bloom_8888[i] =
filt->scale_times * powf((float)i / 255.0f, 1.0f/2.2f) +
filt->scale_add;
filt->scan_range_8888[i] =
filt->scanrange_low + i *
(filt->scanrange_high - filt->scanrange_low) / 255.0f;
}
for (i = 0; i < 64; i++)
{
filt->phosphor_bloom_565[i] = filt->scale_times * powf((float)i / 31.0f, 1.0f/2.2f) + filt->scale_add;
filt->scan_range_565[i] = filt->scanrange_low + i * (filt->scanrange_high - filt->scanrange_low) / 31.0f;
filt->phosphor_bloom_565[i] =
filt->scale_times * powf((float)i / 31.0f, 1.0f/2.2f)
+ filt->scale_add;
filt->scan_range_565[i] =
filt->scanrange_low + i *
(filt->scanrange_high - filt->scanrange_low) / 31.0f;
}
return filt;
}
static void phosphor2x_generic_output(void *data, unsigned *out_width, unsigned *out_height,
static void phosphor2x_generic_output(void *data,
unsigned *out_width, unsigned *out_height,
unsigned width, unsigned height)
{
(void)data;
@ -280,7 +306,8 @@ static void phosphor2x_generic_destroy(void *data)
free(filt);
}
static void phosphor2x_generic_xrgb8888(void *data, unsigned width, unsigned height,
static void phosphor2x_generic_xrgb8888(void *data,
unsigned width, unsigned height,
int first, int last, uint32_t *src,
unsigned src_stride, uint32_t *dst, unsigned dst_stride)
{
@ -296,28 +323,39 @@ static void phosphor2x_generic_xrgb8888(void *data, unsigned width, unsigned hei
{
uint32_t *out_line, *scan_out;
unsigned x;
const uint32_t *in_line = (const uint32_t*)(src + y * (src_stride)); // Input
const uint32_t *in_line = (const uint32_t*)(src + y * (src_stride));
out_line = (uint32_t*)(dst + y * (dst_stride) * 2); // Output in a scanlines fashion.
/* output in a scanlines fashion. */
out_line = (uint32_t*)(dst + y * (dst_stride) * 2);
blit_linear_line_xrgb8888(out_line, in_line, width); // Bilinear stretch horizontally.
bleed_phosphors_xrgb8888(filt, out_line, width << 1); // Mask 'n bleed phosphors.
/* Bilinear stretch horizontally. */
blit_linear_line_xrgb8888(out_line, in_line, width);
// Apply scanlines
/* Mask 'n bleed phosphors */
bleed_phosphors_xrgb8888(filt, out_line, width << 1);
/* Apply scanlines */
scan_out = (uint32_t*)out_line + (dst_stride);
for (x = 0; x < (width << 1); x++)
{
unsigned max = max_component_xrgb8888(out_line[x]);
set_red_xrgb8888(scan_out[x], (uint32_t)(filt->scan_range_8888[max] * red_xrgb8888(out_line[x])));
set_green_xrgb8888(scan_out[x], (uint32_t)(filt->scan_range_8888[max] * green_xrgb8888(out_line[x])));
set_blue_xrgb8888(scan_out[x], (uint32_t)(filt->scan_range_8888[max] * blue_xrgb8888(out_line[x])));
set_red_xrgb8888(scan_out[x],
(uint32_t)(filt->scan_range_8888[max] *
red_xrgb8888(out_line[x])));
set_green_xrgb8888(scan_out[x],
(uint32_t)(filt->scan_range_8888[max] *
green_xrgb8888(out_line[x])));
set_blue_xrgb8888(scan_out[x],
(uint32_t)(filt->scan_range_8888[max] *
blue_xrgb8888(out_line[x])));
}
}
}
static void phosphor2x_generic_rgb565(void *data, unsigned width, unsigned height,
static void phosphor2x_generic_rgb565(void *data,
unsigned width, unsigned height,
int first, int last, uint16_t *src,
unsigned src_stride, uint16_t *dst, unsigned dst_stride)
{
@ -333,48 +371,65 @@ static void phosphor2x_generic_rgb565(void *data, unsigned width, unsigned heigh
{
uint16_t *scan_out;
unsigned x;
uint16_t *out_line = (uint16_t*)(dst + y * (dst_stride) * 2); // Output in a scanlines fashion.
const uint16_t *in_line = (const uint16_t*)(src + y * (src_stride)); // Input
/* Output in a scanlines fashion. */
uint16_t *out_line = (uint16_t*)(dst + y * (dst_stride) * 2);
const uint16_t *in_line = (const uint16_t*)(src + y * (src_stride));
blit_linear_line_rgb565(out_line, in_line, width); // Bilinear stretch horizontally.
bleed_phosphors_rgb565(filt, out_line, width << 1); // Mask 'n bleed phosphors.
/* Bilinear stretch horizontally. */
blit_linear_line_rgb565(out_line, in_line, width);
// Apply scanlines.
/* Mask 'n bleed phosphors. */
bleed_phosphors_rgb565(filt, out_line, width << 1);
/* Apply scanlines. */
scan_out = (uint16_t*)(out_line + (dst_stride));
for (x = 0; x < (width << 1); x++)
{
unsigned max = max_component_rgb565(out_line[x]);
set_red_rgb565(scan_out[x], (uint16_t)(filt->scan_range_565[max] * red_rgb565(out_line[x])));
set_green_rgb565(scan_out[x], (uint16_t)(filt->scan_range_565[max] * green_rgb565(out_line[x])));
set_blue_rgb565(scan_out[x], (uint16_t)(filt->scan_range_565[max] * blue_rgb565(out_line[x])));
set_red_rgb565(scan_out[x],
(uint16_t)(filt->scan_range_565[max] *
red_rgb565(out_line[x])));
set_green_rgb565(scan_out[x],
(uint16_t)(filt->scan_range_565[max] *
green_rgb565(out_line[x])));
set_blue_rgb565(scan_out[x],
(uint16_t)(filt->scan_range_565[max] *
blue_rgb565(out_line[x])));
}
}
}
static void phosphor2x_work_cb_xrgb8888(void *data, void *thread_data)
{
struct softfilter_thread_data *thr = (struct softfilter_thread_data*)thread_data;
struct softfilter_thread_data *thr =
(struct softfilter_thread_data*)thread_data;
uint32_t *input = (uint32_t*)thr->in_data;
uint32_t *output = (uint32_t*)thr->out_data;
unsigned width = thr->width;
unsigned height = thr->height;
phosphor2x_generic_xrgb8888(data, width, height,
thr->first, thr->last, input, thr->in_pitch / SOFTFILTER_BPP_XRGB8888, output, thr->out_pitch / SOFTFILTER_BPP_XRGB8888);
thr->first, thr->last, input,
thr->in_pitch / SOFTFILTER_BPP_XRGB8888,
output,
thr->out_pitch / SOFTFILTER_BPP_XRGB8888);
}
static void phosphor2x_work_cb_rgb565(void *data, void *thread_data)
{
struct softfilter_thread_data *thr = (struct softfilter_thread_data*)thread_data;
struct softfilter_thread_data *thr =
(struct softfilter_thread_data*)thread_data;
uint16_t *input = (uint16_t*)thr->in_data;
uint16_t *output = (uint16_t*)thr->out_data;
unsigned width = thr->width;
unsigned height = thr->height;
phosphor2x_generic_rgb565(data, width, height,
thr->first, thr->last, input, thr->in_pitch / SOFTFILTER_BPP_RGB565, output, thr->out_pitch / SOFTFILTER_BPP_RGB565);
thr->first, thr->last, input,
thr->in_pitch / SOFTFILTER_BPP_RGB565,
output,
thr->out_pitch / SOFTFILTER_BPP_RGB565);
}
static void phosphor2x_generic_packets(void *data,
@ -386,7 +441,8 @@ static void phosphor2x_generic_packets(void *data,
unsigned i;
for (i = 0; i < filt->threads; i++)
{
struct softfilter_thread_data *thr = (struct softfilter_thread_data*)&filt->workers[i];
struct softfilter_thread_data *thr =
(struct softfilter_thread_data*)&filt->workers[i];
unsigned y_start = (height * i) / filt->threads;
unsigned y_end = (height * (i + 1)) / filt->threads;
@ -397,14 +453,17 @@ static void phosphor2x_generic_packets(void *data,
thr->width = width;
thr->height = y_end - y_start;
// Workers need to know if they can access pixels outside their given buffer.
/* Workers need to know if they can access pixels
* outside their given buffer. */
thr->first = y_start;
thr->last = y_end == height;
if (filt->in_fmt == SOFTFILTER_FMT_RGB565)
packets[i].work = phosphor2x_work_cb_rgb565;
//else if (filt->in_fmt == SOFTFILTER_FMT_RGB4444)
//packets[i].work = phosphor2x_work_cb_rgb4444;
#if 0
else if (filt->in_fmt == SOFTFILTER_FMT_RGB4444)
packets[i].work = phosphor2x_work_cb_rgb4444;
#endif
if (filt->in_fmt == SOFTFILTER_FMT_XRGB8888)
packets[i].work = phosphor2x_work_cb_xrgb8888;
packets[i].thread_data = thr;
@ -426,7 +485,8 @@ static const struct softfilter_implementation phosphor2x_generic = {
"phosphor2x",
};
const struct softfilter_implementation *softfilter_get_implementation(softfilter_simd_mask_t simd)
const struct softfilter_implementation *softfilter_get_implementation(
softfilter_simd_mask_t simd)
{
(void)simd;
return &phosphor2x_generic;

View File

@ -91,7 +91,8 @@ static void scale2x_generic_rgb565(unsigned width, unsigned height,
uint16_t *out0, *out1;
out0 = (uint16_t*)dst;
out1 = (uint16_t*)(dst + dst_stride);
SCALE2X_GENERIC(uint16_t, width, height, first, last, src, src_stride, dst, dst_stride, out0, out1);
SCALE2X_GENERIC(uint16_t, width, height, first, last,
src, src_stride, dst, dst_stride, out0, out1);
}
static void scale2x_generic_xrgb8888(unsigned width, unsigned height,
@ -103,7 +104,8 @@ static void scale2x_generic_xrgb8888(unsigned width, unsigned height,
uint32_t *out0, *out1;
out0 = (uint32_t*)dst;
out1 = (uint32_t*)(dst + dst_stride);
SCALE2X_GENERIC(uint32_t, width, height, first, last, src, src_stride, dst, dst_stride, out0, out1);
SCALE2X_GENERIC(uint32_t, width, height, first, last,
src, src_stride, dst, dst_stride, out0, out1);
}
static unsigned scale2x_generic_input_fmts(void)
@ -134,7 +136,8 @@ static void *scale2x_generic_create(const struct softfilter_config *config,
struct filter_data *filt = (struct filter_data*)calloc(1, sizeof(*filt));
if (!filt)
return NULL;
filt->workers = (struct softfilter_thread_data*)calloc(threads, sizeof(struct softfilter_thread_data));
filt->workers = (struct softfilter_thread_data*)
calloc(threads, sizeof(struct softfilter_thread_data));
filt->threads = threads;
filt->in_fmt = in_fmt;
if (!filt->workers)
@ -145,7 +148,8 @@ static void *scale2x_generic_create(const struct softfilter_config *config,
return filt;
}
static void scale2x_generic_output(void *data, unsigned *out_width, unsigned *out_height,
static void scale2x_generic_output(void *data,
unsigned *out_width, unsigned *out_height,
unsigned width, unsigned height)
{
*out_width = width * SCALE2X_SCALE;
@ -161,26 +165,34 @@ static void scale2x_generic_destroy(void *data)
static void scale2x_work_cb_xrgb8888(void *data, void *thread_data)
{
struct softfilter_thread_data *thr = (struct softfilter_thread_data*)thread_data;
struct softfilter_thread_data *thr =
(struct softfilter_thread_data*)thread_data;
const uint32_t *input = (const uint32_t*)thr->in_data;
uint32_t *output = (uint32_t*)thr->out_data;
unsigned width = thr->width;
unsigned height = thr->height;
scale2x_generic_xrgb8888(width, height,
thr->first, thr->last, input, thr->in_pitch / SOFTFILTER_BPP_XRGB8888, output, thr->out_pitch / SOFTFILTER_BPP_XRGB8888);
thr->first, thr->last, input,
thr->in_pitch / SOFTFILTER_BPP_XRGB8888,
output,
thr->out_pitch / SOFTFILTER_BPP_XRGB8888);
}
static void scale2x_work_cb_rgb565(void *data, void *thread_data)
{
struct softfilter_thread_data *thr = (struct softfilter_thread_data*)thread_data;
struct softfilter_thread_data *thr =
(struct softfilter_thread_data*)thread_data;
const uint16_t *input = (const uint16_t*)thr->in_data;
uint16_t *output = (uint16_t*)thr->out_data;
unsigned width = thr->width;
unsigned height = thr->height;
scale2x_generic_rgb565(width, height,
thr->first, thr->last, input, thr->in_pitch / SOFTFILTER_BPP_RGB565, output, thr->out_pitch / SOFTFILTER_BPP_RGB565);
thr->first, thr->last, input,
thr->in_pitch / SOFTFILTER_BPP_RGB565,
output,
thr->out_pitch / SOFTFILTER_BPP_RGB565);
}
static void scale2x_generic_packets(void *data,
@ -192,18 +204,21 @@ static void scale2x_generic_packets(void *data,
unsigned i;
for (i = 0; i < filt->threads; i++)
{
struct softfilter_thread_data *thr = (struct softfilter_thread_data*)&filt->workers[i];
struct softfilter_thread_data *thr =
(struct softfilter_thread_data*)&filt->workers[i];
unsigned y_start = (height * i) / filt->threads;
unsigned y_end = (height * (i + 1)) / filt->threads;
thr->out_data = (uint8_t*)output + y_start * SCALE2X_SCALE * output_stride;
thr->out_data = (uint8_t*)output + y_start *
SCALE2X_SCALE * output_stride;
thr->in_data = (const uint8_t*)input + y_start * input_stride;
thr->out_pitch = output_stride;
thr->in_pitch = input_stride;
thr->width = width;
thr->height = y_end - y_start;
// Workers need to know if they can access pixels outside their given buffer.
/* Workers need to know if they can access pixels
* outside their given buffer. */
thr->first = y_start;
thr->last = y_end == height;
@ -230,7 +245,8 @@ static const struct softfilter_implementation scale2x_generic = {
"scale2x",
};
const struct softfilter_implementation *softfilter_get_implementation(softfilter_simd_mask_t simd)
const struct softfilter_implementation *softfilter_get_implementation(
softfilter_simd_mask_t simd)
{
(void)simd;
return &scale2x_generic;

View File

@ -39,16 +39,22 @@ extern "C" {
#define SOFTFILTER_SIMD_VFPU (1 << 13)
#define SOFTFILTER_SIMD_PS (1 << 14)
// A bit-mask of all supported SIMD instruction sets.
// Allows an implementation to pick different softfilter_implementation structs.
/* A bit-mask of all supported SIMD instruction sets.
* Allows an implementation to pick different
* softfilter_implementation structs. */
typedef unsigned softfilter_simd_mask_t;
// Returns true if config key was found. Otherwise, returns false, and sets value to default value.
typedef int (*softfilter_config_get_float_t)(void *userdata, const char *key, float *value, float default_value);
typedef int (*softfilter_config_get_int_t)(void *userdata, const char *key, int *value, int default_value);
/* Returns true if config key was found. Otherwise, returns false,
* and sets value to default value. */
typedef int (*softfilter_config_get_float_t)(void *userdata,
const char *key, float *value, float default_value);
// Allocates an array with values. free() with softfilter_config_free_t.
typedef int (*softfilter_config_get_float_array_t)(void *userdata, const char *key,
typedef int (*softfilter_config_get_int_t)(void *userdata,
const char *key, int *value, int default_value);
/* Allocates an array with values. free() with softfilter_config_free_t. */
typedef int (*softfilter_config_get_float_array_t)(void *userdata,
const char *key,
float **values, unsigned *out_num_values,
const float *default_values, unsigned num_default_values);
@ -56,9 +62,11 @@ typedef int (*softfilter_config_get_int_array_t)(void *userdata, const char *key
int **values, unsigned *out_num_values,
const int *default_values, unsigned num_default_values);
typedef int (*softfilter_config_get_string_t)(void *userdata, const char *key, char **output, const char *default_output);
typedef int (*softfilter_config_get_string_t)(void *userdata,
const char *key, char **output, const char *default_output);
// Calls free() in host runtime. Sometimes needed on Windows. free() on NULL is fine.
/* Calls free() in host runtime.
* Sometimes needed on Windows. free() on NULL is fine. */
typedef void (*softfilter_config_free_t)(void *ptr);
struct softfilter_config
@ -70,36 +78,44 @@ struct softfilter_config
softfilter_config_get_int_array_t get_int_array;
softfilter_config_get_string_t get_string;
softfilter_config_free_t free; // Avoid problems where softfilter plug and host are linked against different C runtimes.
/* Avoid problems where softfilter plug and
* host are linked against different C runtimes. */
softfilter_config_free_t free;
};
// Dynamic library entrypoint.
typedef const struct softfilter_implementation *(*softfilter_get_implementation_t)(softfilter_simd_mask_t);
// The same SIMD mask argument is forwarded to create() callback as well to avoid having to keep lots of state around.
const struct softfilter_implementation *softfilter_get_implementation(softfilter_simd_mask_t simd);
/* Dynamic library entrypoint. */
typedef const struct softfilter_implementation
*(*softfilter_get_implementation_t)(softfilter_simd_mask_t);
/* The same SIMD mask argument is forwarded to create() callback
* as well to avoid having to keep lots of state around. */
const struct softfilter_implementation *softfilter_get_implementation(
softfilter_simd_mask_t simd);
#define SOFTFILTER_API_VERSION 2
// Required base color formats
/* Required base color formats */
#define SOFTFILTER_FMT_NONE 0
#define SOFTFILTER_FMT_RGB565 (1 << 0)
#define SOFTFILTER_FMT_XRGB8888 (1 << 1)
// Optional color formats
/* Optional color formats */
#define SOFTFILTER_FMT_RGB4444 (1 << 2)
#define SOFTFILTER_BPP_RGB565 2
#define SOFTFILTER_BPP_XRGB8888 4
// Softfilter implementation.
// Returns a bitmask of supported input formats.
/* Softfilter implementation.
* Returns a bitmask of supported input formats. */
typedef unsigned (*softfilter_query_input_formats_t)(void);
// Returns a bitmask of supported output formats for a given input format.
/* Returns a bitmask of supported output formats
* for a given input format. */
typedef unsigned (*softfilter_query_output_formats_t)(unsigned input_format);
// In softfilter_process_t, the softfilter implementation submits work units to a worker thread pool.
/* In softfilter_process_t, the softfilter implementation
* submits work units to a worker thread pool. */
typedef void (*softfilter_work_t)(void *data, void *thread_data);
struct softfilter_work_packet
{
@ -107,31 +123,41 @@ struct softfilter_work_packet
void *thread_data;
};
// Create a filter with given input and output formats as well as maximum possible input size.
// Input sizes can very per call to softfilter_process_t, but they will never be larger than the maximum.
typedef void *(*softfilter_create_t)(const struct softfilter_config *config, unsigned in_fmt, unsigned out_fmt,
/* Create a filter with given input and output formats as well as
* maximum possible input size.
*
* Input sizes can very per call to softfilter_process_t, but they
* will never be larger than the maximum. */
typedef void *(*softfilter_create_t)(const struct softfilter_config *config,
unsigned in_fmt, unsigned out_fmt,
unsigned max_width, unsigned max_height,
unsigned threads, softfilter_simd_mask_t simd, void *userdata);
typedef void (*softfilter_destroy_t)(void *data);
// Given an input size, query the output size of the filter.
// If width and height == max_width/max_height, no other combination of width/height must return a larger size in any dimension.
/* Given an input size, query the output size of the filter.
* If width and height == max_width/max_height, no other combination
* of width/height must return a larger size in any dimension. */
typedef void (*softfilter_query_output_size_t)(void *data,
unsigned *out_width, unsigned *out_height,
unsigned width, unsigned height);
// First step of processing a frame. The filter submits work by filling in the packets array.
// The number of elements in the array is as returned by query_num_threads.
// The processing itself happens in worker threads after this returns.
/* First step of processing a frame. The filter submits work by
* filling in the packets array.
*
* The number of elements in the array is as returned by query_num_threads.
* The processing itself happens in worker threads after this returns.
*/
typedef void (*softfilter_get_work_packets_t)(void *data,
struct softfilter_work_packet *packets,
void *output, size_t output_stride,
const void *input, unsigned width, unsigned height, size_t input_stride);
// Returns the number of worker threads the filter will use.
// This can differ from the value passed to create() instead the filter cannot be parallelized, etc. The number of threads must be less-or-equal compared to the value passed to create().
/* Returns the number of worker threads the filter will use.
* This can differ from the value passed to create() instead the filter
* cannot be parallelized, etc. The number of threads must be less-or-equal
* compared to the value passed to create(). */
typedef unsigned (*softfilter_query_num_threads_t)(void *data);
/////
struct softfilter_implementation
{
@ -145,9 +171,13 @@ struct softfilter_implementation
softfilter_query_output_size_t query_output_size;
softfilter_get_work_packets_t get_work_packets;
unsigned api_version; // Must be SOFTFILTER_API_VERSION
const char *ident; // Human readable identifier of implementation.
const char *short_ident; // Computer-friendly short version of ident. Lower case, no spaces and special characters, etc.
/* Must be SOFTFILTER_API_VERSION. */
unsigned api_version;
/* Human readable identifier of implementation. */
const char *ident;
/* Computer-friendly short version of ident.
* Lower case, no spaces and special characters, etc. */
const char *short_ident;
};
#ifdef __cplusplus