diff --git a/gfx/filters/2xsai.c b/gfx/filters/2xsai.c index dcc11353e0..a27ff18ef2 100644 --- a/gfx/filters/2xsai.c +++ b/gfx/filters/2xsai.c @@ -26,7 +26,7 @@ static unsigned twoxsai_generic_input_fmts(void) { - return SOFTFILTER_FMT_RGB565; + return SOFTFILTER_FMT_RGB565 | SOFTFILTER_FMT_XRGB8888; } static unsigned twoxsai_generic_output_fmts(unsigned input_fmts) @@ -74,11 +74,15 @@ static void twoxsai_generic_destroy(void *data) free(filt); } +#define twoxsai_interpolate_xrgb8888(A, B) ((((A) & 0xFEFEFEFE) >> 1) + (((B) & 0xFEFEFEFE) >> 1) + ((A) & (B) & 0x01010101)) + +#define twoxsai_interpolate2_xrgb8888(A, B, C, D) ((((A) & 0xFCFCFCFC) >> 2) + (((B) & 0xFCFCFCFC) >> 2) + (((C) & 0xFCFCFCFC) >> 2) + (((D) & 0xFCFCFCFC) >> 2) + (((((A) & 0x03030303) + ((B) & 0x03030303) + ((C) & 0x03030303) + ((D) & 0x03030303)) >> 2) & 0x03030303)) + #define twoxsai_interpolate_rgb565(A, B) ((((A) & 0xF7DE) >> 1) + (((B) & 0xF7DE) >> 1) + ((A) & (B) & 0x0821)); #define twoxsai_interpolate2_rgb565(A, B, C, D) ((((A) & 0xE79C) >> 2) + (((B) & 0xE79C) >> 2) + (((C) & 0xE79C) >> 2) + (((D) & 0xE79C) >> 2) + (((((A) & 0x1863) + ((B) & 0x1863) + ((C) & 0x1863) + ((D) & 0x1863)) >> 2) & 0x1863)) -#define twoxsai_result1_rgb565(A, B, C, D) (((A) != (C) || (A) != (D)) - ((B) != (C) || (B) != (D))); +#define twoxsai_result(A, B, C, D) (((A) != (C) || (A) != (D)) - ((B) != (C) || (B) != (D))); #define twoxsai_declare_variables(typename_t, in, nextline) \ typename_t product, product1, product2; \ @@ -99,6 +103,123 @@ static void twoxsai_generic_destroy(void *data) typename_t colorO = *(in + nextline + nextline + 1); \ //typename_t colorP = *(in + nextline + nextline + 2); +#ifndef twoxsai_function +#define twoxsai_function(result_cb, interpolate_cb, interpolate2_cb) \ + if (colorA == colorD && colorB != colorC) \ + { \ + if ((colorA == colorE && colorB == colorL) || (colorA == colorC && colorA == colorF && colorB != colorE && colorB == colorJ)) \ + product = colorA; \ + else \ + { \ + product = interpolate_cb(colorA, colorB); \ + } \ + if ((colorA == colorG && colorC == colorO) || (colorA == colorB && colorA == colorH && colorG != colorC && colorC == colorM)) \ + product1 = colorA; \ + else \ + { \ + product1 = interpolate_cb(colorA, colorC); \ + } \ + product2 = colorA; \ + } else if (colorB == colorC && colorA != colorD) \ + { \ + if ((colorB == colorF && colorA == colorH) || (colorB == colorE && colorB == colorD && colorA != colorF && colorA == colorI)) \ + product = colorB; \ + else \ + { \ + product = interpolate_cb(colorA, colorB); \ + } \ + if ((colorC == colorH && colorA == colorF) || (colorC == colorG && colorC == colorD && colorA != colorH && colorA == colorI)) \ + product1 = colorC; \ + else \ + { \ + product1 = interpolate_cb(colorA, colorC); \ + } \ + product2 = colorB; \ + } \ + else if (colorA == colorD && colorB == colorC) \ + { \ + if (colorA == colorB) \ + { \ + product = colorA; \ + product1 = colorA; \ + product2 = colorA; \ + } \ + else \ + { \ + int r = 0; \ + product1 = interpolate_cb(colorA, colorC); \ + product = interpolate_cb(colorA, colorB); \ + r += result_cb(colorA, colorB, colorG, colorE); \ + r += result_cb(colorB, colorA, colorK, colorF); \ + r += result_cb(colorB, colorA, colorH, colorN); \ + r += result_cb(colorA, colorB, colorL, colorO); \ + if (r > 0) \ + product2 = colorA; \ + else if (r < 0) \ + product2 = colorB; \ + else \ + { \ + product2 = interpolate2_cb(colorA, colorB, colorC, colorD); \ + } \ + } \ + } \ + else \ + { \ + product2 = interpolate2_cb(colorA, colorB, colorC, colorD); \ + if (colorA == colorC && colorA == colorF && colorB != colorE && colorB == colorJ) \ + product = colorA; \ + else if (colorB == colorE && colorB == colorD && colorA != colorF && colorA == colorI) \ + product = colorB; \ + else \ + { \ + product = interpolate_cb(colorA, colorB); \ + } \ + if (colorA == colorB && colorA == colorH && colorG != colorC && colorC == colorM) \ + product1 = colorA; \ + else if (colorC == colorG && colorC == colorD && colorA != colorH && colorA == colorI) \ + product1 = colorC; \ + else \ + { \ + product1 = interpolate_cb(colorA, colorC); \ + } \ + } \ + out[0] = colorA; \ + out[1] = product; \ + out[dst_stride] = product1; \ + out[dst_stride + 1] = product2; \ + ++in; \ + out += 2 +#endif + +static void twoxsai_generic_xrgb8888(unsigned width, unsigned height, + int first, int last, uint32_t *src, + unsigned src_stride, uint32_t *dst, unsigned dst_stride) +{ + const unsigned nextline = (last) ? 0 : src_stride; + + for (; height; height--) + { + uint32_t *in = (uint32_t*)src; + uint32_t *out = (uint32_t*)dst; + + for (unsigned finish = width; finish; finish -= 1) + { + 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 + + twoxsai_function(twoxsai_result, twoxsai_interpolate_xrgb8888, twoxsai_interpolate2_xrgb8888); + } + + src += src_stride; + dst += 2 * dst_stride; + } +} + static void twoxsai_generic_rgb565(unsigned width, unsigned height, int first, int last, uint16_t *src, unsigned src_stride, uint16_t *dst, unsigned dst_stride) @@ -120,100 +241,7 @@ static void twoxsai_generic_rgb565(unsigned width, unsigned height, // H|C D|L // M|N O|P - if (colorA == colorD && colorB != colorC) - { - if ((colorA == colorE && colorB == colorL) || (colorA == colorC && colorA == colorF && colorB != colorE && colorB == colorJ)) - product = colorA; - else - { - product = twoxsai_interpolate_rgb565(colorA, colorB); - } - - if ((colorA == colorG && colorC == colorO) || (colorA == colorB && colorA == colorH && colorG != colorC && colorC == colorM)) - product1 = colorA; - else - { - product1 = twoxsai_interpolate_rgb565(colorA, colorC); - } - - product2 = colorA; - } else if (colorB == colorC && colorA != colorD) - { - if ((colorB == colorF && colorA == colorH) || (colorB == colorE && colorB == colorD && colorA != colorF && colorA == colorI)) - product = colorB; - else - { - product = twoxsai_interpolate_rgb565(colorA, colorB); - } - - if ((colorC == colorH && colorA == colorF) || (colorC == colorG && colorC == colorD && colorA != colorH && colorA == colorI)) - product1 = colorC; - else - { - product1 = twoxsai_interpolate_rgb565(colorA, colorC); - } - - product2 = colorB; - } - else if (colorA == colorD && colorB == colorC) - { - if (colorA == colorB) - { - product = colorA; - product1 = colorA; - product2 = colorA; - } - else - { - int r = 0; - product1 = twoxsai_interpolate_rgb565(colorA, colorC); - product = twoxsai_interpolate_rgb565(colorA, colorB); - - r += twoxsai_result1_rgb565(colorA, colorB, colorG, colorE); - r += twoxsai_result1_rgb565(colorB, colorA, colorK, colorF); - r += twoxsai_result1_rgb565(colorB, colorA, colorH, colorN); - r += twoxsai_result1_rgb565(colorA, colorB, colorL, colorO); - - if (r > 0) - product2 = colorA; - else if (r < 0) - product2 = colorB; - else - { - product2 = twoxsai_interpolate2_rgb565(colorA, colorB, colorC, colorD); - } - } - } - else - { - product2 = twoxsai_interpolate2_rgb565(colorA, colorB, colorC, colorD); - - if (colorA == colorC && colorA == colorF && colorB != colorE && colorB == colorJ) - product = colorA; - else if (colorB == colorE && colorB == colorD && colorA != colorF && colorA == colorI) - product = colorB; - else - { - product = twoxsai_interpolate_rgb565(colorA, colorB); - } - - if (colorA == colorB && colorA == colorH && colorG != colorC && colorC == colorM) - product1 = colorA; - else if (colorC == colorG && colorC == colorD && colorA != colorH && colorA == colorI) - product1 = colorC; - else - { - product1 = twoxsai_interpolate_rgb565(colorA, colorC); - } - } - - out[0] = colorA; - out[1] = product; - out[dst_stride] = product1; - out[dst_stride + 1] = product2; - - ++in; - out += 2; + twoxsai_function(twoxsai_result, twoxsai_interpolate_rgb565, twoxsai_interpolate2_rgb565); } src += src_stride; @@ -233,6 +261,18 @@ static void twoxsai_work_cb_rgb565(void *data, void *thread_data) 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; + 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); +} + static void twoxsai_generic_packets(void *data, struct softfilter_work_packet *packets, void *output, size_t output_stride, @@ -259,6 +299,8 @@ static void twoxsai_generic_packets(void *data, if (filt->in_fmt == SOFTFILTER_FMT_RGB565) packets[i].work = twoxsai_work_cb_rgb565; + else if (filt->in_fmt == SOFTFILTER_FMT_XRGB8888) + packets[i].work = twoxsai_work_cb_xrgb8888; packets[i].thread_data = thr; } } diff --git a/gfx/filters/super2xsai.c b/gfx/filters/super2xsai.c index 5a7b514dd0..4c0375bbd2 100644 --- a/gfx/filters/super2xsai.c +++ b/gfx/filters/super2xsai.c @@ -82,7 +82,7 @@ static void supertwoxsai_generic_destroy(void *data) #define supertwoxsai_interpolate2_rgb565(A, B, C, D) ((((A) & 0xE79C) >> 2) + (((B) & 0xE79C) >> 2) + (((C) & 0xE79C) >> 2) + (((D) & 0xE79C) >> 2) + (((((A) & 0x1863) + ((B) & 0x1863) + ((C) & 0x1863) + ((D) & 0x1863)) >> 2) & 0x1863)) -#define supertwoxsai_result1(A, B, C, D) (((A) != (C) || (A) != (D)) - ((B) != (C) || (B) != (D))) +#define supertwoxsai_result(A, B, C, D) (((A) != (C) || (A) != (D)) - ((B) != (C) || (B) != (D))) #ifndef supertwoxsai_declare_variables #define supertwoxsai_declare_variables(typename_t, in, nextline) \ @@ -106,7 +106,7 @@ static void supertwoxsai_generic_destroy(void *data) #endif #ifndef supertwoxsai_function -#define supertwoxsai_function(result1_cb, interpolate_cb, interpolate2_cb) \ +#define supertwoxsai_function(result_cb, interpolate_cb, interpolate2_cb) \ if (color2 == color6 && color5 != color3) \ product2b = product1b = color2; \ else if (color5 == color3 && color2 != color6) \ @@ -114,10 +114,10 @@ static void supertwoxsai_generic_destroy(void *data) else if (color5 == color3 && color2 == color6) \ { \ int r = 0; \ - r += result1_cb(color6, color5, color1, colorA1); \ - r += result1_cb(color6, color5, color4, colorB1); \ - r += result1_cb(color6, color5, colorA2, colorS1); \ - r += result1_cb(color6, color5, colorB2, colorS2); \ + r += result_cb(color6, color5, color1, colorA1); \ + r += result_cb(color6, color5, color4, colorB1); \ + r += result_cb(color6, color5, colorA2, colorS1); \ + r += result_cb(color6, color5, colorB2, colorS2); \ if (r > 0) \ product2b = product1b = color6; \ else if (r < 0) \ @@ -189,7 +189,7 @@ static void supertwoxsai_generic_xrgb8888(unsigned width, unsigned height, // A1 A2 //-------------------------------------- - supertwoxsai_function(supertwoxsai_result1, supertwoxsai_interpolate_xrgb8888, supertwoxsai_interpolate2_xrgb8888); + supertwoxsai_function(supertwoxsai_result, supertwoxsai_interpolate_xrgb8888, supertwoxsai_interpolate2_xrgb8888); } src += src_stride; @@ -218,7 +218,7 @@ static void supertwoxsai_generic_rgb565(unsigned width, unsigned height, // A1 A2 //-------------------------------------- - supertwoxsai_function(supertwoxsai_result1, supertwoxsai_interpolate_rgb565, supertwoxsai_interpolate2_rgb565); + supertwoxsai_function(supertwoxsai_result, supertwoxsai_interpolate_rgb565, supertwoxsai_interpolate2_rgb565); } src += src_stride; diff --git a/gfx/filters/supereagle.c b/gfx/filters/supereagle.c index 88c703ec62..87081b2c5b 100644 --- a/gfx/filters/supereagle.c +++ b/gfx/filters/supereagle.c @@ -26,7 +26,7 @@ static unsigned supereagle_generic_input_fmts(void) { - return SOFTFILTER_FMT_RGB565; + return SOFTFILTER_FMT_RGB565 | SOFTFILTER_FMT_XRGB8888; } static unsigned supereagle_generic_output_fmts(unsigned input_fmts) @@ -74,11 +74,15 @@ static void supereagle_generic_destroy(void *data) free(filt); } +#define supereagle_interpolate_xrgb8888(A, B) ((((A) & 0xFEFEFEFE) >> 1) + (((B) & 0xFEFEFEFE) >> 1) + ((A) & (B) & 0x01010101)) + +#define supereagle_interpolate2_xrgb8888(A, B, C, D) ((((A) & 0xFCFCFCFC) >> 2) + (((B) & 0xFCFCFCFC) >> 2) + (((C) & 0xFCFCFCFC) >> 2) + (((D) & 0xFCFCFCFC) >> 2) + (((((A) & 0x03030303) + ((B) & 0x03030303) + ((C) & 0x03030303) + ((D) & 0x03030303)) >> 2) & 0x03030303)) + #define supereagle_interpolate_rgb565(A, B) ((((A) & 0xF7DE) >> 1) + (((B) & 0xF7DE) >> 1) + ((A) & (B) & 0x0821)); #define supereagle_interpolate2_rgb565(A, B, C, D) ((((A) & 0xE79C) >> 2) + (((B) & 0xE79C) >> 2) + (((C) & 0xE79C) >> 2) + (((D) & 0xE79C) >> 2) + (((((A) & 0x1863) + ((B) & 0x1863) + ((C) & 0x1863) + ((D) & 0x1863)) >> 2) & 0x1863)) -#define supereagle_result1_rgb565(A, B, C, D) (((A) != (C) || (A) != (D)) - ((B) != (C) || (B) != (D))); +#define supereagle_result(A, B, C, D) (((A) != (C) || (A) != (D)) - ((B) != (C) || (B) != (D))); #define supereagle_declare_variables(typename_t, in, nextline) \ typename_t product1a, product1b, product2a, product2b; \ @@ -95,6 +99,115 @@ static void supereagle_generic_destroy(void *data) const typename_t colorA1 = *(in + nextline + nextline + 0); \ const typename_t colorA2 = *(in + nextline + nextline + 1) +#ifndef supereagle_function +#define supereagle_function(result_cb, interpolate_cb, interpolate2_cb) \ + if (color2 == color6 && color5 != color3) \ + { \ + product1b = product2a = color2; \ + if ((color1 == color2) || (color6 == colorB2)) \ + { \ + product1a = interpolate_cb(color2, color5); \ + product1a = interpolate_cb(color2, product1a); \ + } \ + else \ + { \ + product1a = interpolate_cb(color5, color6); \ + } \ + if ((color6 == colorS2) || (color2 == colorA1)) \ + { \ + product2b = interpolate_cb(color2, color3); \ + product2b = interpolate_cb(color2, product2b); \ + } \ + else \ + { \ + product2b = interpolate_cb(color2, color3); \ + } \ + } \ + else if (color5 == color3 && color2 != color6) \ + { \ + product2b = product1a = color5; \ + if ((colorB1 == color5) || (color3 == colorS1)) \ + { \ + product1b = interpolate_cb(color5, color6); \ + product1b = interpolate_cb(color5, product1b); \ + } \ + else \ + { \ + product1b = interpolate_cb(color5, color6); \ + } \ + if ((color3 == colorA2) || (color4 == color5)) \ + { \ + product2a = interpolate_cb(color5, color2); \ + product2a = interpolate_cb(color5, product2a); \ + } \ + else \ + { \ + product2a = interpolate_cb(color2, color3); \ + } \ + } \ + else if (color5 == color3 && color2 == color6) \ + { \ + int r = 0; \ + r += supereagle_result(color6, color5, color1, colorA1); \ + r += supereagle_result(color6, color5, color4, colorB1); \ + r += supereagle_result(color6, color5, colorA2, colorS1); \ + r += supereagle_result(color6, color5, colorB2, colorS2); \ + if (r > 0) \ + { \ + product1b = product2a = color2; \ + product1a = product2b = interpolate_cb(color5, color6); \ + } \ + else if (r < 0) \ + { \ + product2b = product1a = color5; \ + product1b = product2a = interpolate_cb(color5, color6); \ + } \ + else \ + { \ + product2b = product1a = color5; \ + product1b = product2a = color2; \ + } \ + } \ + else \ + { \ + product2b = product1a = interpolate_cb(color2, color6); \ + product2b = interpolate2_cb(color3, color3, color3, product2b); \ + product1a = interpolate2_cb(color5, color5, color5, product1a); \ + product2a = product1b = interpolate_cb(color5, color3); \ + product2a = interpolate2_cb(color2, color2, color2, product2a); \ + product1b = interpolate2_cb(color6, color6, color6, product1b); \ + } \ + out[0] = product1a; \ + out[1] = product1b; \ + out[dst_stride] = product2a; \ + out[dst_stride + 1] = product2b; \ + ++in; \ + out += 2 +#endif + +static void supereagle_generic_xrgb8888(unsigned width, unsigned height, + int first, int last, uint32_t *src, + unsigned src_stride, uint32_t *dst, unsigned dst_stride) +{ + const unsigned nextline = (last) ? 0 : src_stride; + + for (; height; height--) + { + uint32_t *in = (uint32_t*)src; + uint32_t *out = (uint32_t*)dst; + + for (unsigned finish = width; finish; finish -= 1) + { + supereagle_declare_variables(uint32_t, in, nextline); + + supereagle_function(supereagle_result, supereagle_interpolate_xrgb8888, supereagle_interpolate2_xrgb8888); + } + + src += src_stride; + dst += 2 * dst_stride; + } +} + static void supereagle_generic_rgb565(unsigned width, unsigned height, int first, int last, uint16_t *src, unsigned src_stride, uint16_t *dst, unsigned dst_stride) @@ -110,88 +223,7 @@ static void supereagle_generic_rgb565(unsigned width, unsigned height, { supereagle_declare_variables(uint16_t, in, nextline); - if (color2 == color6 && color5 != color3) - { - product1b = product2a = color2; - if ((color1 == color2) || (color6 == colorB2)) - { - product1a = supereagle_interpolate_rgb565(color2, color5); - product1a = supereagle_interpolate_rgb565(color2, product1a); - } - else - product1a = supereagle_interpolate_rgb565(color5, color6); - - if ((color6 == colorS2) || (color2 == colorA1)) - { - product2b = supereagle_interpolate_rgb565(color2, color3); - product2b = supereagle_interpolate_rgb565(color2, product2b); - } - else - product2b = supereagle_interpolate_rgb565(color2, color3); - } - else if (color5 == color3 && color2 != color6) - { - product2b = product1a = color5; - - if ((colorB1 == color5) || (color3 == colorS1)) - { - product1b = supereagle_interpolate_rgb565(color5, color6); - product1b = supereagle_interpolate_rgb565(color5, product1b); - } - else - product1b = supereagle_interpolate_rgb565(color5, color6); - - if ((color3 == colorA2) || (color4 == color5)) - { - product2a = supereagle_interpolate_rgb565(color5, color2); - product2a = supereagle_interpolate_rgb565(color5, product2a); - } - else - product2a = supereagle_interpolate_rgb565(color2, color3); - } - else if (color5 == color3 && color2 == color6) - { - int r = 0; - - r += supereagle_result1_rgb565(color6, color5, color1, colorA1); - r += supereagle_result1_rgb565(color6, color5, color4, colorB1); - r += supereagle_result1_rgb565(color6, color5, colorA2, colorS1); - r += supereagle_result1_rgb565(color6, color5, colorB2, colorS2); - - if (r > 0) - { - product1b = product2a = color2; - product1a = product2b = supereagle_interpolate_rgb565(color5, color6); - } - else if (r < 0) - { - product2b = product1a = color5; - product1b = product2a = supereagle_interpolate_rgb565(color5, color6); - } - else - { - product2b = product1a = color5; - product1b = product2a = color2; - } - } - else - { - product2b = product1a = supereagle_interpolate_rgb565(color2, color6); - product2b = supereagle_interpolate2_rgb565(color3, color3, color3, product2b); - product1a = supereagle_interpolate2_rgb565(color5, color5, color5, product1a); - - product2a = product1b = supereagle_interpolate_rgb565(color5, color3); - product2a = supereagle_interpolate2_rgb565(color2, color2, color2, product2a); - product1b = supereagle_interpolate2_rgb565(color6, color6, color6, product1b); - } - - out[0] = product1a; - out[1] = product1b; - out[dst_stride] = product2a; - out[dst_stride + 1] = product2b; - - ++in; - out += 2; + supereagle_function(supereagle_result, supereagle_interpolate_rgb565, supereagle_interpolate2_rgb565); } src += src_stride; @@ -211,6 +243,18 @@ static void supereagle_work_cb_rgb565(void *data, void *thread_data) thr->first, thr->last, input, thr->in_pitch / SOFTFILTER_BPP_RGB565, output, thr->out_pitch / SOFTFILTER_BPP_RGB565); } +static void supereagle_work_cb_xrgb8888(void *data, void *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; + + supereagle_generic_xrgb8888(width, height, + thr->first, thr->last, input, thr->in_pitch / SOFTFILTER_BPP_XRGB8888, output, thr->out_pitch / SOFTFILTER_BPP_XRGB8888); +} + static void supereagle_generic_packets(void *data, struct softfilter_work_packet *packets, void *output, size_t output_stride, @@ -237,6 +281,8 @@ static void supereagle_generic_packets(void *data, if (filt->in_fmt == SOFTFILTER_FMT_RGB565) packets[i].work = supereagle_work_cb_rgb565; + else if (filt->in_fmt == SOFTFILTER_FMT_XRGB8888) + packets[i].work = supereagle_work_cb_xrgb8888; packets[i].thread_data = thr; } }