From 35b8f22752531ae3c685a37561daaac8fa3f367e Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Sat, 12 Apr 2008 02:11:07 +0000 Subject: [PATCH] add missing files. SVN revision: 34254 --- .../evas/src/lib/engines/common_16/.cvsignore | 6 + .../src/lib/engines/common_16/Makefile.am | 34 + .../common_16/evas_soft16_dither_mask.c | 294 ++++ .../lib/engines/common_16/evas_soft16_font.c | 302 ++++ .../evas_soft16_image_scaled_sampled.c | 471 +++++++ .../common_16/evas_soft16_image_unscaled.c | 290 ++++ .../lib/engines/common_16/evas_soft16_line.c | 444 ++++++ .../lib/engines/common_16/evas_soft16_main.c | 596 ++++++++ .../engines/common_16/evas_soft16_polygon.c | 231 +++ .../engines/common_16/evas_soft16_rectangle.c | 126 ++ .../common_16/evas_soft16_scanline_blend.c | 471 +++++++ .../common_16/evas_soft16_scanline_fill.c | 86 ++ .../engines/software_16_sdl/.cvsignore | 6 + .../software_16_sdl/Evas_Engine_SDL_16.h | 22 + .../engines/software_16_sdl/Makefile.am | 28 + .../engines/software_16_sdl/evas_engine.c | 1253 +++++++++++++++++ .../engines/software_16_sdl/evas_engine.h | 54 + 17 files changed, 4714 insertions(+) create mode 100644 legacy/evas/src/lib/engines/common_16/.cvsignore create mode 100644 legacy/evas/src/lib/engines/common_16/Makefile.am create mode 100644 legacy/evas/src/lib/engines/common_16/evas_soft16_dither_mask.c create mode 100644 legacy/evas/src/lib/engines/common_16/evas_soft16_font.c create mode 100644 legacy/evas/src/lib/engines/common_16/evas_soft16_image_scaled_sampled.c create mode 100644 legacy/evas/src/lib/engines/common_16/evas_soft16_image_unscaled.c create mode 100644 legacy/evas/src/lib/engines/common_16/evas_soft16_line.c create mode 100644 legacy/evas/src/lib/engines/common_16/evas_soft16_main.c create mode 100644 legacy/evas/src/lib/engines/common_16/evas_soft16_polygon.c create mode 100644 legacy/evas/src/lib/engines/common_16/evas_soft16_rectangle.c create mode 100644 legacy/evas/src/lib/engines/common_16/evas_soft16_scanline_blend.c create mode 100644 legacy/evas/src/lib/engines/common_16/evas_soft16_scanline_fill.c create mode 100644 legacy/evas/src/modules/engines/software_16_sdl/.cvsignore create mode 100644 legacy/evas/src/modules/engines/software_16_sdl/Evas_Engine_SDL_16.h create mode 100644 legacy/evas/src/modules/engines/software_16_sdl/Makefile.am create mode 100644 legacy/evas/src/modules/engines/software_16_sdl/evas_engine.c create mode 100644 legacy/evas/src/modules/engines/software_16_sdl/evas_engine.h diff --git a/legacy/evas/src/lib/engines/common_16/.cvsignore b/legacy/evas/src/lib/engines/common_16/.cvsignore new file mode 100644 index 0000000000..306efda6dd --- /dev/null +++ b/legacy/evas/src/lib/engines/common_16/.cvsignore @@ -0,0 +1,6 @@ +Makefile.in +Makefile +.deps +.libs +libevas_engine_common.la +*.lo diff --git a/legacy/evas/src/lib/engines/common_16/Makefile.am b/legacy/evas/src/lib/engines/common_16/Makefile.am new file mode 100644 index 0000000000..4bf5047db0 --- /dev/null +++ b/legacy/evas/src/lib/engines/common_16/Makefile.am @@ -0,0 +1,34 @@ +AUTOMAKE_OPTIONS = 1.4 foreign + +MAINTAINERCLEANFILES = Makefile.in +INCLUDES = -I. \ + -I$(top_srcdir)/src/lib \ + -I$(top_srcdir)/src/lib/include \ + @FREETYPE_CFLAGS@ @VALGRIND_CFLAGS@ \ + @EET_CFLAGS@ @pthread_cflags@ + +noinst_LTLIBRARIES = libevas_engine_common_16.la +libevas_engine_common_16_la_SOURCES = \ +evas_soft16_dither_mask.c \ +evas_soft16_font.c \ +evas_soft16_image_scaled_sampled.c \ +evas_soft16_image_unscaled.c \ +evas_soft16_main.c \ +evas_soft16_rectangle.c \ +evas_soft16_line.c \ +evas_soft16_polygon.c + +libevas_engine_common_16_la_DEPENDENCIES = \ +$(top_builddir)/config.h + +EXTRA_DIST = \ +evas_soft16_dither_mask.c \ +evas_soft16_font.c \ +evas_soft16_image_scaled_sampled.c \ +evas_soft16_image_unscaled.c \ +evas_soft16_main.c \ +evas_soft16_rectangle.c \ +evas_soft16_line.c \ +evas_soft16_scanline_blend.c \ +evas_soft16_scanline_fill.c \ +evas_soft16_polygon.c diff --git a/legacy/evas/src/lib/engines/common_16/evas_soft16_dither_mask.c b/legacy/evas/src/lib/engines/common_16/evas_soft16_dither_mask.c new file mode 100644 index 0000000000..9414e9ae49 --- /dev/null +++ b/legacy/evas/src/lib/engines/common_16/evas_soft16_dither_mask.c @@ -0,0 +1,294 @@ +#include "evas_common_soft16.h" + +#define S16_DM_SIZE 128 +#define S16_DM_BITS 6 +#define S16_DM_DIV 64 +#define S16_DM_MSK (S16_DM_SIZE - 1) +#define S16_DM_SHF(_b) (S16_DM_BITS - (8 - _b)) + +static const DATA8 dither_table[S16_DM_SIZE][S16_DM_SIZE] = +{ + { 0, 41, 23, 5, 17, 39, 7, 15, 62, 23, 40, 51, 31, 47, 9, 32, 52, 27, 57, 25, 6, 61, 27, 52, 37, 7, 40, 63, 18, 36, 10, 42, 25, 62, 45, 34, 20, 42, 37, 14, 35, 29, 50, 10, 61, 2, 40, 8, 37, 12, 58, 22, 5, 41, 10, 39, 0, 60, 11, 46, 2, 55, 38, 17, 36, 59, 13, 54, 37, 56, 8, 29, 16, 13, 63, 22, 41, 55, 7, 20, 49, 14, 23, 55, 37, 23, 19, 36, 15, 49, 23, 63, 30, 14, 38, 27, 53, 13, 22, 41, 19, 31, 7, 19, 50, 30, 49, 16, 3, 32, 56, 40, 29, 34, 8, 48, 19, 45, 4, 51, 12, 46, 35, 49, 16, 42, 12, 62 }, + { 30, 57, 36, 54, 47, 34, 52, 27, 43, 4, 28, 7, 17, 36, 62, 13, 44, 7, 18, 48, 33, 21, 44, 14, 30, 47, 12, 33, 5, 55, 31, 58, 13, 30, 4, 17, 52, 10, 60, 26, 46, 0, 39, 27, 42, 22, 47, 25, 60, 32, 9, 38, 48, 17, 59, 30, 49, 18, 34, 25, 51, 19, 5, 48, 21, 8, 28, 46, 1, 32, 41, 19, 54, 47, 37, 18, 28, 11, 44, 30, 39, 56, 2, 33, 8, 42, 61, 28, 58, 8, 46, 9, 41, 4, 58, 7, 21, 48, 59, 10, 52, 14, 42, 57, 12, 25, 7, 53, 42, 24, 11, 50, 17, 59, 42, 2, 36, 60, 32, 17, 63, 29, 21, 7, 59, 32, 24, 39 }, + { 22, 8, 16, 32, 3, 25, 13, 57, 18, 45, 58, 39, 55, 20, 5, 42, 23, 34, 63, 1, 51, 10, 58, 4, 60, 23, 53, 27, 44, 21, 3, 48, 8, 50, 43, 54, 27, 32, 5, 55, 21, 58, 12, 53, 6, 36, 14, 50, 17, 29, 53, 15, 24, 52, 7, 36, 13, 42, 4, 53, 9, 35, 61, 26, 56, 32, 49, 15, 62, 23, 6, 60, 2, 31, 4, 48, 58, 38, 15, 61, 5, 25, 47, 28, 50, 15, 7, 40, 3, 32, 33, 52, 25, 50, 35, 42, 61, 3, 28, 36, 23, 63, 4, 33, 46, 62, 36, 23, 60, 6, 54, 28, 4, 37, 23, 55, 25, 8, 42, 54, 14, 6, 56, 38, 19, 52, 4, 46 }, + { 48, 53, 43, 12, 45, 63, 30, 37, 9, 34, 21, 1, 25, 47, 29, 58, 3, 54, 15, 39, 29, 17, 38, 35, 20, 43, 1, 49, 15, 59, 29, 39, 22, 35, 16, 23, 1, 47, 39, 18, 8, 44, 25, 31, 57, 19, 63, 4, 45, 3, 42, 61, 1, 31, 45, 20, 57, 29, 62, 21, 32, 41, 14, 44, 3, 39, 5, 34, 10, 43, 51, 35, 23, 52, 40, 10, 21, 1, 53, 18, 51, 43, 12, 62, 18, 54, 26, 51, 20, 57, 14, 1, 62, 16, 11, 18, 32, 39, 17, 44, 1, 48, 26, 37, 18, 2, 51, 14, 28, 45, 35, 18, 57, 13, 47, 11, 51, 20, 2, 39, 31, 47, 25, 1, 50, 11, 60, 7 }, + { 18, 28, 1, 56, 21, 10, 51, 2, 46, 54, 14, 61, 11, 50, 13, 38, 19, 31, 45, 9, 55, 24, 47, 5, 54, 9, 62, 11, 35, 8, 51, 14, 57, 6, 63, 40, 58, 14, 51, 28, 62, 34, 15, 48, 1, 41, 30, 35, 55, 21, 34, 11, 49, 37, 8, 52, 4, 23, 15, 43, 1, 58, 11, 23, 53, 16, 55, 26, 58, 18, 27, 12, 45, 14, 25, 63, 42, 33, 27, 35, 9, 31, 21, 38, 1, 44, 34, 12, 48, 38, 21, 44, 29, 47, 26, 53, 1, 46, 54, 8, 59, 29, 11, 55, 22, 41, 33, 20, 39, 1, 48, 9, 44, 32, 5, 62, 29, 44, 57, 23, 10, 58, 34, 43, 15, 37, 26, 33 }, + { 51, 38, 59, 24, 35, 42, 19, 60, 5, 32, 41, 26, 43, 33, 7, 53, 48, 11, 59, 23, 42, 2, 61, 30, 16, 40, 32, 24, 56, 41, 19, 33, 37, 26, 47, 9, 31, 22, 2, 45, 9, 54, 4, 37, 21, 52, 11, 23, 7, 57, 16, 25, 55, 18, 63, 27, 46, 39, 56, 10, 50, 37, 29, 47, 19, 63, 24, 9, 46, 2, 39, 60, 9, 57, 30, 7, 49, 11, 59, 3, 45, 57, 5, 60, 29, 22, 5, 60, 30, 9, 59, 18, 40, 6, 57, 36, 30, 12, 24, 34, 15, 40, 52, 6, 49, 9, 58, 4, 63, 12, 26, 61, 22, 53, 38, 16, 35, 14, 28, 50, 42, 17, 5, 28, 62, 20, 54, 12 }, + { 26, 6, 31, 15, 49, 6, 38, 27, 22, 49, 16, 56, 2, 62, 30, 21, 0, 36, 28, 6, 49, 32, 13, 52, 26, 50, 19, 46, 3, 26, 62, 0, 53, 12, 29, 3, 53, 41, 60, 24, 38, 13, 58, 16, 43, 9, 59, 39, 46, 28, 44, 40, 2, 33, 13, 41, 16, 6, 47, 31, 26, 17, 57, 6, 38, 0, 42, 36, 29, 52, 20, 31, 48, 0, 34, 56, 20, 36, 23, 54, 14, 41, 24, 37, 10, 55, 46, 25, 16, 45, 36, 4, 55, 23, 15, 8, 50, 62, 5, 56, 44, 20, 13, 28, 59, 31, 24, 47, 31, 52, 37, 17, 40, 0, 26, 49, 3, 60, 7, 33, 0, 61, 53, 40, 8, 45, 2, 41 }, + { 16, 63, 43, 4, 61, 24, 56, 13, 53, 8, 36, 12, 24, 41, 16, 46, 60, 26, 52, 39, 14, 57, 21, 37, 0, 45, 7, 59, 38, 17, 43, 10, 45, 20, 61, 43, 19, 11, 33, 17, 50, 32, 23, 61, 28, 49, 26, 0, 18, 51, 5, 60, 22, 58, 29, 0, 59, 34, 19, 62, 3, 52, 7, 44, 30, 59, 13, 50, 15, 62, 7, 17, 38, 22, 44, 15, 40, 4, 47, 28, 33, 17, 49, 16, 51, 40, 10, 56, 0, 53, 13, 49, 28, 38, 60, 21, 43, 19, 37, 27, 3, 51, 34, 39, 0, 45, 15, 43, 10, 21, 3, 55, 8, 33, 59, 10, 41, 18, 52, 24, 46, 20, 30, 13, 58, 22, 36, 57 }, + { 50, 34, 11, 47, 29, 17, 44, 0, 33, 63, 28, 46, 52, 5, 57, 10, 42, 18, 4, 63, 20, 8, 44, 10, 56, 34, 14, 29, 5, 54, 23, 59, 32, 49, 7, 34, 49, 27, 56, 0, 42, 7, 46, 3, 40, 6, 54, 32, 62, 13, 36, 10, 47, 8, 35, 49, 24, 51, 12, 40, 22, 35, 60, 12, 22, 51, 33, 4, 40, 25, 43, 55, 5, 54, 12, 61, 26, 51, 8, 62, 0, 53, 7, 63, 2, 32, 19, 34, 42, 24, 31, 63, 2, 10, 45, 33, 0, 48, 9, 61, 22, 47, 8, 62, 18, 56, 7, 54, 27, 57, 46, 30, 50, 19, 45, 30, 56, 36, 22, 47, 11, 38, 3, 51, 32, 48, 18, 9 }, + { 0, 21, 40, 19, 52, 9, 37, 48, 20, 40, 3, 18, 27, 38, 35, 22, 31, 56, 13, 35, 46, 28, 60, 40, 27, 18, 61, 50, 41, 30, 7, 36, 2, 25, 16, 57, 5, 15, 47, 29, 55, 19, 30, 52, 15, 34, 20, 12, 43, 30, 20, 54, 25, 44, 53, 12, 38, 5, 55, 27, 48, 15, 33, 27, 45, 8, 19, 28, 56, 11, 33, 49, 18, 36, 29, 2, 45, 16, 39, 19, 31, 43, 27, 35, 20, 52, 26, 6, 61, 11, 41, 17, 29, 51, 20, 56, 25, 32, 41, 17, 53, 31, 25, 14, 42, 23, 35, 16, 38, 6, 34, 12, 15, 62, 6, 21, 13, 1, 63, 9, 55, 27, 43, 25, 14, 4, 31, 55 }, + { 44, 29, 61, 2, 35, 58, 26, 15, 60, 10, 51, 59, 14, 55, 8, 50, 2, 44, 25, 51, 1, 33, 16, 4, 48, 36, 2, 21, 12, 57, 48, 13, 51, 55, 40, 28, 37, 62, 8, 39, 12, 63, 36, 10, 59, 24, 56, 47, 9, 50, 41, 1, 32, 17, 6, 21, 61, 30, 9, 43, 1, 54, 41, 2, 54, 37, 48, 61, 1, 46, 21, 3, 58, 24, 50, 32, 60, 10, 57, 25, 46, 12, 59, 4, 45, 13, 57, 47, 27, 39, 5, 58, 47, 14, 35, 4, 52, 13, 60, 6, 36, 10, 45, 55, 4, 50, 29, 2, 61, 50, 25, 58, 44, 24, 36, 42, 54, 28, 40, 32, 16, 56, 6, 62, 46, 39, 60, 23 }, + { 7, 48, 14, 54, 23, 40, 4, 45, 30, 22, 42, 32, 1, 44, 20, 29, 58, 8, 37, 19, 41, 54, 24, 58, 9, 53, 25, 46, 34, 16, 23, 38, 27, 11, 18, 1, 52, 21, 35, 22, 48, 5, 25, 45, 18, 38, 2, 27, 35, 4, 57, 15, 62, 39, 57, 28, 42, 16, 36, 60, 24, 18, 10, 63, 20, 5, 16, 23, 37, 14, 59, 27, 41, 8, 13, 42, 21, 35, 6, 50, 3, 38, 15, 48, 30, 39, 17, 3, 49, 14, 53, 33, 24, 7, 61, 44, 11, 39, 23, 49, 19, 58, 1, 32, 36, 12, 60, 41, 20, 13, 41, 4, 39, 1, 48, 8, 18, 51, 14, 44, 5, 37, 21, 34, 1, 26, 10, 37 }, + { 53, 36, 27, 9, 50, 12, 32, 55, 2, 57, 7, 17, 48, 34, 63, 15, 40, 26, 62, 11, 49, 6, 31, 39, 22, 42, 6, 63, 1, 39, 60, 4, 42, 61, 32, 45, 24, 44, 2, 60, 16, 41, 53, 1, 33, 61, 49, 17, 63, 23, 45, 26, 33, 3, 23, 46, 2, 50, 20, 4, 45, 34, 49, 30, 39, 58, 44, 31, 53, 34, 6, 52, 30, 47, 63, 1, 53, 22, 42, 31, 58, 23, 54, 22, 61, 8, 36, 59, 22, 35, 21, 1, 55, 40, 27, 16, 30, 54, 2, 29, 43, 16, 39, 63, 21, 46, 26, 10, 48, 32, 19, 53, 30, 56, 26, 60, 33, 4, 61, 23, 49, 59, 15, 53, 19, 58, 42, 16 }, + { 20, 5, 59, 46, 25, 62, 7, 19, 43, 25, 37, 61, 11, 24, 4, 54, 12, 52, 3, 32, 17, 61, 12, 47, 15, 55, 18, 31, 53, 28, 9, 50, 21, 6, 55, 9, 58, 14, 54, 26, 33, 7, 31, 58, 13, 21, 8, 42, 29, 6, 37, 11, 48, 52, 14, 60, 11, 39, 56, 32, 14, 58, 7, 26, 17, 4, 42, 8, 11, 47, 19, 38, 10, 17, 26, 37, 9, 55, 28, 13, 18, 40, 6, 33, 1, 43, 25, 11, 51, 7, 62, 43, 18, 37, 3, 57, 45, 9, 38, 58, 5, 52, 27, 7, 17, 53, 5, 57, 37, 2, 63, 9, 22, 15, 11, 38, 25, 45, 35, 0, 28, 10, 41, 30, 50, 8, 31, 57 }, + { 49, 33, 16, 38, 1, 42, 51, 34, 53, 14, 28, 49, 30, 56, 36, 23, 43, 20, 38, 56, 22, 45, 28, 0, 62, 35, 26, 44, 11, 19, 52, 35, 44, 15, 30, 38, 10, 31, 40, 4, 46, 50, 20, 40, 27, 44, 51, 14, 56, 53, 19, 59, 7, 29, 41, 19, 35, 25, 8, 52, 22, 44, 13, 53, 50, 32, 61, 24, 56, 25, 63, 0, 45, 57, 33, 59, 16, 46, 4, 62, 50, 11, 60, 37, 52, 19, 55, 29, 37, 46, 13, 26, 48, 10, 50, 34, 21, 63, 26, 13, 42, 33, 22, 55, 35, 28, 43, 15, 24, 51, 27, 34, 46, 49, 58, 3, 52, 9, 57, 19, 48, 55, 3, 35, 12, 45, 24, 3 }, + { 41, 11, 56, 28, 18, 31, 22, 10, 37, 6, 47, 13, 3, 41, 9, 46, 0, 48, 29, 6, 34, 10, 55, 37, 20, 8, 49, 3, 41, 59, 14, 25, 0, 63, 19, 47, 27, 51, 17, 57, 23, 10, 61, 6, 54, 3, 38, 31, 0, 22, 34, 43, 20, 55, 31, 0, 49, 63, 29, 38, 3, 62, 28, 40, 0, 22, 14, 35, 2, 48, 15, 43, 23, 14, 3, 29, 49, 20, 39, 34, 0, 44, 29, 9, 15, 47, 5, 42, 0, 31, 58, 5, 31, 61, 23, 15, 0, 47, 19, 50, 24, 3, 59, 11, 44, 0, 31, 59, 6, 42, 17, 60, 0, 39, 20, 31, 43, 17, 29, 40, 12, 25, 60, 22, 52, 15, 63, 29 }, + { 20, 52, 8, 44, 62, 4, 59, 49, 17, 63, 21, 39, 60, 18, 52, 27, 33, 59, 14, 51, 59, 43, 24, 5, 51, 30, 57, 17, 32, 5, 37, 56, 48, 34, 42, 3, 60, 5, 36, 13, 43, 37, 18, 34, 25, 12, 59, 24, 47, 36, 11, 50, 3, 38, 9, 58, 16, 5, 43, 18, 47, 10, 37, 18, 59, 46, 29, 52, 40, 12, 34, 28, 56, 36, 53, 7, 43, 8, 24, 52, 26, 17, 56, 43, 24, 32, 63, 20, 57, 16, 22, 52, 36, 8, 41, 56, 29, 32, 54, 7, 35, 57, 14, 48, 20, 62, 13, 39, 53, 29, 8, 45, 13, 29, 7, 61, 14, 54, 6, 63, 38, 32, 18, 43, 2, 39, 6, 47 }, + { 0, 58, 23, 35, 13, 46, 12, 39, 0, 31, 55, 24, 5, 35, 15, 61, 17, 5, 39, 25, 18, 2, 50, 33, 41, 13, 39, 23, 62, 46, 29, 12, 22, 8, 56, 25, 20, 49, 32, 62, 0, 56, 11, 46, 63, 42, 9, 16, 55, 5, 60, 15, 62, 26, 45, 21, 36, 51, 13, 57, 31, 24, 55, 6, 35, 9, 57, 5, 20, 60, 7, 51, 5, 19, 40, 25, 61, 32, 56, 12, 36, 48, 21, 2, 58, 12, 39, 28, 9, 50, 40, 12, 44, 18, 25, 49, 6, 38, 11, 62, 18, 46, 30, 9, 40, 25, 49, 19, 10, 36, 55, 22, 33, 52, 41, 18, 37, 27, 49, 21, 2, 46, 7, 53, 33, 61, 27, 35 }, + { 41, 31, 5, 39, 51, 26, 33, 57, 27, 41, 9, 44, 54, 29, 48, 7, 44, 36, 57, 10, 31, 63, 16, 45, 11, 60, 1, 47, 7, 20, 43, 3, 58, 36, 13, 52, 39, 7, 15, 28, 22, 48, 30, 21, 1, 29, 49, 44, 27, 17, 40, 30, 24, 42, 12, 53, 33, 7, 47, 20, 1, 42, 11, 49, 25, 43, 17, 32, 45, 27, 41, 21, 31, 62, 11, 49, 2, 15, 42, 5, 63, 7, 41, 27, 49, 6, 54, 23, 46, 34, 2, 28, 54, 3, 59, 12, 46, 17, 42, 28, 40, 1, 37, 51, 5, 55, 2, 34, 47, 16, 3, 62, 47, 5, 23, 56, 1, 44, 12, 34, 51, 16, 57, 11, 25, 17, 54, 13 }, + { 60, 26, 55, 18, 3, 60, 20, 6, 52, 15, 50, 19, 32, 11, 23, 53, 26, 21, 1, 47, 42, 27, 8, 58, 21, 27, 53, 36, 26, 54, 31, 50, 17, 30, 45, 1, 29, 59, 44, 53, 41, 4, 35, 58, 51, 19, 32, 4, 52, 34, 48, 8, 51, 5, 56, 2, 25, 61, 27, 38, 54, 27, 62, 21, 51, 1, 39, 62, 10, 50, 1, 58, 13, 47, 38, 18, 35, 54, 22, 51, 30, 19, 59, 34, 14, 32, 44, 4, 60, 15, 52, 62, 20, 43, 30, 35, 21, 60, 4, 52, 12, 24, 61, 18, 30, 42, 23, 61, 25, 50, 27, 38, 11, 59, 12, 35, 50, 30, 59, 24, 8, 42, 28, 37, 48, 9, 44, 21 }, + { 10, 47, 15, 50, 30, 43, 8, 45, 29, 2, 36, 59, 1, 58, 41, 3, 63, 31, 54, 20, 13, 55, 35, 38, 4, 44, 15, 9, 61, 2, 14, 38, 61, 10, 23, 54, 18, 12, 24, 2, 14, 55, 16, 8, 38, 14, 41, 60, 10, 23, 1, 58, 32, 17, 28, 37, 41, 15, 3, 60, 15, 33, 4, 36, 16, 59, 28, 14, 23, 55, 37, 18, 44, 28, 2, 57, 30, 10, 27, 46, 14, 38, 3, 53, 21, 61, 17, 35, 10, 41, 26, 7, 33, 9, 57, 1, 53, 37, 26, 20, 56, 48, 9, 33, 58, 16, 37, 7, 45, 1, 57, 15, 32, 26, 42, 23, 7, 20, 4, 54, 31, 62, 22, 1, 59, 30, 4, 51 }, + { 36, 2, 38, 11, 24, 36, 54, 22, 62, 47, 25, 8, 28, 45, 16, 38, 12, 43, 9, 37, 49, 3, 23, 52, 18, 30, 50, 33, 19, 42, 49, 26, 6, 40, 47, 35, 63, 38, 50, 33, 60, 26, 36, 47, 24, 57, 6, 26, 39, 63, 19, 44, 14, 46, 61, 9, 50, 30, 45, 23, 10, 50, 44, 8, 31, 54, 6, 46, 36, 4, 30, 54, 8, 52, 22, 41, 4, 60, 40, 0, 58, 24, 45, 10, 37, 1, 48, 30, 56, 17, 38, 48, 24, 47, 19, 39, 14, 8, 45, 32, 2, 34, 27, 44, 4, 52, 11, 56, 31, 21, 40, 19, 44, 51, 2, 63, 46, 58, 36, 43, 14, 5, 50, 38, 14, 56, 40, 23 }, + { 61, 46, 32, 63, 54, 1, 14, 34, 12, 40, 18, 49, 37, 10, 61, 30, 51, 24, 60, 7, 29, 40, 62, 11, 46, 58, 6, 56, 24, 10, 34, 52, 21, 59, 16, 3, 27, 5, 20, 46, 9, 40, 7, 62, 2, 30, 53, 15, 48, 10, 28, 35, 54, 6, 21, 34, 18, 55, 7, 40, 57, 19, 26, 60, 41, 13, 24, 51, 19, 61, 9, 25, 34, 15, 63, 11, 45, 17, 20, 47, 33, 8, 31, 62, 43, 26, 53, 7, 24, 59, 0, 13, 55, 4, 62, 27, 51, 31, 63, 15, 58, 7, 54, 14, 46, 22, 28, 43, 12, 63, 8, 54, 5, 17, 39, 33, 15, 10, 27, 17, 47, 34, 19, 45, 27, 12, 33, 17 }, + { 5, 28, 21, 7, 17, 48, 42, 58, 23, 4, 63, 14, 55, 21, 34, 5, 19, 0, 45, 17, 52, 15, 25, 32, 0, 22, 40, 13, 45, 62, 18, 0, 43, 11, 33, 55, 30, 42, 57, 19, 51, 31, 22, 43, 18, 45, 34, 0, 43, 31, 56, 3, 23, 40, 59, 0, 44, 13, 48, 35, 2, 32, 46, 0, 21, 48, 35, 3, 40, 32, 43, 59, 0, 48, 33, 26, 53, 36, 55, 12, 51, 16, 55, 5, 18, 29, 11, 39, 51, 19, 45, 31, 42, 21, 35, 6, 22, 47, 10, 38, 23, 50, 20, 36, 0, 60, 38, 4, 50, 35, 48, 34, 24, 57, 9, 53, 28, 48, 61, 0, 56, 24, 53, 3, 63, 6, 42, 57 }, + { 13, 53, 45, 40, 58, 27, 6, 16, 38, 51, 33, 30, 43, 2, 47, 56, 40, 50, 33, 57, 27, 5, 47, 42, 60, 36, 16, 54, 28, 4, 37, 57, 28, 51, 22, 8, 45, 14, 6, 39, 0, 54, 11, 59, 28, 12, 50, 21, 61, 13, 19, 38, 49, 11, 25, 37, 58, 29, 22, 63, 14, 56, 12, 53, 30, 63, 9, 57, 26, 12, 47, 16, 23, 39, 50, 6, 31, 2, 25, 6, 28, 41, 36, 22, 50, 57, 42, 3, 34, 8, 28, 61, 11, 50, 16, 54, 41, 0, 55, 43, 5, 29, 41, 63, 25, 16, 53, 18, 26, 10, 21, 0, 61, 30, 41, 22, 3, 38, 20, 39, 29, 8, 41, 16, 36, 52, 22, 19 }, + { 55, 34, 0, 25, 10, 32, 56, 44, 28, 0, 57, 7, 26, 53, 23, 8, 13, 35, 22, 12, 36, 60, 20, 8, 14, 29, 48, 2, 41, 49, 23, 13, 39, 7, 48, 58, 25, 53, 34, 62, 28, 16, 48, 4, 37, 56, 27, 5, 36, 52, 46, 7, 62, 33, 52, 11, 17, 53, 5, 28, 41, 24, 38, 17, 5, 39, 20, 45, 15, 56, 5, 38, 60, 8, 14, 57, 21, 48, 62, 39, 59, 13, 1, 60, 9, 32, 16, 63, 44, 25, 52, 15, 36, 2, 60, 29, 12, 33, 25, 17, 59, 45, 13, 8, 49, 32, 6, 40, 59, 29, 45, 37, 13, 47, 6, 55, 30, 45, 9, 52, 13, 59, 25, 47, 32, 1, 49, 30 }, + { 9, 39, 14, 61, 49, 37, 3, 20, 50, 13, 41, 19, 46, 17, 38, 59, 28, 62, 4, 44, 54, 1, 34, 51, 55, 7, 63, 32, 21, 8, 56, 31, 62, 19, 36, 1, 41, 17, 24, 12, 42, 35, 25, 52, 20, 8, 44, 59, 25, 2, 22, 42, 16, 29, 4, 46, 20, 36, 43, 9, 51, 8, 49, 26, 58, 33, 54, 1, 37, 29, 52, 20, 27, 45, 19, 35, 42, 16, 10, 32, 20, 49, 46, 27, 40, 4, 47, 22, 13, 55, 4, 47, 26, 44, 23, 40, 58, 19, 48, 13, 31, 2, 57, 34, 42, 19, 61, 32, 14, 55, 5, 51, 26, 19, 58, 16, 49, 14, 62, 5, 33, 44, 21, 7, 60, 26, 11, 41 }, + { 62, 24, 47, 29, 8, 19, 53, 11, 60, 24, 32, 61, 4, 55, 31, 2, 49, 16, 39, 9, 31, 24, 43, 17, 26, 38, 11, 25, 58, 43, 12, 35, 3, 46, 15, 32, 63, 4, 49, 56, 2, 60, 10, 32, 63, 17, 39, 12, 55, 30, 57, 9, 48, 55, 39, 24, 60, 2, 58, 31, 19, 61, 34, 3, 42, 11, 22, 46, 7, 61, 10, 42, 3, 55, 32, 1, 58, 28, 44, 54, 4, 34, 23, 15, 56, 20, 37, 58, 6, 30, 38, 18, 63, 9, 32, 5, 51, 3, 62, 37, 52, 18, 39, 23, 3, 51, 9, 47, 1, 23, 43, 15, 60, 35, 11, 40, 1, 36, 31, 26, 57, 2, 37, 54, 18, 44, 58, 16 }, + { 5, 51, 3, 33, 43, 62, 21, 42, 35, 9, 48, 15, 36, 10, 22, 42, 20, 46, 26, 56, 50, 12, 59, 3, 48, 19, 45, 53, 1, 27, 47, 17, 52, 24, 56, 11, 51, 21, 37, 30, 20, 46, 14, 41, 1, 47, 33, 7, 41, 17, 35, 27, 20, 1, 14, 54, 26, 33, 18, 47, 1, 44, 14, 59, 16, 52, 28, 18, 49, 31, 25, 34, 63, 13, 51, 24, 9, 50, 3, 23, 38, 63, 7, 52, 29, 46, 11, 33, 50, 22, 57, 36, 1, 57, 49, 17, 39, 28, 9, 35, 6, 27, 53, 15, 55, 30, 24, 58, 36, 41, 11, 52, 32, 3, 44, 25, 62, 23, 51, 15, 42, 22, 50, 10, 39, 4, 31, 35 }, + { 46, 22, 57, 17, 12, 39, 26, 5, 31, 59, 1, 45, 27, 62, 52, 7, 58, 33, 6, 18, 39, 22, 33, 41, 57, 5, 35, 18, 40, 16, 60, 5, 29, 42, 7, 39, 27, 44, 9, 47, 8, 26, 54, 22, 51, 29, 24, 49, 15, 61, 4, 51, 31, 63, 43, 6, 50, 8, 39, 12, 53, 37, 23, 30, 40, 6, 62, 43, 14, 53, 2, 49, 7, 36, 17, 41, 61, 37, 18, 56, 11, 18, 44, 35, 2, 19, 61, 0, 41, 14, 8, 30, 43, 12, 24, 46, 14, 54, 42, 21, 44, 61, 10, 46, 37, 11, 44, 7, 18, 63, 20, 29, 7, 49, 28, 54, 8, 43, 4, 48, 18, 63, 12, 29, 48, 24, 59, 20 }, + { 13, 36, 28, 54, 35, 2, 56, 46, 16, 49, 22, 40, 11, 34, 14, 43, 29, 12, 63, 48, 2, 61, 7, 15, 28, 30, 50, 9, 61, 33, 38, 23, 54, 13, 61, 33, 3, 59, 16, 35, 58, 40, 5, 38, 13, 57, 3, 58, 37, 21, 45, 12, 39, 7, 35, 30, 13, 56, 22, 62, 27, 6, 55, 10, 48, 21, 33, 2, 38, 23, 40, 20, 44, 29, 59, 4, 26, 12, 33, 47, 28, 53, 31, 13, 59, 41, 27, 49, 26, 54, 45, 16, 53, 21, 35, 7, 59, 26, 11, 56, 1, 24, 33, 4, 28, 62, 21, 49, 31, 2, 56, 39, 24, 58, 13, 17, 37, 21, 56, 10, 38, 0, 34, 55, 15, 43, 1, 52 }, + { 42, 9, 50, 6, 25, 60, 14, 38, 10, 29, 53, 18, 57, 3, 25, 51, 0, 53, 25, 17, 29, 37, 52, 46, 0, 62, 14, 37, 4, 50, 10, 44, 0, 46, 20, 25, 50, 19, 55, 0, 23, 31, 62, 34, 11, 45, 19, 32, 0, 53, 10, 59, 23, 47, 18, 60, 42, 28, 37, 3, 50, 15, 35, 44, 0, 51, 27, 60, 9, 57, 16, 58, 11, 22, 46, 15, 53, 48, 7, 42, 0, 60, 5, 49, 24, 54, 9, 17, 39, 5, 34, 62, 3, 40, 60, 31, 0, 47, 29, 16, 49, 39, 59, 17, 50, 0, 40, 13, 53, 38, 16, 46, 0, 42, 34, 60, 2, 53, 29, 31, 58, 46, 27, 6, 61, 8, 37, 28 }, + { 0, 63, 21, 40, 45, 18, 51, 23, 63, 34, 6, 43, 28, 38, 55, 19, 40, 35, 8, 41, 54, 10, 21, 32, 39, 23, 53, 26, 55, 28, 22, 63, 30, 34, 9, 48, 6, 38, 29, 43, 49, 6, 18, 52, 27, 61, 9, 43, 28, 42, 33, 26, 56, 3, 51, 23, 0, 48, 16, 45, 32, 25, 63, 20, 57, 17, 42, 12, 35, 47, 5, 31, 39, 56, 6, 30, 34, 21, 61, 25, 14, 40, 22, 38, 15, 6, 36, 56, 20, 60, 25, 12, 51, 27, 10, 56, 42, 20, 36, 63, 32, 6, 21, 41, 12, 34, 60, 26, 5, 48, 27, 10, 62, 19, 6, 47, 39, 14, 45, 7, 24, 17, 41, 32, 23, 51, 19, 56 }, + { 45, 31, 15, 59, 4, 33, 7, 47, 0, 41, 13, 61, 4, 47, 9, 23, 60, 14, 57, 31, 4, 45, 59, 6, 58, 10, 44, 20, 8, 42, 15, 6, 55, 17, 58, 31, 53, 12, 61, 10, 15, 57, 43, 2, 23, 35, 48, 14, 54, 6, 18, 49, 15, 38, 11, 34, 62, 9, 21, 58, 11, 41, 4, 31, 38, 8, 29, 55, 19, 36, 27, 52, 0, 25, 50, 43, 1, 39, 8, 55, 35, 51, 10, 30, 45, 62, 29, 2, 46, 10, 32, 48, 18, 38, 5, 22, 33, 8, 51, 3, 14, 44, 54, 25, 57, 30, 18, 52, 33, 22, 59, 28, 36, 52, 32, 21, 26, 50, 5, 55, 35, 60, 14, 54, 4, 40, 16, 33 }, + { 27, 3, 49, 10, 30, 40, 55, 27, 57, 24, 52, 21, 32, 17, 60, 30, 5, 44, 27, 49, 19, 34, 13, 24, 43, 36, 3, 49, 31, 59, 37, 48, 26, 41, 2, 41, 14, 36, 21, 32, 40, 26, 13, 49, 55, 5, 16, 40, 25, 60, 36, 1, 63, 29, 17, 44, 25, 40, 52, 5, 29, 47, 54, 13, 46, 24, 60, 4, 51, 22, 63, 14, 45, 18, 12, 62, 17, 57, 19, 42, 3, 26, 58, 48, 1, 21, 40, 52, 23, 37, 44, 1, 29, 58, 43, 50, 15, 61, 19, 45, 58, 28, 7, 48, 2, 46, 8, 42, 3, 55, 8, 50, 12, 4, 55, 10, 63, 33, 20, 40, 11, 3, 46, 20, 48, 26, 61, 11 }, + { 44, 56, 24, 36, 53, 19, 12, 37, 16, 44, 7, 36, 49, 54, 11, 37, 48, 21, 15, 1, 62, 25, 47, 56, 16, 18, 51, 12, 40, 1, 24, 11, 52, 16, 23, 59, 28, 1, 45, 53, 4, 60, 37, 21, 39, 30, 63, 20, 52, 10, 30, 45, 8, 41, 54, 4, 57, 7, 34, 55, 36, 18, 23, 59, 2, 48, 11, 32, 44, 1, 41, 8, 33, 54, 38, 23, 30, 46, 6, 29, 62, 18, 32, 16, 55, 34, 14, 11, 61, 7, 55, 16, 53, 13, 23, 2, 55, 37, 26, 10, 33, 23, 36, 16, 38, 22, 56, 15, 24, 43, 35, 17, 44, 40, 25, 46, 16, 1, 57, 25, 49, 36, 28, 62, 9, 35, 7, 53 }, + { 17, 38, 8, 61, 1, 50, 26, 62, 3, 31, 56, 15, 1, 26, 40, 2, 34, 51, 56, 36, 42, 9, 38, 2, 29, 60, 32, 57, 19, 62, 34, 47, 4, 57, 39, 7, 44, 63, 24, 18, 46, 28, 8, 54, 1, 34, 7, 46, 3, 37, 50, 23, 57, 21, 13, 46, 31, 20, 43, 15, 1, 61, 8, 33, 37, 17, 56, 26, 15, 49, 24, 59, 28, 3, 56, 9, 52, 32, 13, 49, 10, 43, 5, 45, 8, 25, 59, 42, 28, 33, 19, 40, 8, 63, 35, 47, 25, 4, 40, 52, 1, 60, 12, 53, 63, 9, 29, 60, 37, 19, 1, 62, 31, 20, 58, 12, 41, 30, 43, 9, 18, 52, 22, 1, 39, 30, 58, 21 }, + { 13, 47, 29, 18, 43, 34, 5, 48, 20, 42, 10, 45, 30, 58, 20, 63, 24, 11, 6, 28, 54, 14, 22, 52, 41, 7, 26, 5, 45, 15, 53, 13, 35, 27, 18, 50, 12, 33, 5, 56, 10, 17, 45, 24, 59, 15, 50, 26, 56, 13, 19, 5, 32, 52, 27, 36, 2, 61, 12, 26, 49, 40, 27, 52, 13, 50, 6, 39, 61, 34, 10, 37, 48, 20, 41, 27, 2, 36, 59, 24, 54, 33, 63, 20, 38, 50, 3, 17, 52, 4, 58, 27, 45, 21, 32, 11, 48, 17, 57, 20, 46, 38, 25, 43, 4, 34, 51, 6, 13, 45, 57, 26, 6, 48, 2, 35, 53, 23, 61, 34, 59, 6, 42, 56, 13, 51, 2, 41 }, + { 32, 5, 55, 23, 58, 14, 22, 52, 29, 15, 61, 25, 51, 8, 43, 13, 53, 41, 46, 20, 3, 33, 63, 11, 48, 21, 54, 38, 28, 3, 30, 43, 21, 62, 9, 31, 55, 22, 51, 29, 37, 62, 32, 12, 42, 29, 41, 9, 33, 44, 62, 28, 43, 1, 59, 19, 48, 30, 51, 39, 24, 4, 58, 19, 42, 29, 22, 43, 3, 18, 53, 5, 13, 50, 16, 60, 45, 21, 7, 40, 15, 0, 26, 53, 13, 31, 43, 24, 47, 31, 15, 49, 2, 41, 6, 59, 29, 42, 9, 30, 14, 7, 49, 18, 31, 47, 20, 39, 49, 32, 11, 41, 54, 15, 61, 18, 7, 38, 4, 13, 44, 28, 15, 32, 45, 19, 27, 49 }, + { 63, 34, 11, 39, 2, 45, 37, 8, 59, 39, 33, 4, 36, 17, 48, 5, 29, 18, 32, 61, 39, 50, 5, 27, 35, 0, 46, 12, 22, 49, 60, 6, 54, 0, 38, 49, 2, 42, 15, 40, 0, 47, 20, 51, 3, 57, 18, 61, 22, 0, 39, 16, 55, 12, 35, 8, 41, 22, 6, 59, 16, 45, 10, 36, 0, 62, 9, 54, 30, 58, 21, 43, 63, 31, 7, 35, 12, 48, 58, 28, 47, 37, 41, 9, 57, 20, 61, 0, 36, 11, 57, 35, 23, 52, 37, 18, 0, 62, 22, 55, 35, 62, 27, 54, 0, 15, 61, 28, 2, 59, 22, 9, 37, 27, 33, 51, 29, 48, 19, 50, 25, 37, 10, 57, 5, 37, 60, 8 }, + { 20, 25, 46, 52, 31, 60, 12, 55, 0, 19, 11, 46, 62, 35, 23, 38, 57, 0, 55, 10, 16, 30, 58, 44, 17, 59, 29, 63, 42, 8, 36, 20, 33, 46, 16, 61, 25, 35, 8, 54, 26, 7, 58, 22, 34, 6, 47, 14, 53, 31, 48, 9, 37, 25, 49, 63, 16, 55, 45, 14, 34, 63, 21, 53, 25, 33, 46, 16, 35, 7, 46, 29, 0, 39, 25, 55, 22, 34, 18, 4, 56, 11, 23, 51, 28, 6, 39, 14, 62, 44, 19, 8, 60, 12, 56, 28, 50, 34, 39, 5, 51, 3, 41, 12, 57, 35, 10, 53, 25, 17, 52, 30, 47, 0, 43, 14, 5, 57, 31, 55, 0, 63, 47, 23, 54, 24, 14, 43 }, + { 0, 57, 16, 6, 26, 19, 35, 28, 49, 42, 54, 26, 21, 1, 59, 27, 9, 47, 26, 44, 50, 22, 13, 40, 8, 37, 10, 34, 17, 56, 25, 58, 13, 27, 44, 9, 20, 58, 31, 17, 60, 36, 10, 41, 53, 25, 36, 39, 4, 24, 58, 17, 60, 4, 22, 38, 10, 32, 0, 50, 31, 7, 28, 47, 12, 57, 5, 26, 52, 23, 14, 40, 57, 17, 47, 5, 53, 1, 44, 31, 19, 60, 46, 2, 35, 48, 30, 54, 22, 5, 51, 39, 25, 31, 4, 43, 14, 9, 45, 16, 24, 44, 19, 29, 40, 23, 44, 7, 38, 42, 4, 63, 12, 54, 23, 59, 22, 42, 8, 15, 40, 21, 8, 34, 3, 41, 30, 50 }, + { 39, 10, 48, 33, 41, 54, 5, 47, 23, 13, 32, 7, 52, 44, 14, 39, 58, 18, 35, 6, 37, 2, 60, 24, 55, 19, 53, 2, 51, 32, 1, 41, 51, 4, 40, 29, 47, 3, 52, 44, 13, 49, 28, 16, 1, 62, 11, 27, 52, 35, 5, 42, 29, 47, 14, 56, 28, 53, 26, 38, 9, 56, 40, 3, 38, 15, 41, 60, 1, 37, 50, 25, 11, 28, 61, 19, 42, 62, 10, 52, 39, 6, 32, 14, 58, 17, 7, 26, 42, 34, 27, 10, 54, 40, 20, 63, 26, 53, 21, 61, 32, 7, 59, 48, 3, 56, 18, 31, 58, 14, 49, 21, 36, 16, 45, 9, 36, 24, 62, 45, 27, 31, 53, 17, 49, 12, 62, 18 }, + { 28, 59, 21, 58, 2, 16, 38, 9, 62, 3, 56, 41, 10, 31, 50, 4, 32, 52, 12, 63, 23, 46, 33, 31, 4, 48, 25, 43, 14, 23, 47, 11, 22, 55, 14, 60, 23, 37, 11, 39, 23, 2, 45, 56, 31, 43, 19, 55, 16, 46, 21, 51, 11, 33, 44, 2, 41, 18, 5, 52, 23, 44, 17, 60, 27, 49, 11, 32, 44, 10, 54, 2, 56, 33, 8, 38, 13, 29, 36, 16, 24, 63, 27, 51, 21, 43, 56, 12, 49, 3, 59, 48, 1, 15, 46, 7, 36, 2, 47, 11, 50, 27, 37, 13, 33, 8, 51, 46, 1, 34, 28, 40, 3, 33, 60, 29, 47, 1, 35, 11, 59, 42, 2, 60, 26, 46, 6, 35 }, + { 4, 43, 9, 29, 36, 63, 24, 44, 20, 50, 30, 17, 60, 22, 16, 43, 25, 3, 42, 19, 51, 15, 8, 54, 42, 15, 61, 5, 39, 57, 18, 61, 31, 48, 34, 2, 50, 19, 57, 5, 63, 33, 19, 38, 13, 27, 48, 7, 32, 61, 2, 26, 58, 6, 24, 50, 13, 61, 42, 20, 62, 2, 35, 20, 51, 4, 62, 18, 23, 58, 20, 31, 43, 15, 51, 45, 26, 50, 4, 55, 45, 3, 35, 9, 38, 1, 32, 61, 20, 45, 17, 33, 24, 57, 29, 51, 22, 58, 38, 30, 15, 1, 54, 21, 63, 43, 26, 12, 24, 56, 8, 60, 50, 19, 5, 52, 13, 54, 17, 50, 4, 16, 36, 12, 32, 56, 22, 54 }, + { 51, 25, 40, 53, 12, 49, 15, 57, 34, 7, 38, 47, 2, 36, 55, 8, 61, 30, 56, 7, 28, 59, 48, 11, 27, 35, 21, 45, 28, 36, 9, 38, 6, 16, 24, 63, 10, 32, 28, 43, 21, 53, 5, 60, 8, 57, 3, 45, 11, 37, 15, 54, 40, 20, 62, 36, 27, 34, 11, 48, 30, 15, 54, 8, 30, 42, 22, 34, 48, 13, 35, 63, 4, 37, 22, 2, 59, 9, 41, 23, 13, 41, 49, 18, 59, 24, 40, 5, 37, 30, 9, 61, 44, 6, 37, 11, 33, 17, 5, 55, 41, 60, 23, 39, 17, 5, 30, 62, 41, 16, 46, 25, 11, 56, 39, 26, 20, 38, 29, 39, 22, 52, 44, 20, 48, 1, 38, 14 }, + { 15, 33, 2, 18, 44, 6, 27, 0, 32, 61, 25, 12, 58, 28, 40, 20, 47, 13, 34, 43, 38, 1, 23, 62, 40, 0, 51, 10, 63, 3, 52, 26, 44, 30, 45, 6, 41, 54, 0, 51, 12, 30, 46, 24, 49, 22, 40, 33, 63, 23, 43, 30, 9, 47, 0, 17, 54, 7, 57, 3, 37, 47, 24, 46, 13, 55, 7, 52, 2, 42, 6, 26, 49, 18, 60, 34, 16, 57, 33, 20, 61, 30, 8, 54, 14, 46, 12, 53, 16, 55, 38, 13, 22, 53, 18, 59, 46, 27, 43, 19, 32, 10, 45, 6, 49, 36, 52, 2, 20, 55, 6, 39, 32, 15, 44, 3, 58, 10, 63, 6, 56, 30, 7, 58, 9, 40, 19, 63 }, + { 10, 47, 61, 23, 55, 31, 52, 42, 17, 45, 4, 51, 27, 6, 15, 53, 0, 49, 26, 10, 56, 18, 36, 6, 20, 58, 32, 30, 13, 49, 19, 56, 0, 59, 12, 53, 27, 17, 38, 25, 48, 9, 15, 36, 14, 30, 59, 17, 0, 50, 8, 58, 18, 56, 31, 45, 21, 41, 29, 19, 60, 6, 32, 59, 0, 36, 29, 39, 19, 59, 46, 12, 55, 30, 10, 47, 24, 3, 28, 48, 0, 55, 44, 27, 33, 4, 63, 29, 49, 0, 26, 50, 34, 2, 42, 14, 0, 62, 9, 56, 3, 52, 28, 34, 58, 9, 20, 48, 37, 32, 22, 53, 0, 62, 27, 49, 34, 46, 21, 33, 41, 14, 25, 37, 53, 29, 31, 45 }, + { 56, 28, 7, 37, 11, 36, 20, 9, 54, 14, 39, 19, 34, 63, 45, 37, 24, 17, 60, 31, 21, 45, 53, 29, 47, 15, 7, 55, 40, 23, 34, 14, 42, 20, 37, 35, 15, 59, 7, 62, 34, 40, 59, 1, 51, 42, 10, 28, 54, 21, 35, 5, 38, 13, 36, 4, 59, 12, 39, 53, 15, 43, 9, 21, 39, 62, 16, 56, 25, 9, 32, 38, 0, 41, 14, 51, 40, 53, 43, 11, 37, 17, 5, 22, 57, 39, 19, 7, 42, 21, 60, 10, 31, 63, 25, 52, 30, 49, 36, 25, 48, 17, 61, 14, 22, 42, 29, 13, 60, 11, 47, 18, 35, 41, 7, 23, 4, 16, 51, 11, 0, 48, 61, 3, 17, 50, 5, 24 }, + { 0, 42, 21, 49, 60, 3, 57, 40, 29, 48, 23, 56, 42, 11, 22, 5, 59, 39, 4, 50, 3, 41, 12, 57, 25, 50, 44, 18, 4, 46, 7, 62, 33, 50, 4, 56, 21, 32, 43, 18, 3, 23, 55, 34, 20, 4, 53, 38, 12, 46, 29, 52, 25, 61, 23, 51, 26, 46, 1, 34, 25, 57, 28, 51, 26, 11, 50, 3, 44, 28, 53, 21, 57, 27, 62, 6, 31, 19, 8, 63, 26, 59, 36, 47, 15, 29, 50, 25, 35, 47, 18, 41, 4, 48, 8, 40, 12, 23, 6, 44, 13, 40, 1, 31, 55, 0, 61, 43, 4, 50, 26, 58, 9, 53, 24, 61, 42, 55, 31, 43, 57, 20, 34, 27, 43, 8, 59, 39 }, + { 18, 51, 30, 13, 26, 16, 46, 22, 2, 59, 8, 30, 1, 48, 33, 51, 29, 9, 46, 16, 62, 14, 33, 2, 38, 9, 27, 60, 37, 26, 53, 17, 28, 10, 24, 46, 2, 49, 8, 57, 29, 45, 6, 26, 62, 44, 18, 25, 61, 3, 42, 14, 49, 10, 43, 6, 17, 32, 63, 10, 49, 4, 40, 14, 45, 33, 22, 37, 12, 61, 5, 17, 43, 7, 23, 37, 15, 58, 49, 13, 39, 21, 10, 52, 1, 62, 9, 56, 12, 2, 58, 28, 36, 16, 56, 28, 56, 35, 20, 63, 24, 37, 51, 8, 45, 25, 16, 33, 27, 38, 2, 44, 13, 30, 17, 36, 12, 26, 5, 18, 28, 47, 13, 60, 23, 45, 13, 33 }, + { 55, 4, 62, 34, 52, 38, 7, 63, 32, 37, 13, 53, 25, 62, 18, 12, 55, 41, 27, 35, 24, 49, 31, 52, 17, 63, 34, 1, 56, 12, 41, 2, 48, 58, 39, 16, 61, 27, 41, 52, 13, 19, 50, 39, 11, 31, 57, 6, 32, 40, 20, 55, 1, 28, 33, 57, 48, 8, 37, 22, 44, 18, 53, 1, 61, 5, 54, 16, 47, 36, 50, 24, 55, 34, 48, 45, 1, 30, 33, 46, 2, 50, 32, 42, 25, 34, 43, 21, 38, 52, 23, 45, 14, 54, 21, 4, 44, 16, 53, 29, 10, 47, 19, 57, 12, 54, 39, 10, 51, 15, 63, 21, 57, 40, 51, 1, 48, 57, 37, 62, 2, 38, 9, 52, 1, 35, 58, 22 }, + { 36, 46, 10, 42, 1, 27, 43, 15, 50, 21, 45, 16, 41, 3, 35, 44, 20, 1, 57, 11, 55, 7, 43, 8, 22, 42, 13, 46, 21, 39, 31, 60, 22, 5, 29, 44, 11, 35, 20, 4, 36, 58, 32, 15, 47, 2, 36, 48, 16, 60, 8, 35, 44, 63, 16, 2, 40, 26, 55, 14, 58, 35, 24, 31, 19, 42, 31, 58, 1, 29, 10, 40, 2, 19, 12, 54, 22, 61, 7, 24, 56, 5, 28, 16, 54, 3, 15, 58, 6, 30, 8, 62, 1, 43, 31, 47, 7, 59, 1, 38, 58, 4, 34, 27, 38, 5, 31, 59, 7, 46, 30, 3, 34, 6, 28, 59, 20, 8, 32, 15, 53, 24, 55, 31, 19, 49, 11, 26 }, + { 2, 24, 16, 58, 19, 55, 5, 35, 10, 61, 4, 28, 57, 24, 58, 7, 31, 47, 22, 38, 19, 28, 61, 36, 54, 5, 59, 29, 6, 52, 15, 11, 43, 36, 8, 54, 52, 1, 62, 25, 47, 9, 1, 60, 28, 53, 24, 14, 46, 27, 51, 22, 12, 24, 38, 53, 20, 11, 51, 3, 29, 7, 48, 63, 8, 49, 9, 21, 52, 14, 63, 32, 46, 60, 35, 4, 41, 16, 52, 35, 18, 42, 59, 7, 36, 61, 45, 27, 33, 51, 19, 39, 34, 11, 61, 18, 33, 41, 28, 15, 54, 22, 42, 3, 49, 21, 47, 18, 36, 23, 55, 19, 48, 24, 45, 10, 33, 44, 50, 40, 7, 35, 15, 41, 63, 6, 40, 54 }, + { 62, 41, 32, 8, 47, 28, 60, 24, 44, 30, 38, 49, 9, 33, 14, 40, 50, 14, 60, 2, 54, 40, 0, 20, 25, 39, 16, 49, 24, 35, 57, 47, 19, 61, 33, 18, 23, 37, 13, 55, 31, 43, 22, 41, 17, 8, 42, 58, 0, 37, 5, 56, 31, 54, 7, 30, 60, 33, 42, 17, 59, 39, 12, 27, 38, 17, 35, 41, 27, 45, 20, 7, 25, 15, 29, 58, 27, 47, 11, 40, 14, 54, 23, 46, 19, 31, 11, 40, 13, 49, 5, 58, 24, 51, 26, 6, 50, 20, 49, 9, 32, 46, 17, 60, 14, 63, 24, 1, 57, 41, 9, 43, 14, 62, 16, 52, 3, 27, 14, 22, 61, 45, 4, 28, 9, 47, 29, 17 }, + { 5, 50, 12, 53, 38, 18, 11, 51, 0, 55, 17, 6, 47, 54, 19, 63, 5, 26, 34, 45, 13, 30, 47, 58, 10, 48, 32, 3, 62, 9, 26, 0, 25, 14, 50, 3, 47, 30, 42, 16, 6, 63, 12, 49, 33, 55, 21, 10, 34, 63, 18, 41, 3, 47, 19, 43, 0, 49, 8, 28, 46, 20, 52, 0, 56, 24, 60, 3, 59, 5, 39, 57, 48, 52, 9, 38, 3, 21, 26, 60, 0, 32, 12, 38, 4, 48, 53, 0, 60, 15, 29, 44, 18, 10, 38, 57, 13, 60, 2, 26, 62, 7, 50, 29, 35, 8, 40, 53, 28, 12, 60, 33, 38, 5, 37, 29, 60, 39, 56, 0, 30, 18, 50, 34, 59, 25, 14, 44 }, + { 20, 31, 60, 22, 3, 49, 33, 25, 40, 13, 34, 59, 22, 36, 0, 28, 37, 56, 8, 18, 51, 16, 4, 45, 27, 12, 53, 42, 18, 44, 51, 31, 55, 40, 28, 58, 7, 60, 10, 51, 27, 37, 24, 56, 5, 26, 44, 29, 50, 23, 45, 11, 34, 15, 59, 27, 13, 23, 62, 37, 4, 57, 15, 32, 42, 6, 47, 11, 30, 43, 23, 13, 0, 36, 18, 44, 63, 51, 37, 29, 49, 20, 57, 27, 62, 9, 24, 35, 23, 53, 37, 3, 42, 55, 0, 36, 23, 39, 31, 43, 17, 37, 24, 11, 52, 43, 19, 32, 5, 50, 26, 0, 56, 21, 54, 11, 19, 6, 47, 25, 59, 42, 12, 54, 21, 3, 38, 57 }, + { 48, 0, 35, 27, 44, 14, 59, 7, 57, 46, 26, 2, 42, 12, 52, 43, 10, 27, 53, 42, 32, 62, 37, 21, 34, 61, 7, 23, 36, 4, 38, 12, 41, 5, 17, 45, 22, 27, 39, 21, 59, 0, 45, 18, 39, 62, 3, 38, 14, 7, 54, 26, 61, 39, 9, 52, 45, 36, 18, 50, 10, 34, 44, 22, 50, 14, 36, 55, 17, 34, 53, 62, 33, 26, 56, 6, 31, 12, 6, 53, 9, 44, 2, 50, 20, 40, 55, 17, 47, 7, 26, 63, 22, 32, 48, 16, 46, 8, 52, 12, 57, 41, 0, 56, 25, 3, 61, 14, 45, 35, 18, 44, 12, 46, 23, 42, 32, 51, 35, 10, 17, 36, 23, 1, 45, 52, 32, 10 }, + { 37, 15, 43, 8, 63, 39, 21, 31, 16, 37, 19, 62, 30, 46, 17, 60, 21, 48, 1, 23, 6, 25, 11, 56, 1, 40, 30, 58, 15, 54, 21, 59, 9, 63, 35, 56, 11, 51, 2, 46, 34, 14, 53, 7, 30, 11, 51, 19, 60, 40, 30, 1, 24, 50, 20, 32, 3, 56, 5, 25, 31, 13, 61, 2, 29, 60, 25, 20, 51, 2, 27, 8, 18, 42, 10, 45, 21, 34, 43, 17, 62, 29, 41, 14, 34, 6, 30, 43, 2, 57, 33, 13, 45, 12, 27, 62, 4, 55, 21, 35, 5, 27, 45, 33, 16, 47, 30, 54, 22, 10, 51, 27, 63, 7, 49, 1, 58, 22, 15, 43, 53, 7, 57, 39, 27, 12, 61, 24 }, + { 56, 51, 26, 56, 19, 2, 41, 54, 5, 52, 9, 48, 6, 23, 39, 4, 32, 15, 63, 35, 59, 49, 43, 15, 52, 19, 50, 9, 46, 33, 1, 29, 48, 20, 32, 1, 38, 33, 19, 54, 9, 32, 24, 48, 58, 35, 16, 48, 4, 52, 13, 57, 33, 5, 45, 59, 15, 29, 41, 55, 47, 39, 23, 53, 9, 40, 4, 57, 10, 44, 48, 40, 50, 14, 61, 24, 55, 1, 59, 22, 33, 8, 51, 25, 58, 46, 11, 59, 20, 41, 17, 51, 6, 56, 35, 25, 42, 30, 15, 58, 48, 18, 61, 9, 58, 39, 13, 2, 37, 59, 40, 2, 31, 16, 34, 41, 8, 30, 62, 3, 29, 48, 33, 5, 63, 16, 41, 7 }, + { 22, 4, 46, 11, 33, 51, 29, 10, 62, 24, 43, 27, 15, 58, 50, 25, 54, 44, 9, 38, 18, 3, 29, 57, 32, 5, 26, 43, 17, 61, 24, 52, 8, 42, 23, 53, 15, 61, 7, 28, 57, 43, 4, 40, 20, 2, 43, 25, 32, 35, 21, 43, 17, 48, 10, 22, 38, 54, 11, 21, 1, 58, 16, 30, 48, 18, 46, 32, 38, 13, 22, 4, 59, 35, 2, 51, 30, 39, 15, 47, 4, 56, 13, 37, 1, 28, 16, 52, 32, 9, 61, 29, 38, 19, 3, 52, 10, 48, 1, 32, 11, 40, 20, 36, 6, 22, 49, 29, 55, 6, 20, 56, 36, 52, 19, 60, 26, 46, 18, 54, 40, 13, 20, 46, 35, 19, 49, 29 }, + { 61, 17, 34, 53, 23, 6, 48, 35, 20, 40, 1, 56, 36, 29, 11, 34, 7, 41, 14, 30, 55, 20, 46, 8, 24, 38, 63, 2, 37, 10, 45, 14, 34, 49, 6, 13, 44, 25, 49, 41, 21, 12, 61, 15, 54, 29, 63, 12, 56, 8, 49, 2, 62, 36, 28, 61, 0, 25, 41, 63, 35, 8, 44, 6, 37, 62, 7, 21, 63, 28, 55, 31, 16, 24, 41, 19, 9, 57, 27, 36, 18, 42, 31, 62, 22, 55, 38, 4, 27, 47, 1, 40, 14, 54, 43, 20, 60, 23, 38, 63, 25, 51, 2, 53, 26, 63, 10, 42, 17, 34, 47, 25, 13, 5, 44, 11, 55, 2, 38, 27, 6, 60, 52, 25, 9, 55, 1, 40 }, + { 8, 30, 58, 3, 42, 61, 17, 38, 13, 59, 32, 10, 54, 3, 51, 20, 61, 26, 57, 2, 46, 33, 12, 60, 41, 13, 48, 29, 55, 20, 39, 27, 57, 18, 62, 29, 55, 2, 31, 16, 37, 50, 26, 36, 6, 46, 9, 41, 27, 57, 23, 39, 26, 6, 51, 12, 31, 46, 7, 16, 27, 52, 19, 56, 26, 12, 33, 53, 1, 41, 8, 57, 46, 7, 54, 32, 47, 5, 49, 11, 60, 23, 5, 48, 10, 43, 19, 63, 35, 24, 49, 21, 59, 5, 31, 37, 14, 44, 7, 42, 6, 30, 46, 13, 44, 32, 19, 50, 4, 58, 8, 30, 62, 38, 28, 53, 21, 36, 13, 50, 21, 33, 15, 2, 44, 31, 14, 47 }, + { 37, 13, 39, 16, 28, 9, 57, 0, 25, 49, 21, 45, 18, 47, 12, 42, 0, 49, 22, 39, 16, 53, 25, 36, 0, 52, 22, 16, 6, 60, 4, 51, 0, 26, 37, 47, 10, 36, 63, 5, 57, 0, 18, 59, 23, 33, 51, 19, 0, 44, 15, 11, 54, 17, 42, 35, 53, 18, 58, 33, 49, 4, 34, 42, 0, 50, 43, 25, 16, 49, 34, 20, 37, 28, 12, 63, 16, 38, 25, 44, 0, 40, 52, 17, 35, 3, 50, 14, 8, 53, 11, 36, 25, 45, 9, 62, 0, 54, 28, 17, 50, 55, 15, 24, 57, 0, 53, 34, 23, 41, 15, 45, 0, 49, 16, 4, 48, 9, 63, 45, 0, 42, 58, 37, 61, 22, 54, 26 }, + { 0, 50, 21, 47, 54, 36, 27, 45, 52, 4, 34, 15, 63, 29, 37, 59, 17, 31, 6, 61, 28, 5, 48, 18, 59, 27, 34, 56, 44, 31, 35, 12, 41, 59, 16, 3, 40, 20, 50, 22, 30, 40, 52, 10, 45, 3, 59, 22, 37, 61, 29, 46, 31, 58, 2, 22, 9, 43, 3, 39, 14, 61, 24, 54, 15, 29, 11, 60, 39, 17, 5, 61, 0, 44, 50, 3, 31, 14, 58, 21, 54, 28, 15, 45, 60, 26, 33, 58, 44, 22, 60, 2, 57, 34, 49, 27, 18, 34, 21, 59, 29, 4, 36, 41, 8, 39, 28, 11, 62, 26, 53, 20, 35, 24, 59, 32, 29, 39, 24, 31, 57, 23, 11, 28, 5, 36, 11, 59 }, + { 44, 32, 63, 5, 20, 12, 41, 7, 30, 61, 42, 8, 39, 5, 33, 8, 24, 53, 45, 11, 37, 58, 7, 44, 10, 50, 3, 40, 8, 22, 53, 19, 46, 9, 33, 52, 24, 58, 8, 44, 13, 47, 8, 34, 38, 30, 14, 47, 7, 34, 4, 55, 9, 19, 40, 49, 56, 26, 60, 21, 30, 45, 10, 19, 40, 58, 23, 36, 3, 52, 45, 23, 54, 13, 22, 42, 53, 45, 7, 33, 10, 36, 57, 6, 29, 12, 41, 0, 30, 15, 41, 30, 17, 7, 16, 53, 40, 56, 2, 39, 12, 61, 10, 52, 31, 60, 16, 45, 1, 37, 7, 61, 40, 10, 43, 17, 58, 7, 54, 14, 4, 51, 39, 49, 18, 56, 42, 20 }, + { 14, 6, 24, 36, 56, 49, 22, 60, 18, 14, 23, 51, 26, 57, 21, 52, 41, 14, 35, 50, 19, 31, 40, 23, 33, 14, 63, 17, 32, 47, 7, 62, 23, 30, 56, 11, 42, 27, 14, 60, 35, 19, 28, 61, 17, 55, 25, 39, 53, 17, 42, 21, 38, 63, 25, 5, 14, 36, 12, 50, 1, 37, 59, 32, 2, 51, 6, 56, 27, 32, 11, 30, 38, 26, 60, 8, 26, 19, 62, 39, 50, 2, 21, 39, 53, 23, 56, 19, 49, 39, 5, 46, 55, 23, 42, 4, 31, 11, 47, 26, 45, 22, 48, 18, 21, 5, 48, 25, 57, 14, 47, 30, 3, 56, 12, 50, 1, 42, 19, 47, 35, 17, 8, 30, 45, 25, 4, 51 }, + { 28, 58, 43, 1, 31, 8, 33, 2, 44, 55, 32, 1, 60, 12, 46, 27, 4, 62, 23, 1, 56, 13, 62, 2, 54, 36, 25, 51, 1, 57, 26, 42, 3, 49, 17, 38, 1, 48, 31, 4, 54, 3, 50, 24, 1, 49, 5, 63, 13, 27, 52, 1, 48, 13, 45, 33, 52, 30, 46, 20, 55, 28, 6, 48, 24, 38, 20, 47, 14, 62, 48, 9, 58, 4, 36, 30, 56, 1, 34, 12, 18, 63, 25, 48, 4, 16, 37, 7, 62, 10, 52, 28, 13, 50, 36, 63, 24, 51, 15, 58, 8, 33, 1, 38, 56, 35, 42, 9, 33, 51, 22, 18, 48, 32, 27, 37, 23, 61, 33, 11, 59, 29, 62, 1, 53, 10, 60, 33 }, + { 12, 39, 17, 52, 26, 46, 53, 38, 25, 11, 48, 36, 16, 43, 2, 35, 55, 17, 39, 29, 43, 9, 28, 45, 20, 5, 46, 12, 42, 28, 13, 52, 36, 6, 60, 22, 54, 17, 62, 39, 25, 42, 15, 55, 44, 20, 31, 10, 35, 57, 24, 32, 29, 6, 59, 18, 7, 62, 3, 41, 10, 44, 16, 54, 13, 62, 31, 9, 41, 1, 21, 43, 18, 47, 15, 40, 11, 49, 28, 55, 46, 30, 8, 43, 32, 61, 28, 47, 25, 34, 21, 61, 32, 1, 20, 9, 46, 6, 35, 19, 41, 54, 27, 63, 14, 3, 51, 20, 62, 2, 38, 55, 8, 21, 63, 6, 46, 9, 26, 51, 3, 24, 43, 34, 16, 41, 18, 48 }, + { 62, 23, 55, 9, 15, 62, 19, 13, 58, 40, 6, 30, 54, 19, 50, 31, 10, 44, 6, 59, 21, 47, 51, 15, 60, 39, 30, 54, 21, 61, 19, 33, 14, 29, 43, 11, 34, 45, 7, 21, 10, 56, 36, 6, 38, 11, 58, 42, 2, 47, 11, 60, 50, 16, 41, 28, 38, 23, 47, 17, 35, 63, 22, 33, 42, 5, 45, 17, 53, 35, 25, 56, 33, 6, 51, 19, 60, 23, 43, 15, 5, 40, 58, 13, 51, 1, 45, 11, 54, 3, 43, 8, 37, 48, 59, 29, 39, 21, 61, 43, 3, 31, 10, 44, 24, 29, 60, 12, 28, 40, 11, 25, 43, 52, 14, 41, 16, 57, 44, 20, 40, 55, 12, 21, 57, 27, 35, 2 }, + { 37, 6, 31, 42, 40, 4, 29, 50, 0, 20, 63, 28, 9, 58, 14, 24, 63, 26, 48, 16, 34, 4, 32, 38, 23, 11, 58, 4, 37, 9, 45, 5, 63, 48, 26, 57, 2, 28, 32, 51, 46, 29, 13, 62, 27, 46, 28, 18, 50, 15, 40, 4, 19, 34, 54, 0, 53, 9, 26, 58, 28, 5, 49, 0, 57, 27, 19, 60, 29, 8, 59, 12, 37, 63, 24, 46, 3, 37, 6, 52, 26, 32, 20, 36, 9, 22, 59, 18, 35, 51, 14, 57, 17, 24, 12, 44, 56, 0, 30, 13, 59, 20, 49, 17, 54, 43, 6, 34, 46, 17, 58, 36, 0, 34, 29, 54, 25, 2, 36, 15, 60, 6, 37, 46, 4, 50, 9, 45 }, + { 19, 59, 48, 3, 24, 60, 44, 22, 34, 51, 15, 45, 41, 5, 33, 47, 0, 37, 12, 55, 25, 54, 8, 57, 0, 47, 18, 34, 49, 15, 55, 24, 40, 20, 8, 35, 53, 13, 41, 18, 0, 59, 22, 33, 4, 52, 8, 60, 24, 36, 31, 56, 45, 26, 10, 43, 15, 56, 36, 4, 51, 14, 39, 30, 12, 55, 36, 2, 39, 49, 4, 44, 17, 0, 32, 13, 53, 35, 59, 17, 62, 0, 55, 24, 52, 38, 31, 6, 42, 19, 29, 40, 4, 54, 33, 5, 16, 27, 52, 37, 23, 55, 7, 37, 0, 39, 23, 49, 4, 53, 31, 15, 59, 10, 50, 4, 60, 34, 48, 7, 31, 49, 27, 14, 62, 22, 53, 29 }, + { 46, 21, 14, 51, 36, 17, 7, 57, 10, 32, 3, 37, 22, 60, 39, 18, 56, 20, 42, 3, 36, 10, 44, 26, 41, 29, 53, 27, 2, 39, 30, 52, 0, 59, 15, 48, 23, 61, 6, 58, 37, 12, 40, 49, 16, 39, 20, 44, 0, 62, 8, 21, 3, 59, 23, 32, 49, 31, 12, 44, 22, 59, 18, 50, 24, 7, 43, 52, 15, 23, 41, 26, 51, 28, 55, 39, 21, 27, 10, 42, 12, 45, 27, 47, 3, 15, 63, 26, 55, 0, 60, 26, 45, 18, 62, 38, 58, 49, 8, 47, 4, 33, 46, 29, 57, 13, 56, 16, 59, 21, 5, 47, 23, 39, 18, 44, 13, 22, 28, 53, 19, 0, 58, 32, 41, 7, 26, 13 }, + { 0, 56, 34, 28, 11, 55, 31, 47, 26, 41, 56, 13, 53, 28, 11, 49, 7, 52, 32, 61, 50, 22, 63, 17, 13, 56, 7, 19, 43, 62, 10, 21, 37, 32, 43, 4, 38, 19, 44, 25, 31, 54, 5, 23, 61, 30, 53, 12, 35, 22, 43, 53, 37, 48, 7, 62, 20, 2, 61, 41, 8, 34, 47, 9, 63, 34, 28, 10, 55, 33, 14, 57, 7, 47, 9, 61, 4, 49, 31, 50, 21, 38, 8, 16, 57, 44, 33, 5, 49, 36, 12, 50, 7, 34, 10, 25, 2, 22, 36, 15, 26, 61, 18, 9, 22, 46, 32, 8, 27, 37, 44, 30, 55, 3, 62, 24, 38, 56, 5, 45, 38, 24, 43, 10, 19, 54, 39, 61 }, + { 41, 30, 8, 63, 43, 23, 38, 3, 62, 19, 8, 49, 25, 1, 58, 30, 23, 40, 9, 28, 18, 40, 6, 38, 49, 22, 35, 59, 8, 27, 50, 5, 56, 17, 11, 50, 30, 9, 55, 2, 51, 19, 34, 47, 9, 41, 6, 26, 48, 57, 14, 28, 17, 12, 39, 13, 37, 46, 25, 19, 54, 27, 1, 37, 16, 45, 20, 60, 1, 48, 20, 38, 31, 22, 42, 15, 19, 44, 1, 61, 6, 34, 56, 40, 29, 10, 20, 46, 13, 22, 41, 23, 59, 42, 30, 51, 45, 13, 63, 53, 42, 12, 51, 38, 62, 2, 26, 41, 50, 1, 61, 10, 19, 42, 31, 8, 49, 32, 12, 63, 9, 52, 16, 56, 36, 2, 31, 16 }, + { 52, 5, 47, 20, 1, 53, 12, 50, 16, 35, 43, 21, 33, 43, 16, 44, 3, 59, 14, 46, 1, 30, 60, 33, 2, 45, 12, 42, 31, 47, 14, 33, 46, 25, 55, 27, 60, 36, 16, 42, 14, 46, 26, 1, 55, 15, 63, 32, 2, 38, 5, 47, 33, 61, 30, 52, 4, 57, 6, 38, 11, 43, 61, 24, 52, 3, 31, 22, 42, 10, 62, 3, 59, 11, 35, 57, 33, 54, 24, 14, 29, 48, 18, 2, 60, 41, 53, 24, 32, 62, 3, 53, 15, 1, 55, 17, 32, 40, 6, 31, 1, 40, 28, 5, 35, 52, 19, 63, 13, 33, 17, 41, 52, 26, 15, 57, 1, 20, 42, 17, 35, 27, 48, 5, 25, 50, 44, 11 }, + { 35, 25, 38, 57, 33, 17, 40, 6, 59, 27, 54, 5, 61, 10, 52, 26, 36, 19, 51, 35, 57, 48, 11, 20, 54, 25, 61, 16, 1, 58, 24, 61, 3, 39, 7, 47, 1, 22, 49, 28, 63, 10, 58, 32, 17, 36, 45, 19, 51, 29, 59, 10, 50, 1, 23, 42, 18, 29, 51, 21, 56, 32, 14, 5, 40, 58, 47, 13, 54, 35, 29, 45, 18, 52, 26, 2, 38, 8, 46, 36, 58, 11, 52, 35, 17, 28, 1, 58, 9, 39, 17, 28, 37, 48, 20, 9, 57, 24, 50, 19, 58, 16, 48, 25, 43, 11, 35, 6, 45, 24, 56, 4, 36, 7, 47, 35, 52, 28, 59, 30, 2, 61, 21, 33, 63, 12, 18, 59 }, + { 3, 49, 15, 10, 27, 61, 25, 45, 30, 0, 14, 47, 31, 38, 17, 62, 7, 55, 27, 4, 15, 24, 42, 52, 10, 34, 5, 51, 36, 18, 41, 11, 35, 21, 62, 13, 33, 57, 8, 35, 5, 40, 21, 43, 52, 3, 24, 56, 11, 16, 33, 25, 41, 20, 55, 8, 60, 35, 15, 48, 2, 57, 30, 49, 18, 25, 6, 39, 17, 57, 7, 25, 43, 5, 49, 16, 62, 22, 55, 4, 25, 43, 23, 7, 50, 11, 37, 48, 14, 51, 33, 57, 7, 27, 39, 46, 4, 29, 11, 43, 34, 56, 7, 60, 20, 54, 30, 57, 22, 49, 9, 33, 54, 14, 63, 23, 6, 43, 10, 40, 50, 13, 44, 8, 38, 33, 46, 23 }, + { 55, 39, 22, 50, 44, 4, 36, 9, 52, 23, 37, 59, 21, 2, 46, 13, 31, 41, 11, 45, 62, 29, 6, 37, 19, 48, 30, 23, 44, 7, 53, 28, 54, 16, 41, 29, 44, 18, 52, 24, 60, 15, 48, 7, 27, 59, 9, 34, 42, 54, 7, 63, 4, 46, 31, 27, 45, 0, 40, 26, 34, 17, 37, 10, 53, 29, 36, 50, 2, 27, 51, 11, 61, 37, 23, 41, 30, 7, 18, 50, 39, 14, 63, 32, 45, 61, 19, 30, 25, 44, 2, 47, 23, 63, 11, 34, 59, 37, 60, 3, 22, 14, 44, 30, 15, 0, 47, 15, 3, 38, 61, 20, 27, 45, 11, 39, 51, 16, 55, 3, 22, 54, 29, 58, 1, 57, 6, 29 }, + { 9, 17, 60, 2, 34, 56, 20, 62, 39, 12, 49, 6, 29, 56, 34, 48, 0, 58, 22, 38, 18, 43, 56, 0, 63, 14, 55, 3, 59, 31, 15, 45, 0, 49, 6, 58, 3, 38, 12, 45, 0, 37, 29, 57, 13, 39, 30, 49, 0, 23, 44, 36, 16, 57, 13, 54, 11, 24, 63, 9, 53, 7, 62, 42, 0, 59, 15, 23, 63, 34, 40, 16, 32, 0, 53, 12, 48, 28, 59, 33, 0, 53, 9, 27, 3, 22, 54, 5, 56, 9, 61, 13, 42, 14, 52, 19, 0, 21, 47, 27, 53, 36, 3, 50, 39, 58, 25, 40, 53, 28, 12, 50, 0, 59, 32, 2, 21, 34, 26, 46, 37, 7, 18, 47, 24, 14, 53, 42 }, + { 61, 32, 13, 54, 29, 7, 46, 13, 28, 57, 18, 41, 53, 15, 9, 39, 24, 49, 33, 3, 53, 9, 26, 32, 40, 28, 46, 39, 25, 9, 56, 21, 63, 37, 26, 22, 51, 27, 17, 56, 31, 53, 4, 43, 22, 46, 12, 18, 60, 40, 20, 26, 50, 21, 39, 5, 49, 33, 16, 44, 22, 46, 20, 32, 24, 45, 8, 43, 12, 46, 4, 48, 56, 20, 29, 58, 3, 40, 10, 42, 31, 21, 47, 41, 56, 38, 15, 42, 36, 27, 20, 33, 55, 3, 26, 44, 31, 54, 12, 35, 9, 63, 28, 10, 21, 32, 9, 60, 17, 8, 43, 29, 40, 16, 36, 48, 60, 7, 57, 14, 62, 31, 42, 15, 36, 40, 20, 26 }, + { 0, 37, 47, 23, 41, 18, 32, 48, 1, 35, 8, 25, 4, 26, 63, 20, 54, 8, 16, 61, 35, 23, 51, 15, 58, 7, 12, 20, 50, 34, 42, 4, 38, 10, 32, 47, 8, 60, 41, 20, 9, 25, 50, 19, 62, 1, 37, 56, 28, 8, 53, 11, 3, 58, 34, 43, 19, 60, 38, 4, 58, 31, 3, 51, 11, 55, 38, 30, 21, 58, 19, 26, 9, 44, 36, 13, 46, 20, 62, 24, 13, 60, 5, 28, 12, 34, 7, 59, 0, 53, 45, 6, 38, 30, 50, 7, 62, 16, 41, 5, 46, 18, 55, 42, 51, 5, 45, 23, 34, 48, 19, 58, 5, 25, 54, 19, 13, 41, 28, 21, 0, 49, 10, 60, 4, 51, 9, 45 }, + { 19, 28, 6, 58, 10, 51, 4, 22, 55, 42, 60, 45, 34, 51, 42, 5, 30, 45, 27, 40, 13, 47, 4, 49, 21, 38, 60, 29, 2, 57, 17, 27, 52, 19, 61, 14, 30, 34, 2, 44, 63, 33, 11, 35, 16, 51, 25, 6, 14, 47, 31, 61, 37, 29, 18, 8, 52, 2, 28, 54, 13, 41, 15, 62, 35, 18, 2, 60, 6, 33, 41, 61, 31, 6, 56, 17, 34, 50, 6, 52, 44, 35, 16, 51, 59, 24, 48, 18, 31, 40, 16, 49, 21, 60, 17, 39, 10, 49, 32, 57, 24, 39, 1, 25, 18, 62, 37, 12, 56, 1, 37, 11, 52, 44, 9, 30, 47, 4, 51, 40, 55, 25, 34, 27, 56, 30, 32, 54 }, + { 63, 40, 49, 15, 43, 26, 63, 38, 16, 20, 30, 12, 57, 14, 19, 60, 36, 12, 59, 2, 57, 17, 42, 31, 1, 44, 16, 35, 47, 11, 32, 48, 13, 43, 1, 39, 51, 12, 57, 23, 6, 40, 53, 3, 55, 31, 39, 60, 35, 44, 5, 15, 45, 1, 62, 41, 26, 14, 47, 22, 36, 27, 50, 9, 26, 47, 52, 28, 54, 16, 1, 13, 51, 39, 23, 63, 1, 30, 15, 26, 2, 57, 19, 37, 1, 44, 21, 50, 13, 63, 8, 24, 56, 1, 35, 25, 58, 20, 2, 28, 14, 51, 33, 59, 13, 30, 4, 49, 31, 24, 63, 26, 33, 3, 58, 38, 62, 24, 32, 8, 17, 45, 5, 48, 18, 3, 43, 11 }, + { 21, 4, 24, 34, 59, 1, 37, 11, 53, 5, 47, 2, 22, 40, 32, 1, 24, 50, 21, 29, 38, 25, 63, 8, 55, 24, 53, 6, 62, 23, 59, 3, 54, 20, 58, 24, 5, 46, 15, 38, 48, 14, 27, 42, 23, 7, 46, 10, 17, 58, 25, 52, 23, 32, 49, 12, 55, 30, 40, 7, 59, 1, 56, 21, 39, 4, 23, 15, 37, 46, 55, 42, 21, 4, 48, 8, 45, 54, 37, 55, 32, 8, 46, 10, 30, 54, 4, 41, 25, 29, 36, 48, 11, 43, 14, 47, 5, 43, 53, 36, 61, 10, 45, 6, 41, 54, 27, 43, 16, 55, 6, 46, 18, 42, 23, 15, 1, 45, 12, 60, 37, 22, 62, 12, 39, 59, 16, 52 }, + { 47, 35, 56, 7, 19, 46, 31, 50, 33, 24, 61, 35, 50, 7, 53, 44, 55, 6, 46, 10, 52, 5, 21, 43, 36, 10, 18, 41, 26, 37, 8, 29, 40, 36, 9, 49, 34, 26, 61, 21, 7, 59, 18, 62, 29, 54, 20, 32, 51, 0, 40, 10, 55, 6, 20, 36, 9, 61, 5, 51, 44, 19, 33, 43, 13, 57, 40, 63, 8, 24, 29, 10, 60, 34, 27, 40, 25, 18, 10, 42, 21, 49, 26, 62, 38, 12, 33, 61, 5, 57, 2, 19, 54, 28, 62, 22, 38, 31, 16, 7, 22, 47, 29, 17, 35, 8, 20, 51, 2, 40, 22, 50, 13, 61, 28, 53, 35, 20, 56, 30, 2, 53, 14, 41, 23, 34, 8, 31 }, + { 12, 2, 42, 29, 52, 13, 21, 8, 55, 14, 41, 17, 28, 58, 23, 11, 17, 36, 31, 62, 17, 34, 50, 14, 28, 61, 33, 52, 2, 51, 17, 45, 7, 25, 62, 30, 18, 55, 0, 42, 30, 35, 45, 1, 12, 48, 3, 63, 21, 36, 30, 48, 19, 59, 43, 27, 46, 17, 34, 25, 12, 29, 53, 6, 48, 31, 11, 34, 49, 3, 36, 50, 19, 47, 14, 61, 11, 36, 58, 4, 60, 14, 39, 22, 6, 52, 15, 35, 17, 46, 31, 42, 9, 34, 3, 52, 12, 60, 26, 56, 40, 2, 53, 23, 57, 38, 62, 14, 36, 59, 10, 31, 39, 6, 49, 9, 41, 26, 5, 48, 43, 27, 33, 58, 1, 50, 25, 57 }, + { 61, 37, 15, 61, 3, 39, 58, 43, 26, 0, 44, 10, 47, 3, 37, 63, 28, 43, 13, 39, 3, 57, 30, 59, 0, 48, 5, 43, 13, 22, 60, 33, 55, 15, 42, 4, 52, 10, 45, 13, 54, 4, 24, 49, 37, 26, 41, 14, 42, 9, 61, 13, 38, 23, 3, 53, 0, 58, 21, 42, 63, 10, 17, 61, 25, 0, 58, 28, 17, 44, 57, 12, 27, 0, 55, 5, 52, 28, 23, 47, 29, 0, 43, 17, 58, 28, 47, 23, 55, 10, 58, 23, 51, 40, 18, 33, 45, 0, 49, 8, 32, 61, 19, 48, 0, 26, 7, 47, 29, 18, 44, 0, 56, 34, 20, 59, 15, 51, 37, 18, 10, 52, 7, 20, 46, 9, 38, 17 }, + { 6, 27, 48, 23, 45, 29, 5, 18, 38, 62, 27, 56, 20, 32, 15, 9, 48, 0, 54, 22, 45, 20, 7, 41, 23, 39, 19, 27, 58, 31, 44, 0, 12, 50, 23, 56, 20, 39, 32, 59, 16, 52, 33, 9, 57, 22, 6, 58, 28, 50, 24, 2, 56, 35, 16, 45, 32, 38, 15, 54, 2, 38, 46, 22, 35, 45, 20, 5, 52, 25, 7, 35, 59, 32, 22, 43, 38, 3, 51, 16, 34, 53, 32, 50, 3, 40, 8, 43, 0, 39, 27, 4, 14, 61, 8, 55, 15, 41, 20, 44, 27, 13, 39, 11, 46, 42, 54, 33, 4, 52, 23, 61, 14, 25, 43, 2, 33, 11, 63, 29, 61, 17, 40, 55, 22, 62, 28, 44 }, + { 20, 54, 8, 56, 35, 10, 63, 31, 52, 12, 48, 6, 59, 41, 52, 33, 19, 58, 25, 49, 11, 37, 47, 12, 54, 15, 56, 35, 7, 47, 16, 53, 28, 34, 5, 37, 28, 8, 48, 3, 28, 38, 18, 61, 16, 43, 53, 32, 4, 17, 47, 27, 44, 8, 63, 10, 25, 49, 6, 37, 24, 52, 32, 3, 50, 12, 41, 56, 38, 14, 62, 20, 40, 16, 53, 31, 18, 63, 41, 9, 59, 7, 13, 25, 57, 20, 63, 26, 53, 18, 48, 62, 30, 46, 21, 25, 58, 29, 36, 4, 55, 34, 6, 60, 31, 16, 21, 12, 58, 38, 9, 29, 47, 7, 52, 30, 57, 44, 22, 0, 35, 45, 3, 31, 14, 36, 0, 51 }, + { 42, 14, 33, 24, 16, 49, 40, 2, 22, 33, 16, 36, 25, 1, 21, 61, 38, 8, 33, 4, 62, 26, 29, 60, 6, 46, 30, 11, 63, 4, 36, 40, 19, 57, 46, 11, 41, 63, 22, 25, 58, 10, 46, 2, 34, 27, 11, 38, 56, 34, 12, 53, 18, 33, 41, 51, 13, 28, 60, 20, 47, 14, 29, 59, 16, 62, 8, 22, 32, 47, 9, 49, 2, 44, 7, 12, 45, 6, 20, 27, 45, 24, 62, 42, 36, 11, 33, 15, 37, 7, 32, 10, 37, 1, 35, 50, 6, 11, 63, 24, 52, 15, 50, 24, 3, 37, 56, 27, 34, 22, 49, 16, 36, 62, 17, 39, 4, 15, 54, 24, 50, 8, 58, 26, 49, 54, 11, 30 }, + { 4, 59, 41, 1, 53, 12, 25, 45, 59, 7, 51, 39, 54, 14, 46, 4, 27, 53, 16, 44, 18, 51, 1, 32, 25, 2, 50, 40, 20, 54, 24, 9, 62, 2, 27, 60, 1, 17, 36, 50, 6, 40, 30, 55, 41, 19, 49, 1, 21, 60, 40, 5, 62, 1, 22, 30, 57, 4, 43, 31, 1, 55, 40, 7, 27, 37, 30, 54, 1, 19, 42, 30, 56, 26, 62, 49, 24, 57, 37, 56, 2, 39, 16, 5, 30, 55, 3, 49, 60, 23, 56, 44, 17, 52, 13, 42, 28, 48, 18, 45, 9, 37, 21, 41, 58, 10, 48, 1, 63, 5, 41, 57, 2, 24, 12, 48, 27, 42, 32, 46, 13, 38, 19, 34, 5, 41, 25, 60 }, + { 39, 28, 21, 46, 32, 57, 36, 9, 19, 42, 4, 29, 11, 43, 30, 49, 13, 42, 35, 56, 9, 39, 15, 52, 36, 61, 18, 26, 45, 14, 31, 48, 21, 43, 14, 33, 49, 54, 14, 44, 21, 62, 13, 23, 8, 62, 15, 51, 44, 7, 30, 37, 20, 42, 56, 7, 39, 18, 50, 11, 61, 9, 19, 43, 57, 2, 48, 11, 39, 60, 28, 4, 37, 17, 35, 1, 33, 11, 31, 14, 48, 19, 35, 51, 46, 21, 44, 29, 12, 41, 2, 22, 58, 26, 54, 4, 59, 38, 2, 33, 57, 1, 63, 13, 28, 51, 15, 40, 18, 45, 8, 30, 43, 37, 54, 19, 8, 59, 21, 6, 60, 29, 55, 10, 63, 15, 47, 17 }, + { 3, 50, 10, 62, 18, 5, 27, 49, 60, 23, 55, 18, 62, 24, 56, 10, 59, 28, 2, 23, 34, 59, 43, 20, 10, 42, 8, 49, 1, 37, 57, 6, 51, 29, 53, 7, 23, 31, 5, 32, 51, 0, 35, 54, 45, 31, 5, 26, 36, 24, 55, 15, 48, 29, 14, 48, 26, 60, 21, 41, 36, 26, 50, 33, 14, 44, 17, 24, 52, 15, 46, 23, 54, 6, 47, 21, 60, 50, 4, 53, 29, 61, 8, 23, 1, 60, 19, 6, 53, 16, 47, 34, 6, 39, 16, 31, 12, 20, 53, 22, 30, 43, 25, 46, 35, 6, 44, 32, 53, 26, 55, 19, 11, 59, 5, 33, 51, 1, 35, 53, 25, 3, 42, 23, 44, 32, 7, 53 }, + { 22, 44, 37, 6, 26, 51, 38, 0, 34, 13, 31, 46, 3, 37, 6, 19, 40, 21, 47, 63, 12, 5, 29, 55, 22, 58, 34, 28, 60, 22, 11, 41, 17, 38, 9, 44, 59, 39, 56, 19, 11, 47, 25, 15, 3, 39, 57, 17, 61, 11, 46, 3, 58, 9, 54, 35, 2, 34, 8, 45, 15, 56, 5, 23, 53, 33, 63, 35, 4, 59, 10, 51, 13, 61, 29, 41, 15, 25, 43, 19, 40, 10, 54, 33, 41, 12, 38, 51, 31, 26, 61, 9, 30, 45, 24, 62, 49, 40, 10, 61, 14, 49, 5, 17, 54, 20, 60, 23, 3, 13, 35, 50, 32, 23, 46, 27, 38, 63, 16, 12, 39, 48, 18, 51, 1, 27, 56, 35 }, + { 63, 15, 30, 55, 43, 14, 57, 17, 53, 44, 7, 48, 26, 50, 32, 60, 0, 53, 14, 31, 50, 24, 46, 0, 38, 13, 4, 52, 16, 45, 30, 59, 0, 25, 55, 35, 16, 10, 26, 42, 58, 29, 60, 38, 50, 22, 28, 47, 0, 50, 28, 19, 33, 39, 11, 44, 16, 52, 24, 59, 3, 38, 27, 51, 0, 21, 7, 42, 26, 34, 21, 40, 33, 18, 39, 3, 54, 38, 8, 59, 0, 44, 27, 15, 58, 28, 57, 9, 43, 0, 36, 50, 20, 59, 8, 34, 0, 27, 47, 7, 36, 19, 56, 32, 0, 38, 11, 29, 62, 47, 6, 61, 0, 41, 14, 56, 10, 23, 45, 31, 57, 8, 36, 13, 58, 38, 11, 19 }, + { 0, 34, 12, 47, 21, 2, 40, 30, 11, 25, 61, 20, 40, 15, 35, 22, 45, 36, 7, 41, 17, 57, 9, 48, 32, 62, 44, 24, 35, 3, 54, 13, 33, 63, 19, 4, 48, 22, 62, 2, 37, 8, 33, 6, 20, 52, 9, 32, 43, 13, 39, 63, 25, 4, 49, 23, 62, 32, 9, 30, 48, 18, 63, 12, 46, 29, 58, 13, 48, 8, 57, 31, 0, 51, 9, 58, 12, 22, 47, 29, 35, 22, 49, 5, 46, 4, 34, 20, 63, 24, 56, 11, 41, 3, 51, 19, 56, 35, 17, 58, 28, 42, 9, 45, 59, 26, 51, 42, 17, 36, 25, 15, 53, 21, 44, 3, 30, 55, 5, 50, 21, 28, 61, 32, 6, 49, 28, 46 }, + { 58, 42, 60, 4, 31, 59, 22, 63, 35, 38, 9, 54, 1, 57, 8, 51, 16, 58, 27, 53, 3, 38, 30, 15, 27, 6, 19, 56, 10, 50, 21, 36, 47, 5, 43, 28, 51, 32, 13, 46, 18, 54, 16, 43, 63, 12, 36, 59, 22, 34, 5, 52, 17, 59, 27, 41, 0, 19, 55, 37, 13, 43, 6, 34, 41, 10, 36, 55, 19, 44, 3, 16, 58, 27, 49, 25, 32, 62, 17, 55, 13, 63, 18, 52, 25, 37, 17, 48, 13, 32, 5, 46, 28, 37, 14, 43, 25, 5, 51, 39, 3, 52, 33, 22, 8, 40, 12, 4, 57, 9, 46, 39, 28, 58, 13, 62, 17, 42, 19, 36, 0, 47, 16, 43, 24, 21, 54, 13 }, + { 25, 9, 23, 50, 36, 8, 45, 14, 3, 51, 16, 28, 44, 12, 42, 29, 4, 26, 10, 47, 22, 61, 18, 54, 51, 39, 46, 13, 41, 26, 58, 7, 18, 39, 12, 57, 15, 1, 52, 27, 41, 23, 48, 1, 27, 45, 18, 2, 57, 26, 55, 8, 43, 31, 6, 58, 14, 51, 40, 5, 61, 31, 24, 54, 17, 60, 22, 1, 39, 30, 53, 45, 36, 13, 43, 5, 45, 2, 37, 6, 34, 42, 2, 39, 10, 62, 7, 54, 40, 18, 60, 15, 52, 21, 63, 8, 55, 46, 15, 30, 23, 13, 62, 16, 50, 24, 58, 31, 48, 21, 34, 2, 49, 7, 31, 37, 26, 48, 9, 61, 40, 11, 52, 2, 60, 40, 4, 37 }, + { 52, 28, 39, 16, 54, 19, 29, 55, 42, 20, 58, 33, 24, 63, 18, 55, 39, 62, 43, 34, 12, 40, 6, 35, 2, 25, 8, 62, 34, 1, 31, 42, 61, 27, 53, 24, 40, 61, 34, 8, 59, 4, 30, 56, 40, 6, 53, 42, 10, 48, 16, 37, 12, 46, 21, 36, 47, 11, 28, 45, 22, 10, 57, 2, 49, 31, 14, 44, 61, 11, 25, 6, 23, 63, 18, 36, 28, 56, 20, 51, 11, 48, 27, 56, 32, 22, 45, 30, 2, 42, 27, 39, 1, 44, 23, 31, 38, 22, 11, 61, 43, 54, 4, 47, 35, 2, 44, 16, 28, 54, 12, 62, 18, 43, 10, 52, 1, 58, 33, 15, 29, 56, 20, 34, 9, 30, 48, 17 }, + { 46, 2, 56, 11, 41, 1, 49, 6, 27, 47, 2, 48, 5, 32, 37, 3, 13, 19, 32, 1, 55, 28, 60, 17, 43, 59, 32, 20, 49, 16, 55, 23, 14, 46, 2, 36, 6, 30, 20, 49, 12, 47, 35, 14, 21, 60, 29, 14, 35, 24, 46, 1, 56, 29, 53, 8, 33, 23, 56, 1, 35, 46, 20, 39, 26, 4, 53, 28, 17, 38, 60, 34, 48, 9, 55, 15, 46, 7, 41, 31, 60, 24, 16, 36, 1, 59, 19, 52, 35, 6, 55, 11, 59, 33, 7, 57, 4, 29, 48, 1, 19, 26, 37, 30, 18, 63, 37, 6, 59, 1, 40, 24, 56, 33, 46, 22, 35, 7, 24, 53, 39, 5, 26, 45, 55, 18, 62, 7 }, + { 20, 60, 29, 34, 20, 62, 33, 52, 10, 36, 13, 60, 41, 21, 50, 27, 56, 49, 8, 51, 21, 45, 11, 48, 8, 23, 53, 3, 29, 44, 5, 52, 9, 32, 50, 17, 43, 56, 3, 38, 24, 10, 62, 25, 51, 9, 33, 49, 61, 7, 30, 62, 22, 19, 2, 42, 63, 5, 49, 18, 60, 15, 52, 7, 43, 56, 23, 50, 5, 50, 2, 20, 41, 30, 1, 52, 22, 61, 14, 26, 3, 43, 53, 7, 47, 28, 11, 14, 23, 58, 33, 25, 47, 13, 50, 17, 40, 54, 34, 60, 41, 6, 59, 14, 50, 7, 25, 55, 20, 42, 51, 8, 27, 4, 16, 60, 28, 50, 44, 3, 22, 49, 63, 12, 33, 1, 43, 31 }, + { 36, 5, 46, 8, 44, 24, 13, 39, 25, 57, 31, 18, 8, 52, 10, 45, 6, 30, 36, 24, 63, 4, 33, 26, 57, 40, 15, 56, 37, 12, 40, 25, 37, 58, 11, 63, 21, 45, 16, 60, 31, 53, 18, 33, 3, 45, 23, 0, 20, 54, 40, 15, 50, 38, 60, 16, 25, 42, 29, 38, 7, 41, 25, 62, 18, 33, 8, 35, 42, 16, 32, 56, 12, 39, 59, 19, 34, 9, 49, 38, 57, 12, 21, 50, 14, 40, 61, 44, 50, 9, 49, 19, 3, 29, 35, 62, 12, 24, 7, 18, 52, 32, 10, 46, 21, 41, 32, 11, 36, 29, 14, 34, 60, 38, 54, 11, 41, 14, 19, 57, 32, 16, 7, 41, 51, 25, 14, 57 }, + { 53, 18, 26, 50, 15, 58, 4, 63, 17, 43, 7, 40, 61, 35, 15, 41, 23, 60, 16, 38, 14, 42, 19, 50, 0, 31, 10, 46, 27, 63, 18, 60, 0, 20, 29, 39, 8, 26, 37, 5, 42, 0, 44, 39, 57, 17, 58, 41, 28, 37, 4, 32, 9, 44, 12, 31, 54, 10, 59, 14, 27, 53, 12, 36, 0, 47, 13, 63, 21, 58, 10, 24, 50, 27, 4, 26, 44, 53, 31, 0, 18, 42, 29, 33, 57, 4, 32, 26, 0, 38, 16, 61, 41, 53, 20, 0, 42, 44, 49, 27, 10, 56, 39, 0, 57, 15, 53, 49, 3, 61, 22, 47, 17, 5, 49, 26, 2, 63, 39, 10, 47, 27, 37, 23, 4, 59, 38, 10 }, + { 23, 39, 61, 3, 37, 28, 48, 31, 0, 34, 51, 23, 2, 26, 58, 0, 53, 11, 46, 1, 57, 29, 52, 14, 37, 61, 21, 35, 2, 49, 7, 34, 47, 55, 4, 33, 54, 13, 58, 52, 19, 50, 22, 7, 13, 29, 36, 11, 51, 17, 60, 25, 55, 4, 34, 51, 0, 35, 20, 48, 32, 3, 51, 30, 59, 28, 40, 3, 46, 29, 54, 43, 7, 62, 47, 11, 39, 4, 23, 46, 55, 8, 63, 5, 25, 37, 18, 46, 21, 56, 31, 5, 36, 8, 45, 58, 26, 15, 2, 36, 47, 21, 29, 44, 25, 34, 3, 27, 43, 10, 52, 0, 45, 30, 24, 36, 43, 18, 34, 59, 0, 52, 61, 15, 44, 19, 30, 49 }, + { 0, 27, 12, 43, 54, 9, 22, 53, 21, 46, 15, 55, 29, 47, 20, 33, 39, 28, 59, 35, 9, 44, 5, 24, 47, 7, 52, 17, 56, 22, 30, 42, 14, 26, 45, 18, 49, 1, 24, 34, 11, 27, 55, 32, 61, 47, 2, 56, 6, 44, 13, 47, 36, 27, 58, 22, 16, 47, 40, 4, 57, 38, 21, 45, 16, 9, 56, 26, 11, 38, 0, 22, 36, 17, 33, 57, 16, 30, 62, 15, 35, 40, 20, 45, 59, 10, 54, 8, 63, 13, 52, 27, 22, 57, 28, 12, 32, 51, 55, 22, 63, 4, 16, 54, 12, 62, 45, 19, 58, 13, 32, 40, 20, 56, 7, 57, 9, 54, 6, 29, 42, 21, 8, 55, 35, 47, 6, 41 }, + { 56, 33, 58, 32, 19, 35, 42, 6, 59, 11, 38, 5, 49, 12, 62, 7, 52, 17, 5, 25, 54, 20, 61, 31, 54, 27, 41, 11, 44, 5, 59, 12, 36, 51, 10, 61, 28, 41, 48, 9, 43, 63, 5, 40, 20, 8, 49, 26, 34, 21, 58, 1, 18, 45, 7, 39, 61, 26, 8, 50, 23, 10, 63, 5, 55, 37, 19, 49, 52, 15, 59, 47, 13, 54, 1, 25, 42, 58, 10, 48, 3, 27, 50, 1, 17, 48, 34, 41, 16, 40, 2, 45, 10, 39, 17, 61, 5, 38, 19, 9, 41, 31, 60, 38, 5, 23, 36, 8, 30, 55, 24, 63, 12, 48, 14, 51, 31, 20, 45, 25, 12, 50, 32, 2, 28, 11, 62, 14 }, + { 44, 16, 7, 48, 1, 62, 16, 50, 27, 33, 61, 25, 17, 44, 31, 14, 22, 43, 32, 48, 18, 40, 8, 36, 3, 16, 33, 62, 23, 38, 25, 53, 2, 21, 41, 6, 22, 15, 59, 29, 16, 37, 26, 15, 52, 42, 23, 15, 54, 39, 10, 30, 53, 11, 49, 24, 2, 43, 55, 17, 34, 44, 15, 31, 24, 44, 2, 32, 7, 35, 25, 5, 40, 45, 29, 51, 6, 21, 37, 52, 24, 60, 13, 31, 53, 23, 2, 28, 49, 24, 31, 60, 20, 51, 1, 34, 48, 14, 59, 33, 50, 1, 18, 33, 48, 60, 17, 51, 39, 6, 38, 2, 35, 29, 40, 23, 1, 62, 15, 53, 37, 17, 46, 57, 40, 51, 24, 22 }, + { 5, 37, 52, 24, 45, 13, 40, 3, 45, 9, 19, 42, 56, 4, 37, 46, 56, 2, 63, 11, 51, 1, 49, 13, 59, 45, 39, 1, 48, 15, 58, 9, 46, 31, 54, 35, 57, 38, 3, 46, 56, 4, 47, 57, 1, 30, 38, 63, 3, 46, 28, 63, 41, 14, 33, 62, 19, 32, 13, 28, 61, 1, 53, 42, 11, 60, 22, 62, 27, 42, 61, 31, 19, 8, 61, 12, 32, 55, 2, 18, 33, 12, 43, 36, 9, 62, 30, 55, 6, 58, 35, 7, 43, 29, 54, 23, 43, 30, 3, 25, 11, 45, 52, 28, 7, 14, 42, 1, 22, 50, 16, 53, 19, 59, 4, 46, 33, 41, 4, 35, 58, 5, 26, 13, 20, 2, 34, 54 }, + { 30, 63, 21, 10, 26, 55, 29, 59, 23, 39, 53, 1, 36, 24, 59, 27, 10, 34, 23, 38, 30, 60, 22, 42, 28, 19, 9, 57, 30, 19, 43, 33, 13, 63, 3, 19, 11, 50, 31, 20, 14, 34, 10, 35, 17, 59, 7, 31, 19, 25, 50, 5, 20, 57, 29, 6, 52, 41, 4, 46, 20, 37, 26, 17, 49, 6, 39, 18, 53, 14, 3, 49, 57, 23, 34, 48, 14, 41, 28, 38, 56, 6, 58, 25, 39, 19, 43, 15, 37, 11, 47, 18, 53, 4, 37, 9, 62, 21, 53, 40, 57, 24, 13, 40, 56, 26, 47, 31, 59, 25, 45, 27, 10, 43, 21, 61, 13, 27, 48, 9, 23, 43, 31, 62, 38, 59, 9, 47 }, + { 25, 4, 40, 60, 34, 6, 18, 36, 8, 57, 12, 30, 49, 14, 6, 54, 41, 16, 50, 6, 43, 15, 34, 4, 53, 24, 50, 35, 4, 51, 7, 55, 28, 24, 39, 44, 60, 7, 25, 62, 42, 53, 24, 61, 28, 45, 52, 12, 48, 37, 9, 35, 43, 3, 37, 48, 12, 58, 30, 52, 9, 59, 6, 57, 33, 29, 48, 4, 37, 45, 20, 34, 10, 39, 0, 60, 22, 45, 8, 63, 21, 42, 14, 49, 3, 56, 11, 46, 21, 61, 0, 42, 25, 13, 63, 17, 36, 8, 46, 16, 6, 35, 63, 0, 21, 37, 4, 57, 9, 34, 5, 61, 48, 32, 8, 37, 54, 17, 56, 30, 60, 0, 50, 16, 7, 29, 42, 17 }, + { 32, 50, 15, 48, 2, 43, 52, 25, 47, 16, 32, 63, 21, 52, 40, 19, 0, 61, 29, 58, 20, 56, 26, 46, 12, 55, 6, 22, 62, 32, 17, 40, 0, 49, 34, 8, 27, 32, 48, 0, 21, 39, 5, 44, 12, 6, 22, 40, 0, 57, 16, 60, 23, 17, 54, 22, 36, 15, 24, 39, 19, 34, 47, 23, 0, 54, 13, 51, 24, 9, 55, 16, 52, 27, 44, 20, 4, 54, 26, 49, 0, 30, 46, 16, 29, 51, 34, 4, 52, 28, 33, 15, 57, 39, 26, 49, 0, 56, 27, 31, 48, 20, 43, 29, 53, 11, 46, 19, 41, 13, 55, 18, 0, 57, 26, 51, 2, 44, 6, 38, 14, 40, 22, 45, 36, 53, 3, 57 }, + { 44, 12, 37, 28, 22, 57, 11, 38, 0, 51, 9, 41, 4, 29, 11, 47, 33, 45, 12, 26, 3, 36, 9, 63, 31, 16, 38, 44, 14, 47, 25, 61, 20, 58, 15, 47, 17, 57, 13, 36, 9, 51, 18, 29, 50, 36, 54, 20, 61, 27, 32, 13, 53, 44, 9, 27, 0, 63, 45, 2, 56, 10, 14, 43, 41, 28, 58, 11, 35, 60, 30, 41, 6, 63, 11, 51, 37, 32, 15, 10, 35, 53, 5, 61, 22, 7, 26, 59, 23, 9, 44, 48, 21, 3, 51, 32, 24, 41, 12, 61, 2, 55, 9, 15, 35, 58, 28, 15, 62, 30, 37, 23, 42, 29, 11, 17, 35, 24, 63, 20, 52, 28, 8, 55, 11, 23, 47, 19 }, + { 0, 56, 8, 53, 14, 31, 61, 20, 55, 28, 62, 18, 35, 60, 25, 57, 7, 23, 39, 54, 47, 17, 43, 0, 40, 59, 29, 2, 56, 10, 37, 5, 43, 11, 29, 52, 1, 23, 54, 41, 59, 30, 55, 1, 62, 15, 33, 4, 43, 10, 47, 39, 1, 31, 40, 60, 49, 33, 7, 55, 26, 50, 31, 61, 8, 18, 21, 32, 44, 1, 25, 47, 18, 36, 30, 23, 59, 7, 40, 59, 27, 19, 38, 32, 44, 54, 40, 17, 38, 60, 27, 6, 35, 55, 10, 14, 44, 5, 50, 17, 38, 26, 42, 50, 18, 3, 44, 52, 2, 49, 7, 52, 15, 46, 62, 39, 55, 10, 31, 48, 3, 58, 33, 18, 61, 34, 13, 59 }, + { 39, 27, 63, 20, 35, 41, 4, 45, 26, 5, 38, 13, 44, 2, 50, 17, 37, 52, 2, 13, 28, 58, 24, 51, 21, 8, 34, 48, 27, 42, 18, 51, 31, 56, 5, 36, 38, 44, 4, 17, 26, 11, 38, 23, 42, 8, 56, 39, 24, 51, 5, 56, 21, 59, 14, 6, 18, 42, 22, 35, 16, 37, 3, 25, 39, 46, 63, 5, 50, 17, 58, 8, 55, 3, 50, 12, 43, 17, 47, 2, 51, 9, 62, 12, 1, 35, 13, 50, 1, 37, 12, 51, 19, 29, 46, 59, 22, 58, 33, 45, 22, 60, 10, 32, 61, 39, 8, 33, 25, 36, 20, 60, 38, 4, 21, 5, 28, 45, 12, 18, 42, 11, 49, 1, 27, 40, 6, 30 }, + { 24, 16, 42, 1, 50, 10, 48, 17, 33, 43, 24, 48, 21, 55, 31, 42, 10, 21, 63, 35, 49, 6, 33, 13, 41, 53, 10, 20, 60, 6, 53, 26, 12, 41, 22, 60, 14, 28, 63, 33, 49, 3, 45, 16, 48, 26, 14, 46, 18, 30, 35, 26, 8, 50, 29, 51, 25, 57, 12, 47, 53, 9, 62, 20, 54, 2, 36, 15, 40, 28, 33, 13, 38, 24, 46, 1, 29, 56, 33, 20, 44, 24, 41, 26, 57, 20, 63, 8, 30, 55, 5, 41, 62, 8, 34, 2, 37, 10, 19, 6, 37, 1, 53, 23, 5, 27, 58, 22, 43, 12, 50, 26, 9, 34, 54, 32, 49, 1, 59, 37, 22, 46, 25, 36, 51, 15, 54, 46 }, + { 52, 7, 45, 33, 26, 58, 14, 60, 7, 54, 3, 58, 8, 34, 14, 5, 59, 30, 18, 44, 8, 22, 48, 62, 3, 26, 55, 38, 23, 16, 39, 1, 62, 24, 49, 9, 53, 19, 46, 7, 19, 60, 31, 58, 2, 34, 53, 7, 59, 2, 62, 42, 46, 19, 36, 11, 44, 4, 38, 28, 1, 43, 32, 51, 12, 29, 56, 22, 52, 2, 62, 49, 22, 60, 14, 35, 63, 5, 25, 57, 14, 53, 4, 46, 18, 31, 42, 22, 47, 20, 58, 31, 16, 43, 23, 54, 30, 42, 52, 57, 29, 49, 30, 13, 45, 48, 16, 55, 6, 63, 1, 44, 14, 58, 19, 47, 15, 24, 51, 34, 6, 55, 5, 63, 20, 41, 21, 9 }, + { 30, 62, 18, 55, 5, 23, 39, 29, 49, 30, 15, 36, 28, 46, 60, 25, 39, 46, 4, 32, 61, 40, 15, 30, 36, 45, 14, 2, 49, 33, 57, 45, 18, 32, 3, 45, 30, 2, 35, 52, 40, 27, 13, 21, 38, 63, 20, 28, 37, 23, 16, 10, 13, 55, 2, 62, 21, 32, 60, 17, 58, 23, 5, 40, 16, 48, 7, 45, 10, 26, 43, 19, 6, 31, 52, 21, 39, 16, 48, 9, 37, 28, 36, 55, 7, 48, 3, 59, 15, 45, 25, 1, 53, 13, 47, 7, 62, 15, 4, 25, 12, 41, 18, 60, 38, 11, 34, 19, 39, 31, 29, 56, 23, 42, 3, 27, 60, 41, 8, 16, 61, 29, 43, 9, 32, 2, 60, 34 }, + { 3, 38, 13, 37, 52, 44, 2, 19, 12, 42, 63, 19, 40, 1, 20, 50, 12, 55, 15, 56, 27, 1, 54, 11, 57, 18, 32, 63, 44, 4, 29, 13, 37, 61, 35, 16, 42, 57, 12, 22, 6, 55, 43, 10, 50, 5, 44, 11, 48, 52, 34, 58, 28, 41, 38, 30, 7, 52, 11, 49, 30, 14, 45, 27, 59, 34, 21, 38, 32, 58, 11, 36, 56, 42, 9, 41, 3, 54, 31, 42, 0, 60, 16, 11, 39, 24, 52, 33, 6, 36, 10, 40, 32, 60, 26, 20, 39, 28, 47, 34, 63, 8, 54, 3, 24, 56, 0, 51, 13, 47, 16, 40, 7, 35, 52, 11, 36, 4, 57, 30, 39, 13, 18, 50, 58, 28, 12, 48 }, + { 57, 24, 49, 21, 10, 31, 61, 36, 56, 0, 22, 53, 11, 56, 32, 7, 36, 27, 41, 9, 46, 19, 34, 42, 25, 7, 50, 9, 28, 21, 54, 8, 50, 7, 27, 59, 10, 25, 48, 62, 37, 0, 33, 58, 25, 18, 32, 61, 0, 15, 45, 5, 50, 3, 23, 55, 47, 17, 40, 6, 60, 34, 53, 8, 41, 0, 61, 13, 54, 4, 46, 28, 0, 17, 48, 27, 58, 13, 23, 61, 33, 21, 50, 30, 62, 8, 14, 29, 56, 27, 61, 49, 17, 2, 44, 11, 51, 0, 59, 17, 40, 20, 32, 47, 36, 21, 42, 28, 60, 4, 54, 10, 59, 17, 30, 62, 21, 43, 26, 48, 0, 56, 36, 25, 8, 44, 39, 17 }, + { 10, 42, 4, 59, 27, 47, 8, 23, 51, 32, 45, 6, 37, 26, 48, 43, 62, 0, 21, 53, 38, 12, 51, 5, 60, 47, 24, 37, 59, 15, 35, 47, 22, 55, 0, 50, 21, 40, 6, 29, 15, 52, 24, 8, 41, 55, 13, 29, 40, 56, 24, 31, 19, 33, 61, 15, 0, 35, 24, 42, 21, 2, 19, 57, 24, 15, 30, 50, 20, 25, 40, 16, 57, 34, 61, 8, 29, 45, 6, 49, 11, 47, 2, 44, 19, 57, 38, 50, 12, 42, 21, 4, 35, 52, 28, 56, 23, 36, 13, 45, 4, 52, 27, 14, 6, 62, 9, 45, 21, 37, 25, 46, 33, 49, 0, 44, 7, 53, 13, 19, 53, 31, 3, 47, 15, 56, 22, 51 }, + { 35, 28, 53, 32, 1, 16, 54, 40, 9, 17, 25, 58, 14, 59, 3, 22, 16, 51, 31, 5, 23, 58, 28, 17, 35, 20, 0, 42, 11, 52, 3, 31, 41, 17, 43, 13, 32, 54, 18, 60, 32, 45, 17, 49, 2, 36, 51, 22, 7, 36, 9, 63, 48, 12, 46, 26, 43, 28, 63, 13, 48, 37, 51, 33, 5, 47, 55, 9, 42, 63, 7, 51, 24, 12, 37, 19, 55, 34, 18, 38, 15, 28, 54, 34, 5, 43, 22, 0, 48, 14, 54, 24, 58, 9, 38, 5, 32, 55, 21, 30, 49, 9, 59, 43, 30, 51, 35, 26, 7, 53, 2, 22, 14, 27, 57, 18, 38, 24, 33, 45, 10, 41, 20, 60, 37, 5, 32, 0 }, + { 63, 19, 15, 40, 62, 35, 14, 28, 46, 61, 4, 49, 35, 10, 29, 54, 33, 8, 45, 62, 37, 1, 43, 55, 10, 52, 61, 30, 19, 40, 25, 62, 11, 38, 27, 58, 36, 3, 46, 8, 39, 4, 62, 28, 47, 20, 4, 54, 47, 27, 43, 1, 21, 38, 8, 58, 10, 54, 4, 56, 9, 26, 12, 39, 60, 27, 18, 37, 1, 31, 35, 5, 45, 50, 2, 43, 26, 1, 59, 23, 56, 40, 7, 26, 58, 17, 32, 63, 25, 39, 7, 31, 45, 19, 63, 15, 48, 8, 37, 61, 16, 34, 1, 56, 18, 3, 15, 58, 49, 32, 63, 41, 55, 5, 40, 22, 50, 6, 59, 2, 63, 23, 52, 11, 26, 61, 44, 23 }, + { 11, 56, 46, 6, 22, 43, 58, 3, 34, 21, 38, 30, 18, 44, 52, 13, 41, 57, 17, 28, 14, 49, 25, 7, 33, 39, 26, 6, 56, 48, 1, 20, 56, 5, 46, 9, 19, 51, 30, 25, 56, 21, 35, 14, 57, 42, 16, 33, 10, 57, 17, 59, 41, 25, 53, 37, 20, 40, 30, 18, 31, 62, 44, 22, 3, 44, 11, 48, 23, 53, 18, 60, 29, 22, 62, 15, 53, 47, 10, 41, 3, 19, 52, 36, 13, 46, 10, 35, 3, 61, 41, 16, 1, 50, 26, 42, 18, 46, 2, 25, 54, 20, 39, 23, 47, 31, 41, 12, 38, 17, 8, 19, 31, 48, 12, 61, 9, 54, 29, 35, 15, 38, 6, 43, 34, 14, 7, 47 }, + { 39, 2, 33, 26, 53, 8, 18, 50, 41, 12, 53, 1, 63, 24, 19, 39, 2, 24, 47, 10, 60, 38, 19, 63, 48, 4, 15, 45, 32, 14, 60, 36, 29, 53, 23, 63, 34, 12, 61, 1, 43, 11, 53, 30, 1, 26, 60, 45, 23, 39, 3, 29, 12, 50, 4, 16, 51, 3, 45, 36, 50, 1, 16, 54, 35, 14, 57, 30, 58, 9, 46, 14, 41, 10, 32, 38, 4, 30, 21, 51, 32, 63, 25, 1, 60, 27, 53, 18, 51, 22, 28, 55, 34, 12, 40, 3, 60, 29, 57, 41, 6, 44, 11, 53, 8, 61, 24, 57, 1, 28, 44, 59, 36, 3, 34, 25, 41, 31, 16, 44, 22, 47, 28, 58, 1, 49, 54, 29 }, + { 58, 25, 50, 13, 38, 30, 60, 24, 6, 57, 27, 42, 9, 45, 6, 61, 30, 50, 4, 34, 29, 3, 46, 13, 22, 42, 58, 28, 9, 39, 23, 44, 7, 15, 44, 2, 40, 15, 47, 41, 23, 37, 7, 59, 38, 11, 34, 6, 62, 14, 52, 35, 55, 19, 32, 61, 33, 24, 57, 6, 22, 59, 29, 7, 49, 25, 40, 3, 17, 39, 27, 52, 0, 55, 16, 57, 24, 61, 36, 6, 29, 12, 48, 39, 20, 44, 6, 40, 33, 5, 48, 10, 57, 36, 22, 51, 33, 9, 24, 12, 62, 29, 50, 35, 14, 43, 5, 33, 47, 52, 13, 23, 10, 51, 56, 16, 46, 1, 49, 4, 61, 9, 52, 18, 31, 21, 36, 17 }, + { 19, 42, 9, 48, 2, 44, 11, 37, 48, 20, 33, 16, 55, 35, 49, 15, 37, 20, 59, 16, 53, 22, 56, 31, 50, 11, 34, 54, 16, 51, 4, 49, 33, 53, 21, 28, 56, 24, 31, 9, 52, 16, 48, 24, 44, 13, 51, 20, 31, 49, 18, 6, 34, 2, 44, 14, 47, 8, 15, 43, 13, 41, 33, 52, 20, 61, 7, 51, 34, 62, 4, 20, 36, 33, 43, 8, 46, 13, 53, 17, 45, 42, 9, 31, 52, 11, 30, 56, 13, 59, 17, 44, 27, 6, 62, 11, 43, 17, 49, 38, 26, 2, 16, 27, 58, 21, 54, 18, 26, 5, 35, 61, 43, 27, 7, 39, 14, 58, 37, 55, 20, 33, 13, 40, 62, 10, 55, 5 }, + { 51, 14, 61, 29, 59, 20, 55, 31, 0, 49, 11, 60, 3, 26, 22, 56, 0, 40, 12, 43, 41, 8, 36, 0, 17, 57, 24, 2, 46, 26, 61, 18, 0, 38, 12, 59, 6, 49, 3, 57, 19, 63, 5, 33, 18, 54, 28, 56, 0, 43, 26, 46, 63, 27, 56, 22, 27, 54, 38, 28, 63, 24, 10, 45, 0, 31, 42, 21, 12, 25, 44, 49, 59, 6, 26, 50, 3, 34, 27, 59, 0, 35, 62, 16, 4, 58, 47, 0, 43, 24, 37, 2, 54, 20, 46, 31, 0, 56, 34, 5, 55, 45, 60, 37, 0, 40, 10, 38, 63, 46, 15, 20, 0, 53, 21, 62, 30, 11, 24, 27, 40, 0, 57, 26, 3, 45, 27, 35 } +}; + +static always_inline void +_soft16_convert_from_rgba_pt(const DATA32 *src, DATA16 *dst, DATA8 *alpha, + const int x, const int y) +{ + DATA8 orig_r, orig_g, orig_b, orig_a; + + orig_r = R_VAL(src); + orig_g = G_VAL(src); + orig_b = B_VAL(src); + orig_a = A_VAL(src); + + if (orig_a == 255) + { + DATA8 dith5, dith6, dith, r, g, b; + + dith = dither_table[x & S16_DM_MSK][y & S16_DM_MSK]; + dith5 = dith >> S16_DM_SHF(5); + dith6 = dith >> S16_DM_SHF(6); + + r = orig_r >> 3; + g = orig_g >> 2; + b = orig_b >> 3; + + if (((orig_r - (r << 3)) >= dith5) && (r < 0x1f)) r++; + if (((orig_g - (g << 2)) >= dith6) && (g < 0x3f)) g++; + if (((orig_b - (b << 3)) >= dith5) && (b < 0x1f)) b++; + + *dst = (r << 11) | (g << 5) | b; + *alpha = 31; + } + else if (orig_a == 0) + { + *dst = 0; + *alpha = 0; + } + else + { + DATA8 r, g, b, a; + r = orig_r >> 3; + g = orig_g >> 2; + b = orig_b >> 3; + a = (orig_a >> 3) + 1; + + *dst = (r << 11) | (g << 5) | b; + *alpha = a; + } +} + +static inline void +_soft16_convert_from_rgba_scanline(const DATA32 *src, DATA16 *dst, + DATA8 *alpha, const int y, const int w) +{ + int x, m; + + m = (w & ~7); + x = 0; + pld(src, 0); + + while (x < m) + { + pld(src, 32); + UNROLL8({ + _soft16_convert_from_rgba_pt(src, dst, alpha, x, y); + src++; + dst++; + alpha++; + x++; + }); + } + + for (; x < w; x++, src++, dst++, alpha++) + _soft16_convert_from_rgba_pt(src, dst, alpha, x, y); +} + +void +soft16_image_convert_from_rgba(Soft16_Image *im, const DATA32 *src) +{ + const DATA32 *sp; + DATA16 *dp; + DATA8 *ap; + int y; + + sp = src; + dp = im->pixels; + ap = im->alpha; + + for (y = 0; y < im->cache_entry.h; y++, sp += im->cache_entry.w, dp += im->stride, ap += im->stride) + _soft16_convert_from_rgba_scanline(sp, dp, ap, y, im->cache_entry.w); +} + +static always_inline void +_soft16_convert_from_rgb_pt(const DATA32 *src, DATA16 *dst, + const int x, const int y) +{ + DATA8 orig_r, orig_g, orig_b, r, g, b, dith5, dith6, dith; + + orig_r = R_VAL(src); + orig_g = G_VAL(src); + orig_b = B_VAL(src); + + r = orig_r >> 3; + g = orig_g >> 2; + b = orig_b >> 3; + + dith = dither_table[x & S16_DM_MSK][y & S16_DM_MSK]; + dith5 = dith >> S16_DM_SHF(5); + dith6 = dith >> S16_DM_SHF(6); + + if (((orig_r - (r << 3)) >= dith5) && (r < 0x1f)) r++; + if (((orig_g - (g << 2)) >= dith6) && (g < 0x3f)) g++; + if (((orig_b - (b << 3)) >= dith5) && (b < 0x1f)) b++; + + *dst = (r << 11) | (g << 5) | b; +} + +static inline void +_soft16_convert_from_rgb_scanline(const DATA32 *src, DATA16 *dst, const int y, + const int w) +{ + int x, m; + + m = (w & ~7); + x = 0; + pld(src, 0); + + while (x < m) + { + pld(src, 32); + UNROLL8({ + _soft16_convert_from_rgb_pt(src, dst, x, y); + src++; + dst++; + x++; + }); + } + + for (; x < w; x++, src++, dst++) + _soft16_convert_from_rgb_pt(src, dst, x, y); +} + +void +soft16_image_convert_from_rgb(Soft16_Image *im, const DATA32 *src) +{ + const DATA32 *sp; + DATA16 *dp; + int y, pad; + + sp = src; + dp = im->pixels; + pad = im->stride - im->cache_entry.w; + + for (y = 0; y < im->cache_entry.h; y++, sp += im->cache_entry.w, dp += im->stride) + _soft16_convert_from_rgb_scanline(sp, dp, y, im->cache_entry.w); +} diff --git a/legacy/evas/src/lib/engines/common_16/evas_soft16_font.c b/legacy/evas/src/lib/engines/common_16/evas_soft16_font.c new file mode 100644 index 0000000000..0874332988 --- /dev/null +++ b/legacy/evas/src/lib/engines/common_16/evas_soft16_font.c @@ -0,0 +1,302 @@ +#include "evas_common_soft16.h" +#include "evas_soft16_scanline_blend.c" + +static always_inline void +_glyph_pt_mask_solid_solid(DATA16 *dst, + const DATA16 rgb565, + const DATA32 rgb565_unpack, + const DATA8 *mask) +{ + DATA8 alpha = *mask >> 3; + + if (alpha == 31) *dst = rgb565; + else if (alpha > 0) + { + DATA32 d; + + d = RGB_565_UNPACK(*dst); + d = RGB_565_UNPACKED_BLEND_UNMUL(rgb565_unpack, d, alpha); + *dst = RGB_565_PACK(d); + } +} + +static void +_glyph_scanline_mask_solid_solid(DATA16 *dst, + int size, + const DATA16 rgb565, + const DATA32 rgb565_unpack, + const DATA8 *mask) +{ + DATA16 *start, *end; + + start = dst; + pld(start, 0); + pld(mask, 0); + end = start + (size & ~3); + + while (start < end) + { + pld(start, 16); + pld(mask, 4); + UNROLL4({ + _glyph_pt_mask_solid_solid(start, rgb565, rgb565_unpack, mask); + start++; + mask++; + }); + } + + end = start + (size & 3); + for (; start < end; start++, mask++) + _glyph_pt_mask_solid_solid(start, rgb565, rgb565_unpack, mask); +} + +static always_inline void +_glyph_pt_mask_transp_solid(DATA16 *dst, + DATA32 rgb565_unpack, + DATA8 alpha, + const DATA8 *mask) +{ + DATA32 a, b; + int rel_alpha; + + rel_alpha = *mask >> 3; + alpha = (alpha * rel_alpha) >> 5; + if (alpha == 0) + return; + + alpha++; + + a = ((rgb565_unpack * rel_alpha) >> 5) & RGB_565_UNPACKED_MASK; + b = RGB_565_UNPACK(*dst); + b = RGB_565_UNPACKED_BLEND(a, b, alpha); + *dst = RGB_565_PACK(b); +} + +static void +_glyph_scanline_mask_transp_solid(DATA16 *dst, + int size, + const DATA32 rgb565_unpack, + const DATA8 rel_alpha, + const DATA8 *mask) +{ + DATA16 *start, *end; + + start = dst; + pld(start, 0); + pld(mask, 0); + end = start + (size & ~3); + + while (start < end) + { + pld(start, 16); + pld(mask, 4); + UNROLL4({ + _glyph_pt_mask_transp_solid(start, rgb565_unpack, rel_alpha, mask); + start++; + mask++; + }); + } + + end = start + (size & 3); + for (; start < end; start++, mask++) + _glyph_pt_mask_transp_solid(start, rgb565_unpack, rel_alpha, mask); +} + +static inline void +_calc_ext(const Soft16_Image *dst, const RGBA_Draw_Context *dc, + Evas_Rectangle *ext) +{ + ext->x = 0; + ext->y = 0; + ext->w = dst->cache_entry.w; + ext->h = dst->cache_entry.h; + + if (dc->clip.use) + { + int v; + + ext->x = dc->clip.x; + ext->y = dc->clip.y; + ext->w = dc->clip.w; + ext->h = dc->clip.h; + if (ext->x < 0) + { + ext->w += ext->x; + ext->x = 0; + } + if (ext->y < 0) + { + ext->h += ext->y; + ext->y = 0; + } + + v = dst->cache_entry.w - ext->x; + if (ext->w > v) ext->w = v; + + v = dst->cache_entry.h - ext->y; + if (ext->h > v) ext->h = v; + } +} + +static inline void +_glyph_scanline(Soft16_Image *dst, const DATA8 *p_mask, + const Evas_Rectangle ext, int dx, int dy, int max_x, int max_y, + int w, DATA8 alpha, const DATA16 rgb565, + const DATA32 rgb565_unpack) +{ + int size, in_x, in_w; + DATA16 *p_pixels; + + if ((dx >= max_x) || (dy < ext.y) || (dy >= max_y)) return; + + in_x = 0; + in_w = 0; + + if (dx + w > max_x) in_w += (dx + w) - max_x; + + if (dx < ext.x) + { + in_w += ext.x - dx; + in_x = ext.x - dx; + dx = ext.x; + } + + size = w - in_w; + p_pixels = dst->pixels + (dy * dst->stride) + dx; + p_mask += in_x; + + if (size > 1) + { + if (alpha == 31) + _glyph_scanline_mask_solid_solid + (p_pixels, size, rgb565, rgb565_unpack, p_mask); + else if (alpha != 0) + _glyph_scanline_mask_transp_solid + (p_pixels, size, rgb565_unpack, alpha, p_mask); + } + else if (size == 1) + { + if (alpha == 31) + _glyph_pt_mask_solid_solid(p_pixels, rgb565, rgb565_unpack, p_mask); + else if (alpha != 0) + _glyph_pt_mask_transp_solid(p_pixels, rgb565_unpack, alpha, p_mask); + } +} + +static void +_soft16_font_glyph_draw_grayscale(Soft16_Image *dst, + RGBA_Draw_Context *dc, RGBA_Font_Glyph *fg, + int x, int y, DATA8 alpha, DATA16 rgb565, + const Evas_Rectangle ext, int bw, int bh, + int bpitch, const DATA8 *bitmap) +{ + const DATA32 rgb565_unpack = RGB_565_UNPACK(rgb565); + int i, max_x, max_y; + + max_x = ext.x + ext.w; + max_y = ext.y + ext.h; + + for (i = 0; i < bh; i++, bitmap += bpitch) + _glyph_scanline(dst, bitmap, ext, x, y + i, max_x, max_y, bw, + alpha, rgb565, rgb565_unpack); +} + +static inline void +_glyph_create_mask_line(DATA8 *mask, const DATA8 *bitmap, int w) +{ + const DATA8 bitrepl[2] = {0x0, 0xff}; + int i; + + for (i = 0; i < w; i += 8, bitmap++) + { + int j, size; + DATA32 bits; + + if (i + 8 < w) size = 8; + else size = w - i; + + bits = *bitmap; + + for (j = size - 1; j >= 0; j--, mask++) + *mask = bitrepl[(bits >> j) & 0x1]; + } +} + +static void +_soft16_font_glyph_draw_mono(Soft16_Image *dst, + RGBA_Draw_Context *dc, RGBA_Font_Glyph *fg, + int x, int y, DATA8 alpha, DATA16 rgb565, + const Evas_Rectangle ext, int bw, int bh, + int bpitch, const DATA8 *bitmap) +{ + const DATA32 rgb565_unpack = RGB_565_UNPACK(rgb565); + DATA8 *mask; + int i, max_x, max_y; + + max_x = ext.x + ext.w; + max_y = ext.y + ext.h; + + mask = alloca(bpitch); + for (i = 0; i < bh; i++, bitmap += bpitch) + { + _glyph_create_mask_line(mask, bitmap, bw); + _glyph_scanline(dst, mask, ext, x, y + i, max_x, max_y, bw, + alpha, rgb565, rgb565_unpack); + } +} + +void +soft16_font_glyph_draw(void *data, void *dest, void *context, + RGBA_Font_Glyph *fg, int x, int y) +{ + Soft16_Image *dst; + RGBA_Draw_Context *dc; + const DATA8 *bitmap; + DATA8 alpha, r, g, b; + DATA16 rgb565; + Evas_Rectangle ext; + int bpitch, bw, bh; + + dst = data; + dc = context; + + alpha = A_VAL(&dc->col.col) >> 3; + if (alpha == 0) return; /* precision is 5 bits, 3 bits lost */ + + r = R_VAL(&dc->col.col) >> 3; + g = G_VAL(&dc->col.col) >> 2; + b = B_VAL(&dc->col.col) >> 3; + + if (r > alpha) r = alpha; + if (g > (alpha << 1)) g = (alpha << 1); + if (b > alpha) b = alpha; + + rgb565 = (r << 11) | (g << 5) | b; + + bitmap = fg->glyph_out->bitmap.buffer; + bh = fg->glyph_out->bitmap.rows; + bw = fg->glyph_out->bitmap.width; + bpitch = fg->glyph_out->bitmap.pitch; + if (bpitch < bw) bpitch = bw; + + _calc_ext(dst, dc, &ext); + + if ((fg->glyph_out->bitmap.num_grays == 256) && + (fg->glyph_out->bitmap.pixel_mode == ft_pixel_mode_grays)) + _soft16_font_glyph_draw_grayscale(dst, dc, fg, x, y, alpha, rgb565, + ext, bw, bh, bpitch, bitmap); + else + _soft16_font_glyph_draw_mono(dst, dc, fg, x, y, alpha, rgb565, + ext, bw, bh, bpitch, bitmap); +} + +void * +soft16_font_glyph_new(void *data, RGBA_Font_Glyph *fg) +{ + return (void *)1; /* core requires != NULL to work */ +} + +void +soft16_font_glyph_free(void *ext_dat) +{ +} diff --git a/legacy/evas/src/lib/engines/common_16/evas_soft16_image_scaled_sampled.c b/legacy/evas/src/lib/engines/common_16/evas_soft16_image_scaled_sampled.c new file mode 100644 index 0000000000..10b5f41c74 --- /dev/null +++ b/legacy/evas/src/lib/engines/common_16/evas_soft16_image_scaled_sampled.c @@ -0,0 +1,471 @@ +#include "evas_common_soft16.h" +#include "evas_soft16_scanline_blend.c" + +static void +_soft16_image_draw_scaled_solid_solid(Soft16_Image *src, + Soft16_Image *dst, + RGBA_Draw_Context *dc, + int dst_offset, int w, int h, + int *offset_x, int *offset_y) +{ + DATA16 *dst_itr; + int y, w_align; + + w_align = w & ~7; + + dst_itr = dst->pixels + dst_offset; + for (y = 0; y < h; y++, dst_itr += dst->stride) + { + DATA16 *d, *s; + int x; + + s = src->pixels + offset_y[y]; + pld(s, 0); + pld(offset_x, 0); + + d = dst_itr; + x = 0; + while (x < w_align) + { + pld(s, 32); + pld(offset_x + x, 32); + + UNROLL8({ + _soft16_pt_blend_solid_solid(d, s[offset_x[x]]); + x++; + d++; + }); + } + + for (; x < w; x++, d++) + _soft16_pt_blend_solid_solid(d, s[offset_x[x]]); + } +} +static void +_soft16_image_draw_scaled_transp_solid(Soft16_Image *src, + Soft16_Image *dst, + RGBA_Draw_Context *dc, + int dst_offset, int w, int h, + int *offset_x, int *offset_y) +{ + DATA16 *dst_itr; + int y, w_align; + + w_align = w & ~7; + + dst_itr = dst->pixels + dst_offset; + for (y = 0; y < h; y++, dst_itr += dst->stride) + { + DATA16 *d, *s; + DATA8 *a; + int x; + + s = src->pixels + offset_y[y]; + a = src->alpha + offset_y[y]; + pld(s, 0); + pld(a, 0); + pld(offset_x, 0); + + d = dst_itr; + x = 0; + while (x < w_align) + { + pld(s, 32); + pld(a, 8); + pld(offset_x + x, 32); + + UNROLL8({ + int off_x = offset_x[x]; + _soft16_pt_blend_transp_solid(d, s[off_x], a[off_x]); + x++; + d++; + }); + } + + for (; x < w; x++, d++) + _soft16_pt_blend_transp_solid(d, s[offset_x[x]], a[offset_x[x]]); + } +} + +static inline void +_soft16_image_draw_scaled_no_mul(Soft16_Image *src, Soft16_Image *dst, + RGBA_Draw_Context *dc, + int dst_offset, int w, int h, + int *offset_x, int *offset_y) +{ + if (src->flags.have_alpha && (!dst->flags.have_alpha)) + _soft16_image_draw_scaled_transp_solid + (src, dst, dc, dst_offset, w, h, offset_x, offset_y); + else if ((!src->flags.have_alpha) && (!dst->flags.have_alpha)) + _soft16_image_draw_scaled_solid_solid + (src, dst, dc, dst_offset, w, h, offset_x, offset_y); + else + fprintf(stderr, + "Unsupported draw of scaled images src->flags.have_alpha=%d, " + "dst->flags.have_alpha=%d, WITHOUT COLOR MUL\n", + src->flags.have_alpha, dst->flags.have_alpha); +} + +static void +_soft16_image_draw_scaled_solid_solid_mul_alpha(Soft16_Image *src, + Soft16_Image *dst, + RGBA_Draw_Context *dc, + int dst_offset, int w, int h, + int *offset_x, int *offset_y, + DATA8 alpha) +{ + DATA16 *dst_itr; + int y, w_align; + + w_align = w & ~7; + + dst_itr = dst->pixels + dst_offset; + for (y = 0; y < h; y++, dst_itr += dst->stride) + { + DATA16 *d, *s; + int x; + + s = src->pixels + offset_y[y]; + pld(s, 0); + pld(offset_x, 0); + + d = dst_itr; + x = 0; + while (x < w_align) + { + pld(s, 32); + pld(offset_x + x, 32); + + UNROLL8({ + _soft16_pt_blend_solid_solid_mul_alpha + (d, s[offset_x[x]], alpha); + x++; + d++; + }); + } + + for (; x < w; x++, d++) + _soft16_pt_blend_solid_solid_mul_alpha + (d, s[offset_x[x]], alpha); + } +} + +static void +_soft16_image_draw_scaled_transp_solid_mul_alpha(Soft16_Image *src, + Soft16_Image *dst, + RGBA_Draw_Context *dc, + int dst_offset, int w, int h, + int *offset_x, int *offset_y, + DATA8 alpha) +{ + DATA16 *dst_itr; + int y, w_align; + + w_align = w & ~7; + + dst_itr = dst->pixels + dst_offset; + for (y = 0; y < h; y++, dst_itr += dst->stride) + { + DATA16 *d, *s; + DATA8 *a; + int x; + + s = src->pixels + offset_y[y]; + a = src->alpha + offset_y[y]; + pld(s, 0); + pld(a, 0); + pld(offset_x, 0); + + d = dst_itr; + x = 0; + while (x < w_align) + { + pld(s, 32); + pld(a, 8); + pld(offset_x + x, 32); + + UNROLL8({ + int off_x = offset_x[x]; + _soft16_pt_blend_transp_solid_mul_alpha + (d, s[off_x], a[off_x], alpha); + x++; + d++; + }); + } + + for (; x < w; x++, d++) + _soft16_pt_blend_transp_solid_mul_alpha + (d, s[offset_x[x]], a[offset_x[x]], alpha); + } +} + +static inline void +_soft16_image_draw_scaled_mul_alpha(Soft16_Image *src, Soft16_Image *dst, + RGBA_Draw_Context *dc, + int dst_offset, int w, int h, + int *offset_x, int *offset_y, DATA8 a) +{ + if (src->flags.have_alpha && (!dst->flags.have_alpha)) + _soft16_image_draw_scaled_transp_solid_mul_alpha + (src, dst, dc, dst_offset, w, h, offset_x, offset_y, a); + else if ((!src->flags.have_alpha) && (!dst->flags.have_alpha)) + _soft16_image_draw_scaled_solid_solid_mul_alpha + (src, dst, dc, dst_offset, w, h, offset_x, offset_y, a); + else + fprintf(stderr, + "Unsupported draw of scaled images src->flags.have_alpha=%d, " + "dst->flags.have_alpha=%d, WITH ALPHA MUL %d\n", + src->flags.have_alpha, dst->flags.have_alpha, A_VAL(&dc->mul.col)); +} + +static void +_soft16_image_draw_scaled_solid_solid_mul_color(Soft16_Image *src, + Soft16_Image *dst, + RGBA_Draw_Context *dc, + int dst_offset, int w, int h, + int *offset_x, int *offset_y, + DATA8 r, DATA8 g, DATA8 b, + DATA8 alpha) +{ + DATA16 *dst_itr; + int y, w_align; + + w_align = w & ~7; + + dst_itr = dst->pixels + dst_offset; + + if (alpha == 31) + for (y = 0; y < h; y++, dst_itr += dst->stride) + { + DATA16 *d, *s; + int x; + + s = src->pixels + offset_y[y]; + pld(s, 0); + pld(offset_x, 0); + + d = dst_itr; + x = 0; + while (x < w_align) + { + pld(s, 32); + pld(offset_x + x, 32); + + UNROLL8({ + _soft16_pt_blend_solid_solid_mul_color_solid + (d, s[offset_x[x]], r, g, b); + x++; + d++; + }); + } + + for (; x < w; x++, d++) + _soft16_pt_blend_solid_solid_mul_color_solid + (d, s[offset_x[x]], r, g, b); + } + else + for (y = 0; y < h; y++, dst_itr += dst->stride) + { + DATA16 *d, *s; + int x; + + s = src->pixels + offset_y[y]; + pld(s, 0); + pld(offset_x, 0); + + d = dst_itr; + x = 0; + while (x < w_align) + { + pld(s, 32); + pld(offset_x + x, 32); + + UNROLL8({ + _soft16_pt_blend_solid_solid_mul_color_transp + (d, s[offset_x[x]], alpha, r, g, b); + x++; + d++; + }); + } + + for (; x < w; x++, d++) + _soft16_pt_blend_solid_solid_mul_color_transp + (d, s[offset_x[x]], alpha, r, g, b); + } +} + +static void +_soft16_image_draw_scaled_transp_solid_mul_color(Soft16_Image *src, + Soft16_Image *dst, + RGBA_Draw_Context *dc, + int dst_offset, int w, int h, + int *offset_x, int *offset_y, + DATA8 r, DATA8 g, DATA8 b, + DATA8 alpha) +{ + DATA16 *dst_itr; + int y, w_align; + + w_align = w & ~7; + + dst_itr = dst->pixels + dst_offset; + + if (alpha == 31) + for (y = 0; y < h; y++, dst_itr += dst->stride) + { + DATA16 *d, *s; + DATA8 *a; + int x; + + s = src->pixels + offset_y[y]; + a = src->alpha + offset_y[y]; + pld(s, 0); + pld(a, 0); + pld(offset_x, 0); + + d = dst_itr; + x = 0; + while (x < w_align) + { + pld(s, 32); + pld(a, 8); + pld(offset_x + x, 32); + + UNROLL8({ + int off_x = offset_x[x]; + _soft16_pt_blend_transp_solid_mul_color_solid + (d, s[off_x], a[off_x], r, g, b); + x++; + d++; + }); + } + + for (; x < w; x++, d++) + _soft16_pt_blend_transp_solid_mul_color_solid + (d, s[offset_x[x]], a[offset_x[x]], r, g, b); + } + else + for (y = 0; y < h; y++, dst_itr += dst->stride) + { + DATA16 *d, *s; + DATA8 *a; + int x; + + s = src->pixels + offset_y[y]; + a = src->alpha + offset_y[y]; + pld(s, 0); + pld(a, 0); + pld(offset_x, 0); + + d = dst_itr; + x = 0; + while (x < w_align) + { + pld(s, 32); + pld(a, 8); + pld(offset_x + x, 32); + + UNROLL8({ + int off_x = offset_x[x]; + _soft16_pt_blend_transp_solid_mul_color_transp + (d, s[off_x], a[off_x], alpha, r, g, b); + x++; + d++; + }); + } + + for (; x < w; x++, d++) + _soft16_pt_blend_transp_solid_mul_color_transp + (d, s[offset_x[x]], a[offset_x[x]], alpha, r, g, b); + } +} + +static inline void +_soft16_image_draw_scaled_mul_color(Soft16_Image *src, Soft16_Image *dst, + RGBA_Draw_Context *dc, + int dst_offset, int w, int h, + int *offset_x, int *offset_y, + DATA8 r, DATA8 g, DATA8 b, DATA8 a) +{ + if (src->flags.have_alpha && (!dst->flags.have_alpha)) + _soft16_image_draw_scaled_transp_solid_mul_color + (src, dst, dc, dst_offset, w, h, offset_x, offset_y, r, g, b, a); + else if ((!src->flags.have_alpha) && (!dst->flags.have_alpha)) + _soft16_image_draw_scaled_solid_solid_mul_color + (src, dst, dc, dst_offset, w, h, offset_x, offset_y, r, g, b, a); + else + fprintf(stderr, + "Unsupported draw of scaled images src->flags.have_alpha=%d, " + "dst->flags.have_alpha=%d, WITH COLOR MUL 0x%08x\n", + src->flags.have_alpha, dst->flags.have_alpha, dc->mul.col); +} + +static inline void +_soft16_image_draw_scaled_mul(Soft16_Image *src, Soft16_Image *dst, + RGBA_Draw_Context *dc, + int dst_offset, int w, int h, + int *offset_x, int *offset_y, DATA8 r, DATA8 g, + DATA8 b, DATA8 a) +{ + if ((a == r) && (a == (g >> 1)) && (a == b)) + _soft16_image_draw_scaled_mul_alpha + (src, dst, dc, dst_offset, w, h, offset_x, offset_y, a); + else + _soft16_image_draw_scaled_mul_color + (src, dst, dc, dst_offset, w, h, offset_x, offset_y, r, g, b, a); +} + +void +soft16_image_draw_scaled_sampled(Soft16_Image *src, Soft16_Image *dst, + RGBA_Draw_Context *dc, + const Evas_Rectangle sr, + const Evas_Rectangle dr, + const Evas_Rectangle cr) +{ + int x, y, dst_offset, *offset_x, *offset_y; + DATA16 mul_rgb565; + DATA8 r, g, b, a; + + if (!dc->mul.use) + { + r = b = a = 31; + g = 63; + mul_rgb565 = 0xffff; + } + else + { + a = A_VAL(&dc->mul.col) >> 3; + if (a == 0) + return; + + r = R_VAL(&dc->mul.col) >> 3; + g = G_VAL(&dc->mul.col) >> 2; + b = B_VAL(&dc->mul.col) >> 3; + + if (r > a) r = a; + if (g > (a << 1)) g = (a << 1); + if (b > a) b = a; + + mul_rgb565 = (r << 11) || (g << 5) | b; + } + + /* pre-calculated scale tables */ + offset_x = alloca(cr.w * sizeof(*offset_x)); + for (x = 0; x < cr.w; x++) + offset_x[x] = (((x + cr.x - dr.x) * sr.w) / dr.w) + sr.x; + + offset_y = alloca(cr.h * sizeof(*offset_y)); + for (y = 0; y < cr.h; y++) + offset_y[y] = (((((y + cr.y - dr.y) * sr.h) / dr.h) + sr.y) + * src->stride); + + dst_offset = cr.x + (cr.y * dst->stride); + + + if (mul_rgb565 == 0xffff) + _soft16_image_draw_scaled_no_mul + (src, dst, dc, dst_offset, cr.w, cr.h, offset_x, offset_y); + else + _soft16_image_draw_scaled_mul + (src, dst, dc, dst_offset, cr.w, cr.h, offset_x, offset_y, r, g, b, a); +} diff --git a/legacy/evas/src/lib/engines/common_16/evas_soft16_image_unscaled.c b/legacy/evas/src/lib/engines/common_16/evas_soft16_image_unscaled.c new file mode 100644 index 0000000000..eab91235cc --- /dev/null +++ b/legacy/evas/src/lib/engines/common_16/evas_soft16_image_unscaled.c @@ -0,0 +1,290 @@ +#include "evas_common_soft16.h" +#include "evas_soft16_scanline_blend.c" + +static void +_soft16_image_draw_unscaled_solid_solid(Soft16_Image *src, Soft16_Image *dst, + RGBA_Draw_Context *dc, + int src_offset, int dst_offset, + int w, int h) +{ + DATA16 *src_itr, *dst_itr; + int y; + + src_itr = src->pixels + src_offset; + dst_itr = dst->pixels + dst_offset; + + for (y = 0; y < h; y++) + { + _soft16_scanline_blend_solid_solid(src_itr, dst_itr, w); + src_itr += src->stride; + dst_itr += dst->stride; + } +} + +static void +_soft16_image_draw_unscaled_transp_solid(Soft16_Image *src, Soft16_Image *dst, + RGBA_Draw_Context *dc, + int src_offset, int dst_offset, + int w, int h) + +{ + DATA16 *src_itr, *dst_itr; + DATA8 *alpha_itr; + int y; + + src_itr = src->pixels + src_offset; + alpha_itr = src->alpha + src_offset; + dst_itr = dst->pixels + dst_offset; + + for (y = 0; y < h; y++) + { + _soft16_scanline_blend_transp_solid(src_itr, alpha_itr, dst_itr, w); + src_itr += src->stride; + alpha_itr += src->stride; + dst_itr += dst->stride; + } +} + +static inline void +_soft16_image_draw_unscaled_no_mul(Soft16_Image *src, Soft16_Image *dst, + RGBA_Draw_Context *dc, + int src_offset, int dst_offset, + int width, int height) +{ + if (src->flags.have_alpha && (!dst->flags.have_alpha)) + _soft16_image_draw_unscaled_transp_solid(src, dst, dc, + src_offset, dst_offset, + width, height); + else if ((!src->flags.have_alpha) && (!dst->flags.have_alpha)) + _soft16_image_draw_unscaled_solid_solid(src, dst, dc, + src_offset, dst_offset, + width, height); + else + fprintf(stderr, + "Unsupported draw of unscaled images src->flags.have_alpha=%d, " + "dst->flags.have_alpha=%d, WITHOUT COLOR MUL\n", + src->flags.have_alpha, dst->flags.have_alpha); +} + +static void +_soft16_image_draw_unscaled_solid_solid_mul_alpha(Soft16_Image *src, + Soft16_Image *dst, + RGBA_Draw_Context *dc, + int src_offset, + int dst_offset, + int w, int h, DATA8 a) +{ + DATA16 *src_itr, *dst_itr; + int y; + + src_itr = src->pixels + src_offset; + dst_itr = dst->pixels + dst_offset; + + for (y = 0; y < h; y++) + { + _soft16_scanline_blend_solid_solid_mul_alpha(src_itr, dst_itr, w, a); + src_itr += src->stride; + dst_itr += dst->stride; + } +} + +static void +_soft16_image_draw_unscaled_transp_solid_mul_alpha(Soft16_Image *src, + Soft16_Image *dst, + RGBA_Draw_Context *dc, + int src_offset, + int dst_offset, + int w, int h, DATA8 a) + +{ + DATA16 *src_itr, *dst_itr; + DATA8 *alpha_itr; + int y; + + src_itr = src->pixels + src_offset; + alpha_itr = src->alpha + src_offset; + dst_itr = dst->pixels + dst_offset; + + for (y = 0; y < h; y++) + { + _soft16_scanline_blend_transp_solid_mul_alpha(src_itr, alpha_itr, + dst_itr, w, a); + src_itr += src->stride; + alpha_itr += src->stride; + dst_itr += dst->stride; + } +} + +static inline void +_soft16_image_draw_unscaled_mul_alpha(Soft16_Image *src, Soft16_Image *dst, + RGBA_Draw_Context *dc, + int src_offset, int dst_offset, + int width, int height, DATA8 a) +{ + if (src->flags.have_alpha && (!dst->flags.have_alpha)) + _soft16_image_draw_unscaled_transp_solid_mul_alpha + (src, dst, dc, src_offset, dst_offset, width, height, a); + else if ((!src->flags.have_alpha) && (!dst->flags.have_alpha)) + _soft16_image_draw_unscaled_solid_solid_mul_alpha + (src, dst, dc, src_offset, dst_offset, width, height, a); + else + fprintf(stderr, + "Unsupported draw of unscaled images src->flags.have_alpha=%d, " + "dst->flags.have_alpha=%d, WITH ALPHA MUL %d\n", + src->flags.have_alpha, dst->flags.have_alpha, A_VAL(&dc->mul.col)); +} + +static void +_soft16_image_draw_unscaled_solid_solid_mul_color(Soft16_Image *src, + Soft16_Image *dst, + RGBA_Draw_Context *dc, + int src_offset, + int dst_offset, + int w, int h, DATA8 r, + DATA8 g, DATA8 b, DATA8 a) +{ + DATA16 *src_itr, *dst_itr; + int y; + + src_itr = src->pixels + src_offset; + dst_itr = dst->pixels + dst_offset; + + if (a == 31) + for (y = 0; y < h; y++) + { + _soft16_scanline_blend_solid_solid_mul_color_solid + (src_itr, dst_itr, w, r, g, b); + src_itr += src->stride; + dst_itr += dst->stride; + } + else + for (y = 0; y < h; y++) + { + _soft16_scanline_blend_solid_solid_mul_color_transp + (src_itr, dst_itr, w, a, r, g, b); + src_itr += src->stride; + dst_itr += dst->stride; + } +} + +static void +_soft16_image_draw_unscaled_transp_solid_mul_color(Soft16_Image *src, + Soft16_Image *dst, + RGBA_Draw_Context *dc, + int src_offset, + int dst_offset, + int w, int h, DATA8 r, + DATA8 g, DATA8 b, DATA8 a) + +{ + DATA16 *src_itr, *dst_itr; + DATA8 *alpha_itr; + int y; + + src_itr = src->pixels + src_offset; + alpha_itr = src->alpha + src_offset; + dst_itr = dst->pixels + dst_offset; + + if (a == 31) + for (y = 0; y < h; y++) + { + _soft16_scanline_blend_transp_solid_mul_color_solid + (src_itr, alpha_itr, dst_itr, w, r, g, b); + src_itr += src->stride; + alpha_itr += src->stride; + dst_itr += dst->stride; + } + else + for (y = 0; y < h; y++) + { + _soft16_scanline_blend_transp_solid_mul_color_transp + (src_itr, alpha_itr, dst_itr, w, a, r, g, b); + src_itr += src->stride; + alpha_itr += src->stride; + dst_itr += dst->stride; + } +} + +static inline void +_soft16_image_draw_unscaled_mul_color(Soft16_Image *src, Soft16_Image *dst, + RGBA_Draw_Context *dc, + int src_offset, int dst_offset, + int width, int height, + DATA8 r, DATA8 g, DATA8 b, DATA8 a) +{ + if (src->flags.have_alpha && (!dst->flags.have_alpha)) + _soft16_image_draw_unscaled_transp_solid_mul_color + (src, dst, dc, src_offset, dst_offset, width, height, r, g, b, a); + else if ((!src->flags.have_alpha) && (!dst->flags.have_alpha)) + _soft16_image_draw_unscaled_solid_solid_mul_color + (src, dst, dc, src_offset, dst_offset, width, height, r, g, b, a); + else + fprintf(stderr, + "Unsupported draw of unscaled images src->flags.have_alpha=%d, " + "dst->flags.have_alpha=%d, WITH COLOR MUL 0x%08x\n", + src->flags.have_alpha, dst->flags.have_alpha, dc->mul.col); +} + +static inline void +_soft16_image_draw_unscaled_mul(Soft16_Image *src, Soft16_Image *dst, + RGBA_Draw_Context *dc, + int src_offset, int dst_offset, + int width, int height, DATA8 r, DATA8 g, + DATA8 b, DATA8 a) +{ + if ((a == r) && (a == (g >> 1)) && (a == b)) + _soft16_image_draw_unscaled_mul_alpha(src, dst, dc, src_offset, + dst_offset, width, height, a); + else + _soft16_image_draw_unscaled_mul_color(src, dst, dc, src_offset, + dst_offset, width, height, + r, g, b, a); +} + +void +soft16_image_draw_unscaled(Soft16_Image *src, Soft16_Image *dst, + RGBA_Draw_Context *dc, + const Evas_Rectangle sr, + const Evas_Rectangle dr, + const Evas_Rectangle cr) +{ + int src_offset_rows, src_offset, dst_offset; + DATA16 mul_rgb565; + DATA8 r, g, b, a; + + if (!dc->mul.use) + { + r = b = a = 31; + g = 63; + mul_rgb565 = 0xffff; + } + else + { + a = A_VAL(&dc->mul.col) >> 3; + if (a == 0) + return; + + r = R_VAL(&dc->mul.col) >> 3; + g = G_VAL(&dc->mul.col) >> 2; + b = B_VAL(&dc->mul.col) >> 3; + + if (r > a) r = a; + if (g > (a << 1)) g = (a << 1); + if (b > a) b = a; + + mul_rgb565 = (r << 11) || (g << 5) | b; + } + + + src_offset_rows = (cr.y - dr.y) + sr.y; + src_offset = (src_offset_rows * src->stride) + (cr.x - dr.x) + sr.x; + + dst_offset = cr.x + (cr.y * dst->stride); + + if (mul_rgb565 == 0xffff) + _soft16_image_draw_unscaled_no_mul(src, dst, dc, src_offset, dst_offset, + cr.w, cr.h); + else + _soft16_image_draw_unscaled_mul(src, dst, dc, src_offset, dst_offset, + cr.w, cr.h, r, g, b, a); +} diff --git a/legacy/evas/src/lib/engines/common_16/evas_soft16_line.c b/legacy/evas/src/lib/engines/common_16/evas_soft16_line.c new file mode 100644 index 0000000000..dd80afae42 --- /dev/null +++ b/legacy/evas/src/lib/engines/common_16/evas_soft16_line.c @@ -0,0 +1,444 @@ +#include "evas_common_soft16.h" +#include "evas_soft16_scanline_fill.c" + +/* + * All functions except by soft16_line_draw() expect x0 <= x1. + */ + +static inline int +_in_range(int value, int min, int max) +{ + return min <= value && value <= max; +} + +static inline int +_is_xy_inside_clip(int x, int y, const struct RGBA_Draw_Context_clip clip) +{ + if (!clip.use) + return 1; + + if (!_in_range(x, clip.x, clip.x + clip.w - 1)) + return 0; + + if (!_in_range(y, clip.y, clip.y + clip.h - 1)) + return 0; + + return 1; +} + +static inline int +_is_x_inside_clip(int x, const struct RGBA_Draw_Context_clip clip) +{ + if (!clip.use) + return 1; + + return _in_range(x, clip.x, clip.x + clip.w - 1); +} + +static inline int +_is_y_inside_clip(int y, const struct RGBA_Draw_Context_clip clip) +{ + if (!clip.use) + return 1; + + return _in_range(y, clip.y, clip.y + clip.h - 1); +} + +static inline int +_is_xy_inside_rect(int x, int y, int w, int h) +{ + return _in_range(x, 0, w - 1) && _in_range(y, 0, h - 1); +} + +static inline int +_is_empty_clip(const struct RGBA_Draw_Context_clip clip) +{ + return clip.w < 1 || clip.h < 1; +} + +static void +_soft16_line_point(Soft16_Image *dst, RGBA_Draw_Context *dc, int x, int y) +{ + DATA16 rgb565, *dst_itr; + DATA8 alpha; + + if (!_is_xy_inside_rect(x, y, dst->cache_entry.w, dst->cache_entry.h)) + return; + + if (!_is_xy_inside_clip(x, y, dc->clip)) + return; + + dst_itr = dst->pixels + (dst->stride * y) + x; + alpha = A_VAL(&dc->col.col) >> 3; + rgb565 = RGB_565_FROM_COMPONENTS(R_VAL(&dc->col.col), + G_VAL(&dc->col.col), + B_VAL(&dc->col.col)); + + if (alpha == 31) + _soft16_pt_fill_solid_solid(dst_itr, rgb565); + else if (alpha > 0) + { + DATA32 rgb565_unpack; + + rgb565_unpack = RGB_565_UNPACK(rgb565); + alpha++; + _soft16_pt_fill_transp_solid(dst_itr, rgb565_unpack, alpha); + } +} + +static void +_soft16_line_horiz(Soft16_Image *dst, RGBA_Draw_Context *dc, int x0, int x1, int y) +{ + DATA16 rgb565, *dst_itr; + DATA8 alpha; + int w; + + if (!_is_y_inside_clip(y, dc->clip)) + return; + + if (x0 < dc->clip.x) + x0 = dc->clip.x; + + if (x1 >= dc->clip.x + dc->clip.w) + x1 = dc->clip.x + dc->clip.w - 1; + + w = x1 - x0; + if (w < 1) + return; + + dst_itr = dst->pixels + (dst->stride * y) + x0; + alpha = A_VAL(&dc->col.col) >> 3; + rgb565 = RGB_565_FROM_COMPONENTS(R_VAL(&dc->col.col), + G_VAL(&dc->col.col), + B_VAL(&dc->col.col)); + + if (alpha == 31) + _soft16_scanline_fill_solid_solid(dst_itr, w, rgb565); + else if (alpha > 0) + { + DATA32 rgb565_unpack; + + rgb565_unpack = RGB_565_UNPACK(rgb565); + alpha++; + _soft16_scanline_fill_transp_solid(dst_itr, w, rgb565_unpack, alpha); + } +} + +static void +_soft16_line_vert(Soft16_Image *dst, RGBA_Draw_Context *dc, int x, int y0, int y1) +{ + DATA16 rgb565, *dst_itr; + DATA8 alpha; + int h; + + if (!_is_x_inside_clip(x, dc->clip)) + return; + + if (y1 < y0) + { + int t; + t = y0; + y0 = y1; + y1 = t; + } + + if (y0 < dc->clip.y) + y0 = dc->clip.y; + + if (y1 >= dc->clip.y + dc->clip.h) + y1 = dc->clip.y + dc->clip.h - 1; + + h = y1 - y0; + if (h < 1) + return; + + dst_itr = dst->pixels + (dst->stride * y0) + x; + alpha = A_VAL(&dc->col.col) >> 3; + rgb565 = RGB_565_FROM_COMPONENTS(R_VAL(&dc->col.col), + G_VAL(&dc->col.col), + B_VAL(&dc->col.col)); + + if (alpha == 31) + { + for (; h > 0; h--, dst_itr += dst->stride) + _soft16_pt_fill_solid_solid(dst_itr, rgb565); + } + else if (alpha > 0) + { + DATA32 rgb565_unpack; + + rgb565_unpack = RGB_565_UNPACK(rgb565); + alpha++; + + for (; h > 0; h--, dst_itr += dst->stride) + _soft16_pt_fill_transp_solid(dst_itr, rgb565_unpack, alpha); + } +} + +static inline void +_soft16_line_45deg_adjust_boundaries(const struct RGBA_Draw_Context_clip clip, int *p_x0, int *p_y0, int *p_x1, int *p_y1) +{ + int diff, dy, x0, y0, x1, y1; + + x0 = *p_x0; + y0 = *p_y0; + x1 = *p_x1; + y1 = *p_y1; + + dy = y1 - y0; + + diff = clip.x - x0; + if (diff > 0) + { + x0 = clip.x; + y0 += (dy > 0) ? diff : -diff; + } + + diff = x1 - (clip.x + clip.w); + if (diff > 0) + { + x1 = clip.x + clip.w; + y1 += (dy > 0) ? -diff : diff; + } + + if (dy > 0) + { + diff = clip.y - y0; + if (diff > 0) + { + y0 = clip.y; + x0 += diff; + } + + diff = y1 - (clip.y + clip.h); + if (diff > 0) + { + y1 = clip.y + clip.h; + x1 -= diff; + } + } + else + { + diff = clip.y - y1; + if (diff > 0) + { + y1 = clip.y; + x1 -= diff; + } + + diff = y0 - (clip.y + clip.h - 1); + if (diff > 0) + { + y0 = clip.y + clip.h - 1; + x0 += diff; + } + } + + *p_x0 = x0; + *p_y0 = y0; + *p_x1 = x1; + *p_y1 = y1; +} + +static void +_soft16_line_45deg(Soft16_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x1, int y1) +{ + int dy, step_dst_itr, len; + DATA8 alpha; + DATA16 *dst_itr, rgb565; + + alpha = A_VAL(&dc->col.col) >> 3; + if (alpha < 1) + return; + + rgb565 = RGB_565_FROM_COMPONENTS(R_VAL(&dc->col.col), + G_VAL(&dc->col.col), + B_VAL(&dc->col.col)); + + dy = y1 - y0; + step_dst_itr = 1 + ((dy > 0) ? dst->stride : -dst->stride); + + _soft16_line_45deg_adjust_boundaries(dc->clip, &x0, &y0, &x1, &y1); + + len = (dy > 0) ? (y1 - y0) : (y0 - y1); + if (len < 1) + return; + + dst_itr = dst->pixels + dst->stride * y0 + x0; + if (alpha == 31) + { + for (; len > 0; len--, dst_itr += step_dst_itr) + _soft16_pt_fill_solid_solid(dst_itr, rgb565); + } + else + { + DATA32 rgb565_unpack; + + rgb565_unpack = RGB_565_UNPACK(rgb565); + alpha++; + for (; len > 0; len--, dst_itr += step_dst_itr) + _soft16_pt_fill_transp_solid(dst_itr, rgb565_unpack, alpha); + } +} + +static always_inline void +_soft16_line_aliased_pt(DATA16 *dst_itr, DATA16 rgb565, DATA32 rgb565_unpack, DATA8 alpha) +{ + if (alpha == 32) + _soft16_pt_fill_solid_solid(dst_itr, rgb565); + else + _soft16_pt_fill_transp_solid(dst_itr, rgb565_unpack, alpha); +} + +static void +_soft16_line_aliased(Soft16_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x1, int y1) +{ + int dx, dy, step_y, step_dst_itr; + DATA32 rgb565_unpack; + DATA16 rgb565; + DATA8 alpha; + + alpha = A_VAL(&dc->col.col) >> 3; + if (alpha == 0) + return; + alpha++; + + rgb565 = RGB_565_FROM_COMPONENTS(R_VAL(&dc->col.col), + G_VAL(&dc->col.col), + B_VAL(&dc->col.col)); + rgb565_unpack = RGB_565_UNPACK(rgb565); + + dx = x1 - x0; + dy = y1 - y0; + + if (dy >= 0) + { + step_y = 1; + step_dst_itr = dst->stride; + } + else + { + dy = -dy; + step_y = -1; + step_dst_itr = -dst->stride; + } + + if (dx > dy) + { + DATA16 *dst_itr; + int e, x, y; + + e = - (dx / 2); + y = y0; + dst_itr = dst->pixels + dst->stride * y0 + x0; + for (x=x0; x <= x1; x++, dst_itr++) + { + if (_is_xy_inside_clip(x, y, dc->clip)) + _soft16_line_aliased_pt(dst_itr, rgb565, rgb565_unpack, alpha); + + e += dy; + if (e >= 0) + { + dst_itr += step_dst_itr; + y += step_y; + e -= dx; + } + } + } + else + { + DATA16 *dst_itr; + int e, x, y; + + e = - (dy / 2); + x = x0; + dst_itr = dst->pixels + dst->stride * y0 + x0; + for (y=y0; y != y1; y += step_y, dst_itr += step_dst_itr) + { + if (_is_xy_inside_clip(x, y, dc->clip)) + _soft16_line_aliased_pt(dst_itr, rgb565, rgb565_unpack, alpha); + + e += dx; + if (e >= 0) + { + dst_itr++; + x++; + e -= dy; + } + } + } +} + +void +soft16_line_draw(Soft16_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x1, int y1) +{ + struct RGBA_Draw_Context_clip c_bkp, c_tmp; + int dx, dy; + int x, y, w, h; + + c_tmp.use = 1; + c_tmp.x = 0; + c_tmp.y = 0; + c_tmp.w = dst->cache_entry.w; + c_tmp.h = dst->cache_entry.h; + + /* save out clip info */ + c_bkp = dc->clip; + if (c_bkp.use) + { + RECTS_CLIP_TO_RECT(c_tmp.x, c_tmp.y, c_tmp.w, c_tmp.h, + c_bkp.x, c_bkp.y, c_bkp.w, c_bkp.h); + if (_is_empty_clip(c_tmp)) + return; + } + + x = MIN(x0, x1); + y = MIN(y0, y1); + w = MAX(x0, x1) - x + 1; + h = MAX(y0, y1) - y + 1; + + RECTS_CLIP_TO_RECT(c_tmp.x, c_tmp.y, c_tmp.w, c_tmp.h, x, y, w, h); + if (_is_empty_clip(c_tmp)) + return; + + /* Check if the line doesn't cross the clip area */ + if (x0 < c_tmp.x && x1 < c_tmp.x) + return; + if (x0 >= c_tmp.x + c_tmp.w && x1 >= c_tmp.x + c_tmp.w) + return; + if (y0 < c_tmp.y && y1 < c_tmp.y) + return; + if (y0 >= c_tmp.y + c_tmp.h && y1 >= c_tmp.y + c_tmp.h) + return; + + dc->clip = c_tmp; + dx = x1 - x0; + dy = y1 - y0; + + if (dx < 0) + { + int t; + + t = x0; + x0 = x1; + x1 = t; + + t = y0; + y0 = y1; + y1 = t; + } + + if (dx == 0 && dy == 0) + _soft16_line_point(dst, dc, x0, y0); + else if (dx == 0) + _soft16_line_vert(dst, dc, x0, y0, y1); + else if (dy == 0) + _soft16_line_horiz(dst, dc, x0, x1, y0); + else if (dy == dx || dy == -dx) + _soft16_line_45deg(dst, dc, x0, y0, x1, y1); + else + _soft16_line_aliased(dst, dc, x0, y0, x1, y1); + + /* restore clip info */ + dc->clip = c_bkp; +} diff --git a/legacy/evas/src/lib/engines/common_16/evas_soft16_main.c b/legacy/evas/src/lib/engines/common_16/evas_soft16_main.c new file mode 100644 index 0000000000..8592b4a003 --- /dev/null +++ b/legacy/evas/src/lib/engines/common_16/evas_soft16_main.c @@ -0,0 +1,596 @@ +#include "evas_common_soft16.h" + +static Evas_Cache_Image *eci = NULL; +static int reference = 0; + +static Image_Entry *_evas_common_soft16_image_new(void); +static void _evas_common_soft16_image_delete(Image_Entry *ie); + +static int _evas_common_soft16_image_surface_alloc(Image_Entry *ie, int w, int h); +static void _evas_common_soft16_image_surface_delete(Image_Entry *ie); + +static int _evas_common_load_soft16_image_from_file(Image_Entry *ie); +static void _evas_common_soft16_image_unload(Image_Entry *ie); + +static void _evas_common_soft16_image_dirty_region(Image_Entry *im, int x, int y, int w, int h); +static int _evas_common_soft16_image_dirty(Image_Entry *ie_dst, const Image_Entry *ie_src); + +static int _evas_common_soft16_image_ram_usage(Image_Entry *ie); + +static int _evas_common_soft16_image_size_set(Image_Entry *ie_dst, const Image_Entry *ie_im, int w, int h); +static int _evas_common_soft16_image_from_copied_data(Image_Entry* ie_dst, int w, int h, DATA32 *image_data, int alpha, int cspace); +static int _evas_common_soft16_image_from_data(Image_Entry* ie_dst, int w, int h, DATA32 *image_data, int alpha, int cspace); +static int _evas_common_soft16_image_colorspace_set(Image_Entry* ie_dst, int cspace); + +static int _evas_common_load_soft16_image_data_from_file(Image_Entry *ie); + +static void +_evas_common_soft16_image_debug(const char* context, Image_Entry *eim) +{ + fprintf(stderr, "[16] %p = [%s] {%s,%s} %i [%i|%i]\n", eim, context, eim->file, eim->key, eim->references, eim->w, eim->h); +} + +static const Evas_Cache_Image_Func _evas_common_soft16_image_func = +{ + _evas_common_soft16_image_new, + _evas_common_soft16_image_delete, + _evas_common_soft16_image_surface_alloc, + _evas_common_soft16_image_surface_delete, + _evas_common_load_soft16_image_from_file, + _evas_common_soft16_image_unload, + _evas_common_soft16_image_dirty_region, + _evas_common_soft16_image_dirty, + _evas_common_soft16_image_size_set, + _evas_common_soft16_image_from_copied_data, + _evas_common_soft16_image_from_data, + _evas_common_soft16_image_colorspace_set, + _evas_common_load_soft16_image_data_from_file, + _evas_common_soft16_image_ram_usage, +/* _evas_common_soft16_image_debug */ + NULL +}; + +EAPI void +evas_common_soft16_image_init(void) +{ + if (!eci) + eci = evas_cache_image_init(&_evas_common_soft16_image_func); + reference++; +} + +EAPI void +evas_common_soft16_image_shutdown(void) +{ + if (--reference == 0) + { +// DISABLE for now - something wrong with cache shutdown freeing things +// still in use - rage_thumb segv's now. +// +// actually - i think i see it. cache ref goes to 0 (and thus gets freed) +// because in eng_setup() when a buffer changes size it is FIRST freed +// THEN allocated again - thus brignhjing ref to 0 then back to 1 immediately +// where it should stay at 1. - see evas_engine.c in the buffer enigne for +// example. eng_output_free() is called BEFORE _output_setup(). although this +// is only a SIGNE of the problem. we can patch this up with either freeing +// after the setup (so we just pt a ref of 2 then back to 1), or just +// evas_common_image_init() at the start and evas_common_image_shutdown() +// after it all. really ref 0 should only be reached when no more canvases +// with no more objects exist anywhere. +// evas_cache_image_shutdown(eci); +// eci = NULL; + } +} + +EAPI Evas_Cache_Image * +evas_common_soft16_image_cache_get(void) +{ + return eci; +} + +static Image_Entry * +_evas_common_soft16_image_new(void) +{ + Soft16_Image *im; + + im = malloc(sizeof (Soft16_Image)); + if (!im) return NULL; + + im->stride = -1; + im->pixels = NULL; + im->alpha = NULL; + /* When is have_alpha set ? */ + im->flags.have_alpha = 0; + im->flags.free_pixels = 0; + im->flags.free_alpha = 0; + + return (Image_Entry *) im; +} + +static void +_evas_common_soft16_image_delete(Image_Entry *ie) +{ + memset(ie, 0xFF, sizeof (Soft16_Image)); + free(ie); +} + +static int +_evas_common_soft16_image_surface_alloc(Image_Entry *ie, int w, int h) +{ + Soft16_Image *im = (Soft16_Image *) ie; + + if (im->stride < 0) im->stride = _calc_stride(w); + + im->pixels = realloc(im->pixels, IMG_BYTE_SIZE(im->stride, h, im->flags.have_alpha)); + if (!im->pixels) return -1; + + if (im->flags.have_alpha) + { + im->alpha = (DATA8 *)(im->pixels + (im->stride * h)); + im->flags.free_alpha = 0; + } + im->flags.free_pixels = 1; + + return 0; +} + +static void +_evas_common_soft16_image_surface_delete(Image_Entry *ie) +{ + Soft16_Image *im = (Soft16_Image *) ie; + + if (im->flags.free_pixels) + free(im->pixels); + im->pixels = NULL; + im->flags.free_pixels = 0; + + if (im->flags.free_alpha) + free(im->alpha); + im->alpha = NULL; + im->flags.free_alpha = 0; +} + +static int +_evas_common_load_soft16_image_from_file(Image_Entry *ie) +{ + Soft16_Image *sim = (Soft16_Image *) ie; + RGBA_Image *im; + int error = 0; + + im = (RGBA_Image *) evas_cache_image_request(evas_common_image_cache_get(), sim->cache_entry.file, sim->cache_entry.key, &sim->cache_entry.load_opts, &error); + sim->source = im; + if (!sim->source) return -1; + + sim->cache_entry.w = sim->source->cache_entry.w; + sim->cache_entry.h = sim->source->cache_entry.h; + sim->flags.have_alpha = !!(im->flags & RGBA_IMAGE_HAS_ALPHA); + + return 0; +} + +static void +_evas_common_soft16_image_unload(Image_Entry *ie) +{ +} + +static void +_evas_common_soft16_image_dirty_region(Image_Entry *im, int x, int y, int w, int h) +{ +} + +static int +_evas_common_soft16_image_dirty(Image_Entry *ie_dst, const Image_Entry *ie_src) +{ + Soft16_Image *dst = (Soft16_Image *) ie_dst; + Soft16_Image *src = (Soft16_Image *) ie_src; + + evas_cache_image_load_data(&src->cache_entry); + evas_cache_image_surface_alloc(&dst->cache_entry, + src->cache_entry.w, src->cache_entry.h); + +/* evas_common_blit_rectangle(src, dst, 0, 0, src->cache_entry.w, src->cache_entry.h, 0, 0); */ + + return 0; +} + +static int +_evas_common_soft16_image_ram_usage(Image_Entry *ie) +{ + Soft16_Image *im = (Soft16_Image *) ie; + + if (im->pixels && im->flags.free_pixels) + return IMG_BYTE_SIZE(im->stride, im->cache_entry.h, im->flags.have_alpha); + return 0; +} + +static int +_evas_common_soft16_image_size_set(Image_Entry *ie_dst, const Image_Entry *ie_im, int w, int h) +{ + Soft16_Image *dst = (Soft16_Image *) ie_dst; + Soft16_Image *im = (Soft16_Image *) ie_im; + + dst->flags = im->flags; + + return 0; +} + +static int +_evas_common_soft16_image_from_data(Image_Entry* ie_dst, int w, int h, DATA32 *image_data, int alpha, int cspace) +{ + Soft16_Image *im = (Soft16_Image *) ie_dst; + + /* FIXME: handle colorspace */ + ie_dst->w = w; + ie_dst->h = h; + + im->flags.have_alpha = alpha; + im->flags.free_pixels = 0; + im->flags.free_alpha = 0; + + /* FIXME: That's bad, the application must be aware of the engine internal. */ + im->pixels = (DATA16 *) image_data; + if (im->flags.have_alpha) + im->alpha = (DATA8 *)(im->pixels + (im->stride * h)); + + return 0; +} + +static int +_evas_common_soft16_image_from_copied_data(Image_Entry* ie_dst, int w, int h, DATA32 *image_data, int alpha, int cspace) +{ + Soft16_Image *im = (Soft16_Image *) ie_dst; + + /* FIXME: handle colorspace */ + im->flags.have_alpha = alpha; + evas_cache_image_surface_alloc(ie_dst, w, h); + if (image_data) + memcpy(im->pixels, image_data, IMG_BYTE_SIZE(im->stride, h, im->flags.have_alpha)); + else + memset(im->pixels, 0, IMG_BYTE_SIZE(im->stride, h, im->flags.have_alpha)); + + return 0; +} + +static int +_evas_common_soft16_image_colorspace_set(Image_Entry* ie_dst, int cspace) +{ + /* FIXME: handle colorspace */ + return 0; +} + +static int +_evas_common_load_soft16_image_data_from_file(Image_Entry *ie) +{ + Soft16_Image *im = (Soft16_Image *) ie; + + if (im->pixels) return 0; + if (!im->source) return -1; + + evas_cache_image_load_data(&im->source->cache_entry); + if (im->source->image.data) + { + DATA32 *sp; + + evas_cache_image_surface_alloc(&im->cache_entry, + im->source->cache_entry.w, + im->source->cache_entry.h); + + sp = im->source->image.data; + if (im->alpha) + soft16_image_convert_from_rgba(im, sp); + else + soft16_image_convert_from_rgb(im, sp); + } + evas_cache_image_drop(&im->source->cache_entry); + im->source = NULL; + + return 0; +} + +/* Soft16_Image * */ +/* soft16_image_new(int w, int h, int stride, int have_alpha, DATA16 *pixels, */ +/* int copy) */ +/* { */ +/* Soft16_Image *im; */ + +/* if (stride < 0) stride = _calc_stride(w); */ + +/* im = soft16_image_alloc(w, h, stride, have_alpha, copy); */ +/* if (!im) return NULL; */ + +/* if (pixels) */ +/* { */ +/* if (copy) */ +/* memcpy(im->pixels, pixels, IMG_BYTE_SIZE(stride, h, have_alpha)); */ +/* else */ +/* { */ +/* im->pixels = pixels; */ +/* if (have_alpha) im->alpha = (DATA8 *)(im->pixels + (stride * h)); */ +/* } */ +/* } */ +/* return im; */ +/* } */ + +static inline void +_get_clip(const RGBA_Draw_Context *dc, const Soft16_Image *im, + Evas_Rectangle *clip) +{ + if (dc->clip.use) + { + clip->x = dc->clip.x; + clip->y = dc->clip.y; + clip->w = dc->clip.w; + clip->h = dc->clip.h; + if (clip->x < 0) + { + clip->w += clip->x; + clip->x = 0; + } + if (clip->y < 0) + { + clip->h += clip->y; + clip->y = 0; + } + if ((clip->x + clip->w) > im->cache_entry.w) clip->w = im->cache_entry.w - clip->x; + if ((clip->y + clip->h) > im->cache_entry.h) clip->h = im->cache_entry.h - clip->y; + } + else + { + clip->x = 0; + clip->y = 0; + clip->w = im->cache_entry.w; + clip->h = im->cache_entry.h; + } +} + +static inline int +_is_empty_rectangle(const Evas_Rectangle *r) +{ + return (r->w < 1) || (r->h < 1); +} + +static inline void +_shrink(int *s_pos, int *s_size, int pos, int size) +{ + int d; + + d = (*s_pos) - pos; + if (d < 0) + { + (*s_size) += d; + (*s_pos) = pos; + } + + d = size + pos - (*s_pos); + if ((*s_size) > d) + (*s_size) = d; +} + +static int +_soft16_adjust_areas(Evas_Rectangle *src, + int src_max_x, int src_max_y, + Evas_Rectangle *dst, + int dst_max_x, int dst_max_y, + Evas_Rectangle *dst_clip) +{ + if (_is_empty_rectangle(src) || + _is_empty_rectangle(dst) || + _is_empty_rectangle(dst_clip)) + return 0; + + /* shrink clip */ + _shrink(&dst_clip->x, &dst_clip->w, dst->x, dst->w); + _shrink(&dst_clip->y, &dst_clip->h, dst->y, dst->h); + if (_is_empty_rectangle(dst_clip)) return 0; + + /* sanitise x */ + if (src->x < 0) + { + dst->x -= (src->x * dst->w) / src->w; + dst->w += (src->x * dst->w) / src->w; + src->w += src->x; + src->x = 0; + } + if (src->x >= src_max_x) return 0; + if ((src->x + src->w) > src_max_x) + { + dst->w = (dst->w * (src_max_x - src->x)) / (src->w); + src->w = src_max_x - src->x; + } + if (dst->w <= 0) return 0; + if (src->w <= 0) return 0; + if (dst_clip->x < 0) + { + dst_clip->w += dst_clip->x; + dst_clip->x = 0; + } + if (dst_clip->w <= 0) return 0; + if (dst_clip->x >= dst_max_x) return 0; + + _shrink(&dst_clip->x, &dst_clip->w, 0, dst_max_x); + if (dst_clip->w <= 0) return 0; + + /* sanitise y */ + if (src->y < 0) + { + dst->y -= (src->y * dst->h) / src->h; + dst->h += (src->y * dst->h) / src->h; + src->h += src->y; + src->y = 0; + } + if (src->y >= src_max_y) return 0; + if ((src->y + src->h) > src_max_y) + { + dst->h = (dst->h * (src_max_y - src->y)) / (src->h); + src->h = src_max_y - src->y; + } + if (dst->h <= 0) return 0; + if (src->h <= 0) return 0; + if (dst_clip->y < 0) + { + dst_clip->h += dst_clip->y; + dst_clip->y = 0; + } + if (dst_clip->h <= 0) return 0; + if (dst_clip->y >= dst_max_y) return 0; + + _shrink(&dst_clip->y, &dst_clip->h, 0, dst_max_y); + if (dst_clip->h <= 0) return 0; + + return 1; +} + +static void +_soft16_image_draw_sampled_int(Soft16_Image *src, Soft16_Image *dst, + RGBA_Draw_Context *dc, + Evas_Rectangle sr, Evas_Rectangle dr) +{ + Evas_Rectangle cr; + + if (!(RECTS_INTERSECT(dr.x, dr.y, dr.w, dr.h, 0, 0, dst->cache_entry.w, dst->cache_entry.h))) + return; + if (!(RECTS_INTERSECT(sr.x, sr.y, sr.w, sr.h, 0, 0, src->cache_entry.w, src->cache_entry.h))) + return; + + _get_clip(dc, dst, &cr); + if (!_soft16_adjust_areas(&sr, src->cache_entry.w, src->cache_entry.h, &dr, dst->cache_entry.w, dst->cache_entry.h, &cr)) + return; + + if ((dr.w == sr.w) && (dr.h == sr.h)) + soft16_image_draw_unscaled(src, dst, dc, sr, dr, cr); + else + soft16_image_draw_scaled_sampled(src, dst, dc, sr, dr, cr); +} + +EAPI void +soft16_image_draw(Soft16_Image *src, Soft16_Image *dst, + RGBA_Draw_Context *dc, + int src_region_x, int src_region_y, + int src_region_w, int src_region_h, + int dst_region_x, int dst_region_y, + int dst_region_w, int dst_region_h, + int smooth) +{ + Evas_Rectangle sr, dr; + Cutout_Rects *rects; + Cutout_Rect *r; + struct RGBA_Draw_Context_clip clip_bkp; + int i; + + /* handle cutouts here! */ + dr.x = dst_region_x; + dr.y = dst_region_y; + dr.w = dst_region_w; + dr.h = dst_region_h; + + if (_is_empty_rectangle(&dr)) return; + if (!(RECTS_INTERSECT(dr.x, dr.y, dr.w, dr.h, 0, 0, dst->cache_entry.w, dst->cache_entry.h))) + return; + + sr.x = src_region_x; + sr.y = src_region_y; + sr.w = src_region_w; + sr.h = src_region_h; + + if (_is_empty_rectangle(&sr)) return; + if (!(RECTS_INTERSECT(sr.x, sr.y, sr.w, sr.h, 0, 0, src->cache_entry.w, src->cache_entry.h))) + return; + + /* no cutouts - cut right to the chase */ + if (!dc->cutout.rects) + { + _soft16_image_draw_sampled_int(src, dst, dc, sr, dr); + return; + } + + /* save out clip info */ + clip_bkp = dc->clip; + evas_common_draw_context_clip_clip(dc, 0, 0, dst->cache_entry.w, dst->cache_entry.h); + evas_common_draw_context_clip_clip(dc, dst_region_x, dst_region_y, dst_region_w, dst_region_h); + /* our clip is 0 size.. abort */ + if ((dc->clip.w <= 0) || (dc->clip.h <= 0)) + { + dc->clip = clip_bkp; + return; + } + rects = evas_common_draw_context_apply_cutouts(dc); + for (i = 0; i < rects->active; i++) + { + r = rects->rects + i; + evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h); + _soft16_image_draw_sampled_int(src, dst, dc, sr, dr); + } + evas_common_draw_context_apply_clear_cutouts(rects); + dc->clip = clip_bkp; +} + +EAPI Soft16_Image * +soft16_image_alpha_set(Soft16_Image *im, int have_alpha) +{ + Soft16_Image *new_im; + + if (im->flags.have_alpha == have_alpha) return im; + + new_im = (Soft16_Image *) evas_cache_image_alone(&im->cache_entry); + + new_im->flags.have_alpha = have_alpha; + + if (im->cache_entry.w > 0 + && im->cache_entry.h) + new_im = (Soft16_Image *) evas_cache_image_size_set(&new_im->cache_entry, im->cache_entry.w, im->cache_entry.h); + + return new_im; +} + +/* Soft16_Image * */ +/* soft16_image_size_set(Soft16_Image *old_im, int w, int h) */ +/* { */ +/* Soft16_Image *new_im; */ +/* DATA16 *dp, *sp; */ +/* int i, cw, ch, ew; */ + +/* if ((old_im->cache_entry.w == w) && (old_im->cache_entry.h == h)) return old_im; */ + +/* new_im = soft16_image_new(w, h, -1, old_im->flags.have_alpha, NULL, 1); */ + +/* if (old_im->cache_entry.w < new_im->cache_entry.w) */ +/* cw = old_im->cache_entry.w; */ +/* else */ +/* cw = new_im->cache_entry.w; */ + +/* ew = new_im->cache_entry.w - cw; */ + +/* if (old_im->cache_entry.h < new_im->cache_entry.h) */ +/* ch = old_im->cache_entry.h; */ +/* else */ +/* ch = new_im->cache_entry.h; */ + +/* dp = new_im->pixels; */ +/* sp = old_im->pixels; */ +/* for (i = 0; i < ch; i++) */ +/* { */ +/* memcpy(dp, sp, cw * sizeof(DATA16)); */ +/* if (ew > 0) memset(dp, 0, ew * sizeof(DATA16)); */ + +/* dp += new_im->stride; */ +/* sp += old_im->stride; */ +/* } */ + +/* if (old_im->flags.have_alpha) */ +/* { */ +/* DATA8 *dp, *sp; */ + +/* dp = new_im->alpha; */ +/* sp = old_im->alpha; */ +/* for (i = 0; i < ch; i++) */ +/* { */ +/* memcpy(dp, sp, cw * sizeof(DATA8)); */ +/* if (ew > 0) memset(dp, 0, ew * sizeof(DATA8)); */ + +/* dp += new_im->stride; */ +/* sp += old_im->stride; */ +/* } */ +/* } */ + +/* evas_cache_image_drop(&old_im->cache_entry); */ +/* return new_im; */ +/* } */ diff --git a/legacy/evas/src/lib/engines/common_16/evas_soft16_polygon.c b/legacy/evas/src/lib/engines/common_16/evas_soft16_polygon.c new file mode 100644 index 0000000000..1a60995dd8 --- /dev/null +++ b/legacy/evas/src/lib/engines/common_16/evas_soft16_polygon.c @@ -0,0 +1,231 @@ +#include +#include "evas_soft16_scanline_fill.c" +#include + +typedef struct _RGBA_Edge RGBA_Edge; +typedef struct _RGBA_Vertex RGBA_Vertex; + +struct _RGBA_Edge +{ + float x, dx; + int i; +}; + +struct _RGBA_Vertex +{ + float x, y; + int i; +}; + +#define POLY_EDGE_DEL(_i) \ +{ \ + int _j; \ + \ + for (_j = 0; (_j < num_active_edges) && (edges[_j].i != _i); _j++); \ + if (_j < num_active_edges) \ + { \ + num_active_edges--; \ + memmove(&(edges[_j]), &(edges[_j + 1]), \ + (num_active_edges - _j) * sizeof(RGBA_Edge)); \ + } \ +} + +#define POLY_EDGE_ADD(_i, _y) \ +{ \ + int _j; \ + float _dx; \ + RGBA_Vertex *_p, *_q; \ + if (_i < (n - 1)) _j = _i + 1; \ + else _j = 0; \ + if (point[_i].y < point[_j].y) \ + { \ + _p = &(point[_i]); \ + _q = &(point[_j]); \ + } \ + else \ + { \ + _p = &(point[_j]); \ + _q = &(point[_i]); \ + } \ + edges[num_active_edges].dx = _dx = (_q->x - _p->x) / (_q->y - _p->y); \ + edges[num_active_edges].x = (_dx * ((float)_y + 0.5 - _p->y)) + _p->x; \ + edges[num_active_edges].i = _i; \ + num_active_edges++; \ +} + +static int +polygon_point_sorter(const void *a, const void *b) +{ + RGBA_Vertex *p, *q; + + p = (RGBA_Vertex *)a; + q = (RGBA_Vertex *)b; + if (p->y <= q->y) return -1; + return 1; +} + +static int +polygon_edge_sorter(const void *a, const void *b) +{ + RGBA_Edge *p, *q; + + p = (RGBA_Edge *)a; + q = (RGBA_Edge *)b; + if (p->x <= q->x) return -1; + return 1; +} + +void +soft16_polygon_draw(Soft16_Image *dst, RGBA_Draw_Context *dc, RGBA_Polygon_Point *points) +{ + RGBA_Polygon_Point *pt; + RGBA_Vertex *point; + RGBA_Edge *edges; + Evas_Object_List *l; + int num_active_edges; + int n; + int i, j, k; + int y0, y1, y; + int ext_x, ext_y, ext_w, ext_h; + int *sorted_index; + DATA8 alpha; + DATA16 rgb565; + DATA32 rgb565_unpack; + + alpha = A_VAL(&dc->col.col) >> 3; + if (alpha == 0) + return; + alpha++; + + rgb565 = RGB_565_FROM_COMPONENTS(R_VAL(&dc->col.col), + G_VAL(&dc->col.col), + B_VAL(&dc->col.col)); + rgb565_unpack = RGB_565_UNPACK(rgb565); + + ext_x = 0; + ext_y = 0; + ext_w = dst->cache_entry.w; + ext_h = dst->cache_entry.h; + if (dc->clip.use) + RECTS_CLIP_TO_RECT(ext_x, ext_y, ext_w, ext_h, + dc->clip.x, dc->clip.y, dc->clip.w, dc->clip.h); + + if ((ext_w <= 0) || (ext_h <= 0)) + return; + + n = 0; + for (l = (Evas_Object_List *)points; l; l = l->next) + n++; + + if (n < 3) + return; + + edges = malloc(sizeof(RGBA_Edge) * n); + if (!edges) + return; + + point = malloc(sizeof(RGBA_Vertex) * n); + if (!point) + { + free(edges); + return; + } + + sorted_index = malloc(sizeof(int) * n); + if (!sorted_index) + { + free(edges); + free(point); + return; + } + + for (k = 0, l = (Evas_Object_List *)points; l; k++, l = l->next) + { + pt = (RGBA_Polygon_Point *)l; + point[k].x = pt->x; + point[k].y = pt->y; + point[k].i = k; + } + qsort(point, n, sizeof(RGBA_Vertex), polygon_point_sorter); + + for (k = 0; k < n; k++) + sorted_index[k] = point[k].i; + + for (k = 0, l = (Evas_Object_List *)points; l; k++, l = l->next) + { + pt = (RGBA_Polygon_Point *)l; + point[k].x = pt->x; + point[k].y = pt->y; + point[k].i = k; + } + + y0 = MAX(ext_y, ceil(point[sorted_index[0]].y - 0.5)); + y1 = MIN(ext_y + ext_h - 1, floor(point[sorted_index[n - 1]].y - 0.5)); + + k = 0; + num_active_edges = 0; + + for (y = y0; y <= y1; y++) + { + for (; (k < n) && (point[sorted_index[k]].y <= ((float)y + 0.5)); k++) + { + i = sorted_index[k]; + + if (i > 0) j = i - 1; + else j = n - 1; + if (point[j].y <= ((float)y - 0.5)) + { + POLY_EDGE_DEL(j) + } + else if (point[j].y > ((float)y + 0.5)) + { + POLY_EDGE_ADD(j, y) + } + if (i < (n - 1)) j = i + 1; + else j = 0; + if (point[j].y <= ((float)y - 0.5)) + { + POLY_EDGE_DEL(i) + } + else if (point[j].y > ((float)y + 0.5)) + { + POLY_EDGE_ADD(i, y) + } + } + + qsort(edges, num_active_edges, sizeof(RGBA_Edge), polygon_edge_sorter); + + for (j = 0; j < num_active_edges; j += 2) + { + int x0, x1; + + x0 = ceil(edges[j].x - 0.5); + if (j < (num_active_edges - 1)) + x1 = floor(edges[j + 1].x - 0.5); + else + x1 = x0; + if ((x1 >= ext_x) && (x0 < (ext_x + ext_w)) && (x0 <= x1)) + { + DATA16 *dst_itr; + int w; + + if (x0 < ext_x) x0 = ext_x; + if (x1 >= (ext_x + ext_w)) x1 = ext_x + ext_w - 1; + + w = (x1 - x0) + 1; + dst_itr = dst->pixels + (y * dst->stride) + x0; + + if (alpha == 32) + _soft16_scanline_fill_solid_solid(dst_itr, w, rgb565); + else + _soft16_scanline_fill_transp_solid(dst_itr, w, rgb565_unpack, alpha); + } + edges[j].x += edges[j].dx; + edges[j + 1].x += edges[j + 1].dx; + } + } + + free(edges); + free(point); + free(sorted_index); +} diff --git a/legacy/evas/src/lib/engines/common_16/evas_soft16_rectangle.c b/legacy/evas/src/lib/engines/common_16/evas_soft16_rectangle.c new file mode 100644 index 0000000000..0119b8b1ca --- /dev/null +++ b/legacy/evas/src/lib/engines/common_16/evas_soft16_rectangle.c @@ -0,0 +1,126 @@ +#include "evas_common_soft16.h" +#include "evas_soft16_scanline_fill.c" + +static inline int +_is_empty_rectangle(const Evas_Rectangle *r) +{ + return (r->w < 1) || (r->h < 1); +} + +static inline void +_soft16_rectangle_draw_solid_solid(Soft16_Image *dst, int offset, int w, int h, + DATA16 rgb565) +{ + DATA16 *dst_itr; + int i; + + dst_itr = dst->pixels + offset; + + for (i = 0; i < h; i++, dst_itr += dst->stride) + _soft16_scanline_fill_solid_solid(dst_itr, w, rgb565); +} + +static inline void +_soft16_rectangle_draw_transp_solid(Soft16_Image *dst, int offset, int w, int h, + DATA16 rgb565, DATA8 alpha) +{ + DATA16 *dst_itr; + DATA32 rgb565_unpack; + int i; + + dst_itr = dst->pixels + offset; + rgb565_unpack = RGB_565_UNPACK(rgb565); + alpha++; + + for (i = 0; i < h; i++, dst_itr += dst->stride) + _soft16_scanline_fill_transp_solid(dst_itr, w, rgb565_unpack, alpha); +} + +static void +_soft16_rectangle_draw_int(Soft16_Image *dst, RGBA_Draw_Context *dc, + Evas_Rectangle dr) +{ + int dst_offset; + + if (_is_empty_rectangle(&dr)) return; + RECTS_CLIP_TO_RECT(dr.x, dr.y, dr.w, dr.h, 0, 0, dst->cache_entry.w, dst->cache_entry.h); + if (_is_empty_rectangle(&dr)) return; + + if (dc->clip.use) + RECTS_CLIP_TO_RECT(dr.x, dr.y, dr.w, dr.h, dc->clip.x, + dc->clip.y, dc->clip.w, dc->clip.h); + if (_is_empty_rectangle(&dr)) return; + if (A_VAL(&dc->col.col) == 0) return; + + dst_offset = dr.x + (dr.y * dst->cache_entry.w); + + if (!dst->flags.have_alpha) + { + DATA16 rgb565; + DATA8 alpha; + + alpha = A_VAL(&dc->col.col) >> 3; + rgb565 = RGB_565_FROM_COMPONENTS(R_VAL(&dc->col.col), + G_VAL(&dc->col.col), + B_VAL(&dc->col.col)); + if (alpha == 31) + _soft16_rectangle_draw_solid_solid + (dst, dst_offset, dr.w, dr.h, rgb565); + else if (alpha > 0) + _soft16_rectangle_draw_transp_solid + (dst, dst_offset, dr.w, dr.h, rgb565, alpha); + } + else + fprintf(stderr, + "Unsupported feature: drawing rectangle to non-opaque " + "destination.\n"); +} + +void +soft16_rectangle_draw(Soft16_Image *dst, RGBA_Draw_Context *dc, + int x, int y, int w, int h) +{ + Evas_Rectangle dr; + Cutout_Rects *rects; + Cutout_Rect *r; + struct RGBA_Draw_Context_clip c_bkp; + int i; + + /* handle cutouts here! */ + dr.x = x; + dr.y = y; + dr.w = w; + dr.h = h; + + if (_is_empty_rectangle(&dr)) return; + if (!(RECTS_INTERSECT(dr.x, dr.y, dr.w, dr.h, 0, 0, dst->cache_entry.w, dst->cache_entry.h))) + return; + + /* no cutouts - cut right to the chase */ + if (!dc->cutout.rects) + { + _soft16_rectangle_draw_int(dst, dc, dr); + return; + } + + c_bkp = dc->clip; + + evas_common_draw_context_clip_clip(dc, 0, 0, dst->cache_entry.w, dst->cache_entry.h); + evas_common_draw_context_clip_clip(dc, x, y, w, h); + /* our clip is 0 size.. abort */ + if ((dc->clip.w <= 0) || (dc->clip.h <= 0)) + { + dc->clip = c_bkp; + return; + } + rects = evas_common_draw_context_apply_cutouts(dc); + for (i = 0; i < rects->active; ++i) + { + r = rects->rects + i; + evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h); + _soft16_rectangle_draw_int(dst, dc, dr); + } + evas_common_draw_context_apply_clear_cutouts(rects); + dc->clip = c_bkp; +} + diff --git a/legacy/evas/src/lib/engines/common_16/evas_soft16_scanline_blend.c b/legacy/evas/src/lib/engines/common_16/evas_soft16_scanline_blend.c new file mode 100644 index 0000000000..409eb1085a --- /dev/null +++ b/legacy/evas/src/lib/engines/common_16/evas_soft16_scanline_blend.c @@ -0,0 +1,471 @@ +/** NOTE: This file is meant to be included by users **/ + +/** NOTE2: r, g, b parameters are 16bits, so you can pass 0 to 256 inclusive. + ** this is due our division by 256 when multiplying the color. + **/ + +/***************************************************************************** + * Scanline processing + * + * _soft16_scanline___[_]() + * + ****************************************************************************/ + +static always_inline void +_soft16_pt_blend_transp_solid(DATA16 *p_dst, DATA16 src, DATA8 alpha) +{ + if (alpha == 31) *p_dst = src; + else if (alpha != 0) + { + DATA32 a, b; + + a = RGB_565_UNPACK(src); + b = RGB_565_UNPACK(*p_dst); + b = RGB_565_UNPACKED_BLEND(a, b, alpha); + *p_dst = RGB_565_PACK(b); + } +} + +/*********************************************************************** + * Regular blend operations + */ +static void +_soft16_scanline_blend_transp_solid(DATA16 *src, DATA8 *alpha, DATA16 *dst, int size) +{ + DATA16 *start, *end; + + start = dst; + end = start + (size & ~7); + + pld(alpha, 0); + pld(src, 0); + + /* work on 8 pixels per time, do data preload */ + while (start < end) + { + DATA8 alpha1, alpha2; + + alpha1 = alpha[0]; + alpha += 8; + + /* empirical tests show these give the best performance */ + pld(alpha, 8); + pld(src, 32); + + src += 8; + start += 8; + + alpha2 = alpha[-7]; + _soft16_pt_blend_transp_solid(start - 8, src[-8], alpha1); + + alpha1 = alpha[-6]; + _soft16_pt_blend_transp_solid(start - 7, src[-7], alpha2); + + alpha2 = alpha[-5]; + _soft16_pt_blend_transp_solid(start - 6, src[-6], alpha1); + + alpha1 = alpha[-4]; + _soft16_pt_blend_transp_solid(start - 5, src[-5], alpha2); + + alpha2 = alpha[-3]; + _soft16_pt_blend_transp_solid(start - 4, src[-4], alpha1); + + alpha1 = alpha[-2]; + _soft16_pt_blend_transp_solid(start - 3, src[-3], alpha2); + + alpha2 = alpha[-1]; + _soft16_pt_blend_transp_solid(start - 2, src[-2], alpha1); + + _soft16_pt_blend_transp_solid(start - 1, src[-1], alpha2); + } + + /* remaining pixels (up to 7) */ + end = start + (size & 7); + for (; start < end; start++, src++, alpha++) + _soft16_pt_blend_transp_solid(start, *src, *alpha); +} + +static always_inline void +_soft16_pt_blend_solid_solid(DATA16 *p_dst, DATA16 src) +{ + *p_dst = src; +} + +static inline void +_soft16_scanline_blend_solid_solid(DATA16 *src, DATA16 *dst, int size) +{ + memcpy(dst, src, size * sizeof(DATA16)); +} + +/*********************************************************************** + * Blend operations taking an extra alpha (fade in, out) + */ + +static inline void +_soft16_pt_blend_transp_solid_mul_alpha(DATA16 *p_dst, DATA16 src, DATA8 alpha, DATA8 rel_alpha) +{ + DATA32 a, b; + + alpha = (alpha * rel_alpha) >> 5; + if (alpha == 0) + return; + + alpha++; + + a = ((RGB_565_UNPACK(src) * rel_alpha) >> 5) & RGB_565_UNPACKED_MASK; + b = RGB_565_UNPACK(*p_dst); + b = RGB_565_UNPACKED_BLEND(a, b, alpha); + *p_dst = RGB_565_PACK(b); +} + +static void +_soft16_scanline_blend_transp_solid_mul_alpha(DATA16 *src, DATA8 *alpha, DATA16 *dst, int size, const DATA8 rel_alpha) +{ + DATA16 *start, *end; + + start = dst; + end = start + (size & ~7); + + pld(alpha, 0); + pld(src, 0); + + while (start < end) + { + DATA8 alpha1, alpha2; + + alpha1 = alpha[0]; + alpha += 8; + + pld(alpha, 8); + pld(src, 32); + + src += 8; + start += 8; + + alpha2 = alpha[-7]; + _soft16_pt_blend_transp_solid_mul_alpha + (start - 8, src[-8], alpha1, rel_alpha); + + alpha1 = alpha[-6]; + _soft16_pt_blend_transp_solid_mul_alpha + (start - 7, src[-7], alpha2, rel_alpha); + + alpha2 = alpha[-5]; + _soft16_pt_blend_transp_solid_mul_alpha + (start - 6, src[-6], alpha1, rel_alpha); + + alpha1 = alpha[-4]; + _soft16_pt_blend_transp_solid_mul_alpha + (start - 5, src[-5], alpha2, rel_alpha); + + alpha2 = alpha[-3]; + _soft16_pt_blend_transp_solid_mul_alpha + (start - 4, src[-4], alpha1, rel_alpha); + + alpha1 = alpha[-2]; + _soft16_pt_blend_transp_solid_mul_alpha + (start - 3, src[-3], alpha2, rel_alpha); + + alpha2 = alpha[-1]; + _soft16_pt_blend_transp_solid_mul_alpha + (start - 2, src[-2], alpha1, rel_alpha); + + _soft16_pt_blend_transp_solid_mul_alpha + (start - 1, src[-1], alpha2, rel_alpha); + } + + end = start + (size & 7); + for (; start < end; start++, src++, alpha++) + _soft16_pt_blend_transp_solid_mul_alpha(start, *src, *alpha, rel_alpha); +} + +static always_inline void +_soft16_pt_blend_solid_solid_mul_alpha(DATA16 *p_dst, DATA16 src, DATA8 rel_alpha) +{ + DATA32 a, b; + a = RGB_565_UNPACK(src); + b = RGB_565_UNPACK(*p_dst); + b = RGB_565_UNPACKED_BLEND_UNMUL(a, b, rel_alpha); + *p_dst = RGB_565_PACK(b); +} + +static void +_soft16_scanline_blend_solid_solid_mul_alpha(DATA16 *src, DATA16 *dst, int size, DATA8 rel_alpha) +{ + DATA16 *start, *end; + + start = dst; + end = start + (size & ~7); + + pld(src, 0); + + while (start < end) + { + pld(src, 32); + UNROLL8({ + _soft16_pt_blend_solid_solid_mul_alpha(start, *src, rel_alpha); + start++; + src++; + }); + } + + end = start + (size & 7); + for (; start < end; start++, src++) + _soft16_pt_blend_solid_solid_mul_alpha(start, *src, rel_alpha); +} + +/*********************************************************************** + * Blend operations with extra alpha and multiply color + */ + +static always_inline void +_soft16_pt_blend_transp_solid_mul_color_transp(DATA16 *p_dst, DATA16 src, DATA8 alpha, DATA8 rel_alpha, DATA16 r, DATA16 g, DATA16 b) +{ + DATA32 rgb, d; + int r1, g1, b1; + + alpha = (alpha * rel_alpha) >> 5; + if (alpha == 0) + return; + + alpha++; + + r1 = ((((src) >> 11) & 0x1f) * r) >> 5; + g1 = ((((src) >> 5) & 0x3f) * g) >> 6; + b1 = (((src) & 0x1f) * b) >> 5; + rgb = ((r1 << 11) | (g1 << 21) | b1) & RGB_565_UNPACKED_MASK; + d = RGB_565_UNPACK(*p_dst); + d = RGB_565_UNPACKED_BLEND(rgb, d, alpha); + + *p_dst = RGB_565_PACK(d); +} + +static void +_soft16_scanline_blend_transp_solid_mul_color_transp(DATA16 *src, DATA8 *alpha, DATA16 *dst, int size, DATA8 rel_alpha, DATA16 r, DATA16 g, DATA16 b) +{ + DATA16 *start, *end; + + start = dst; + end = start + (size & ~7); + + pld(alpha, 0); + pld(src, 0); + + while (start < end) + { + DATA8 alpha1, alpha2; + + alpha1 = alpha[0]; + alpha += 8; + + pld(src, 32); + pld(start, 32); + + src += 8; + start += 8; + + alpha2 = alpha[-7]; + _soft16_pt_blend_transp_solid_mul_color_transp + (start - 8, src[-8], alpha1, rel_alpha, r, g, b); + + alpha1 = alpha[-6]; + _soft16_pt_blend_transp_solid_mul_color_transp + (start - 7, src[-7], alpha2, rel_alpha, r, g, b); + + alpha2 = alpha[-5]; + _soft16_pt_blend_transp_solid_mul_color_transp + (start - 6, src[-6], alpha1, rel_alpha, r, g, b); + + alpha1 = alpha[-4]; + _soft16_pt_blend_transp_solid_mul_color_transp + (start - 5, src[-5], alpha2, rel_alpha, r, g, b); + + alpha2 = alpha[-3]; + _soft16_pt_blend_transp_solid_mul_color_transp + (start - 4, src[-4], alpha1, rel_alpha, r, g, b); + + alpha1 = alpha[-2]; + _soft16_pt_blend_transp_solid_mul_color_transp + (start - 3, src[-3], alpha2, rel_alpha, r, g, b); + + alpha2 = alpha[-1]; + _soft16_pt_blend_transp_solid_mul_color_transp + (start - 2, src[-2], alpha1, rel_alpha, r, g, b); + + _soft16_pt_blend_transp_solid_mul_color_transp + (start - 1, src[-1], alpha2, rel_alpha, r, g, b); + } + + end = start + (size & 7); + for (; start < end; start++, src++, alpha++) + _soft16_pt_blend_transp_solid_mul_color_transp + (start, *src, *alpha, rel_alpha, r, g, b); +} + +static always_inline void +_soft16_pt_blend_solid_solid_mul_color_transp(DATA16 *p_dst, DATA16 src, DATA8 rel_alpha, DATA16 r, DATA16 g, DATA16 b) +{ + int r1, g1, b1; + DATA32 rgb, d; + + r1 = ((((src) >> 11) & 0x1f) * r) >> 5; + g1 = ((((src) >> 5) & 0x3f) * g) >> 6; + b1 = (((src) & 0x1f) * b) >> 5; + + rgb = ((r1 << 11) | (g1 << 21) | b1) & RGB_565_UNPACKED_MASK; + d = RGB_565_UNPACK(*p_dst); + d = RGB_565_UNPACKED_BLEND(rgb, d, rel_alpha); + *p_dst = RGB_565_PACK(d); +} + +static void +_soft16_scanline_blend_solid_solid_mul_color_transp(DATA16 *src, DATA16 *dst, int size, DATA8 rel_alpha, DATA16 r, DATA16 g, DATA16 b) +{ + DATA16 *start, *end; + + start = dst; + end = start + (size & ~7); + + pld(src, 0); + + while (start < end) + { + pld(src, 32); + UNROLL8({ + _soft16_pt_blend_solid_solid_mul_color_transp + (start, *src, rel_alpha, r, g, b); + start++; + src++; + }); + } + + end = start + (size & 7); + for (; start < end; start++, src++) + _soft16_pt_blend_solid_solid_mul_color_transp + (start, *src, rel_alpha, r, g, b); +} + +/*********************************************************************** + * Blend operations with extra multiply color + */ +static always_inline void +_soft16_pt_blend_transp_solid_mul_color_solid(DATA16 *p_dst, DATA16 src, DATA8 alpha, DATA8 r, DATA8 g, DATA8 b) +{ + int r1, g1, b1; + + if (alpha == 0) return; + + r1 = ((((src >> 11) & 0x1f) * r) >> 5) & 0x1f; + g1 = ((((src >> 5) & 0x3f) * g) >> 6) & 0x3f; + b1 = (((src & 0x1f) * b) >> 5) & 0x1f; + + if (alpha == 31) *p_dst = (r1 << 11) | (g1 << 5) | b1; + else + { + DATA32 rgb_unpack, d; + + rgb_unpack = ((r1 << 11) | (g1 << 21) | b1) & RGB_565_UNPACKED_MASK; + d = RGB_565_UNPACK(*p_dst); + d = RGB_565_UNPACKED_BLEND(rgb_unpack, d, alpha); + *p_dst = RGB_565_PACK(d); + } +} + +static void +_soft16_scanline_blend_transp_solid_mul_color_solid(DATA16 *src, DATA8 *alpha, DATA16 *dst, int size, DATA16 r, DATA16 g, DATA16 b) +{ + DATA16 *start, *end; + + start = dst; + end = start + (size & ~7); + + pld(alpha, 0); + pld(src, 0); + + while (start < end) + { + DATA8 alpha1, alpha2; + + alpha1 = alpha[0]; + alpha += 8; + + pld(alpha, 8); + pld(src, 32); + + src += 8; + start += 8; + + alpha2 = alpha[-7]; + _soft16_pt_blend_transp_solid_mul_color_solid + (start - 8, src[-8], alpha1, r, g, b); + + alpha1 = alpha[-6]; + _soft16_pt_blend_transp_solid_mul_color_solid + (start - 7, src[-7], alpha2, r, g, b); + + alpha2 = alpha[-5]; + _soft16_pt_blend_transp_solid_mul_color_solid + (start - 6, src[-6], alpha1, r, g, b); + + alpha1 = alpha[-4]; + _soft16_pt_blend_transp_solid_mul_color_solid + (start - 5, src[-5], alpha2, r, g, b); + + alpha2 = alpha[-3]; + _soft16_pt_blend_transp_solid_mul_color_solid + (start - 4, src[-4], alpha1, r, g, b); + + alpha1 = alpha[-2]; + _soft16_pt_blend_transp_solid_mul_color_solid + (start - 3, src[-3], alpha2, r, g, b); + + alpha2 = alpha[-1]; + _soft16_pt_blend_transp_solid_mul_color_solid + (start - 2, src[-2], alpha1, r, g, b); + + _soft16_pt_blend_transp_solid_mul_color_solid + (start - 1, src[-1], alpha2, r, g, b); + } + + end = start + (size & 7); + for (; start < end; start++, src++, alpha++) + _soft16_pt_blend_transp_solid_mul_color_solid + (start, *src, *alpha, r, g, b); +} + +static always_inline void +_soft16_pt_blend_solid_solid_mul_color_solid(DATA16 *p_dst, DATA16 src, DATA16 r, DATA16 g, DATA16 b) +{ + int r1, g1, b1; + + r1 = ((((src >> 11) & 0x1f) * r) >> 5) & 0x1f; + g1 = ((((src >> 5) & 0x3f) * g) >> 6) & 0x3f; + b1 = (((src & 0x1f) * b) >> 5) & 0x1f; + + *p_dst = (r1 << 11) | (g1 << 5) | b1; +} + +static void +_soft16_scanline_blend_solid_solid_mul_color_solid(DATA16 *src, DATA16 *dst, int size, DATA8 r, DATA8 g, DATA8 b) +{ + DATA16 *start, *end; + + start = dst; + end = start + (size & ~7); + + pld(src, 0); + + while (start < end) + { + pld(src, 32); + UNROLL8({ + _soft16_pt_blend_solid_solid_mul_color_solid(start, *src, r, g, b); + start++; + src++; + }); + } + + end = start + (size & 7); + for (; start < end; start++, src++) + _soft16_pt_blend_solid_solid_mul_color_solid(start, *src, r, g, b); +} diff --git a/legacy/evas/src/lib/engines/common_16/evas_soft16_scanline_fill.c b/legacy/evas/src/lib/engines/common_16/evas_soft16_scanline_fill.c new file mode 100644 index 0000000000..b4ab63070c --- /dev/null +++ b/legacy/evas/src/lib/engines/common_16/evas_soft16_scanline_fill.c @@ -0,0 +1,86 @@ +/** NOTE: This file is meant to be included by users **/ + +/***************************************************************************** + * Point processing + * + * _soft16_pt___[_]() + * + * Scanline processing + * + * _soft16_scanline___[_]() + * + ****************************************************************************/ +static always_inline void +_soft16_pt_fill_solid_solid(DATA16 *dst, DATA16 rgb565) +{ + *dst = rgb565; +} + +static void +_soft16_scanline_fill_solid_solid(DATA16 *dst, int size, DATA16 rgb565) +{ + DATA16 *start, *end; + DATA32 rgb565_double; + + start = dst; + + if ((long)start & 0x2) + { + *start = rgb565; + start++; + size--; + } + + end = start + (size & ~7); + + rgb565_double = (rgb565 << 16) | rgb565; + + while (start < end) + { + DATA32 *p = (DATA32 *)start; + + p[0] = rgb565_double; + p[1] = rgb565_double; + p[2] = rgb565_double; + p[3] = rgb565_double; + + start += 8; + } + + end = start + (size & 7); + for (; start < end; start++) + *start = rgb565; +} + +static always_inline void +_soft16_pt_fill_transp_solid(DATA16 *dst, DATA32 rgb565_unpack, DATA8 alpha) +{ + DATA32 d; + + d = RGB_565_UNPACK(*dst); + d = RGB_565_UNPACKED_BLEND(rgb565_unpack, d, alpha); + *dst = RGB_565_PACK(d); +} + +static void +_soft16_scanline_fill_transp_solid(DATA16 *dst, int size, DATA32 rgb565_unpack, DATA8 alpha) +{ + DATA16 *start, *end; + + start = dst; + pld(start, 0); + end = start + (size & ~7); + + while (start < end) + { + pld(start, 32); + UNROLL8({ + _soft16_pt_fill_transp_solid(start, rgb565_unpack, alpha); + start++; + }); + } + + end = start + (size & 7); + for (; start < end; start++) + _soft16_pt_fill_transp_solid(start, rgb565_unpack, alpha); +} diff --git a/legacy/evas/src/modules/engines/software_16_sdl/.cvsignore b/legacy/evas/src/modules/engines/software_16_sdl/.cvsignore new file mode 100644 index 0000000000..09980ae6ba --- /dev/null +++ b/legacy/evas/src/modules/engines/software_16_sdl/.cvsignore @@ -0,0 +1,6 @@ +.deps +.libs +Makefile +Makefile.in +*.lo +*.la diff --git a/legacy/evas/src/modules/engines/software_16_sdl/Evas_Engine_SDL_16.h b/legacy/evas/src/modules/engines/software_16_sdl/Evas_Engine_SDL_16.h new file mode 100644 index 0000000000..20adccffae --- /dev/null +++ b/legacy/evas/src/modules/engines/software_16_sdl/Evas_Engine_SDL_16.h @@ -0,0 +1,22 @@ +#ifndef _EVAS_ENGINE_SDL_16_H +# define _EVAS_ENGINE_SDL_16_H + +#include + +typedef struct _Evas_Engine_Info_SDL_16 Evas_Engine_Info_SDL_16; +struct _Evas_Engine_Info_SDL_16 +{ + /* PRIVATE - don't mess with this baby or evas will poke its tongue out */ + /* at you and make nasty noises */ + Evas_Engine_Info magic; + + struct { + int rotation; + int fullscreen : 1; + int hwsurface : 1; + int noframe : 1; + int alpha : 1; + } info; +}; + +#endif diff --git a/legacy/evas/src/modules/engines/software_16_sdl/Makefile.am b/legacy/evas/src/modules/engines/software_16_sdl/Makefile.am new file mode 100644 index 0000000000..ab1603d423 --- /dev/null +++ b/legacy/evas/src/modules/engines/software_16_sdl/Makefile.am @@ -0,0 +1,28 @@ +AUTOMAKE_OPTIONS = 1.4 foreign + +MAINTAINERCLEANFILES = Makefile.in + +INCLUDES = -I. -I$(top_srcdir)/src/lib -I$(top_srcdir)/src/lib/include @FREETYPE_CFLAGS@ @SDL_CFLAGS@ + +if BUILD_ENGINE_SDL + +pkgdir = $(libdir)/evas/modules/engines/software_16_sdl/$(MODULE_ARCH) + +pkg_LTLIBRARIES = module.la + +module_la_SOURCES = \ +evas_engine.c \ +evas_engine.h + +module_la_LIBADD = @SDL_LIBS@ $(top_builddir)/src/lib/libevas.la +module_la_LDFLAGS = @create_shared_lib@ -module -avoid-version -L$(top_builddir)/src/lib -L$(top_builddir)/src/lib/.libs +module_la_DEPENDENCIES = $(top_builddir)/config.h + +include_HEADERS = Evas_Engine_SDL_16.h + +endif + +EXTRA_DIST = \ +evas_engine.c \ +evas_engine.h \ +Evas_Engine_SDL_16.h diff --git a/legacy/evas/src/modules/engines/software_16_sdl/evas_engine.c b/legacy/evas/src/modules/engines/software_16_sdl/evas_engine.c new file mode 100644 index 0000000000..94e77f1736 --- /dev/null +++ b/legacy/evas/src/modules/engines/software_16_sdl/evas_engine.c @@ -0,0 +1,1253 @@ +#include +#include +#include +#include +#include +#include + +#include "evas_engine.h" + +/* function tables - filled in later (func and parent func) */ +static Evas_Func func = {}; +static Evas_Func pfunc = {}; + +static Engine_Image_Entry *_sdl16_image_alloc (void); +static void _sdl16_image_delete (Engine_Image_Entry *eim); + +static int _sdl16_image_constructor (Engine_Image_Entry *ie, void* data); +static void _sdl16_image_destructor (Engine_Image_Entry *eim); + +static void _sdl16_image_dirty_region(Engine_Image_Entry *eim, int x, int y, int w, int h); + +static int _sdl16_image_dirty (Engine_Image_Entry *dst, const Engine_Image_Entry *src); + +static int _sdl16_image_size_set (Engine_Image_Entry *dst, const Engine_Image_Entry *src); + +static int _sdl16_image_update_data (Engine_Image_Entry* dst, void* engine_data); + +static void _sdl16_image_load (Engine_Image_Entry *eim, const Image_Entry* im); +static int _sdl16_image_mem_size_get(Engine_Image_Entry *eim); + +#ifdef DEBUG_SDL +static void _sdl16_image_debug (const char* context, Engine_Image_Entry* im); +#endif + +static const Evas_Cache_Engine_Image_Func _sdl16_cache_engine_image_cb = { + NULL /* key */, + _sdl16_image_alloc /* alloc */, + _sdl16_image_delete /* dealloc */, + _sdl16_image_constructor /* constructor */, + _sdl16_image_destructor /* destructor */, + _sdl16_image_dirty_region /* dirty_region */, + _sdl16_image_dirty /* dirty */, + _sdl16_image_size_set /* size_set */, + _sdl16_image_update_data /* update_data */, + _sdl16_image_load /* load */, + _sdl16_image_mem_size_get /* mem_size_get */, +#ifdef DEBUG_SDL /* debug */ + _sdl16_image_debug +#else + NULL +#endif +}; + +#define _SDL_UPDATE_PIXELS(EIM) \ + ((Soft16_Image *) EIM->cache_entry.src)->pixels = EIM->surface->pixels; + +#define RMASK565 0xf800 +#define GMASK565 0x07e0 +#define BMASK565 0x001f +#define AMASK565 0x0000 + +/* engine api this module provides */ +static void * +evas_engine_sdl16_info(Evas *e) +{ + Evas_Engine_Info_SDL_16 *info; + + (void) e; + + info = calloc(1, sizeof(Evas_Engine_Info_SDL_16)); + if (!info) return NULL; + info->magic.magic = rand(); + return info; +} + +static void +evas_engine_sdl16_info_free(Evas *e, void *info) +{ + Evas_Engine_Info_SDL_16 *in; + + in = (Evas_Engine_Info_SDL_16 *)info; + free(in); +} + +static void +_tmp_out_alloc(Render_Engine *re) +{ + Tilebuf_Rect *r; + int w = 0, h = 0; + + for (r = re->rects; r; r = (Tilebuf_Rect *)(r->_list_data.next)) + { + if (r->w > w) w = r->w; + if (r->h > h) h = r->h; + } + + if (re->tmp_out) + { + if ((re->tmp_out->cache_entry.w < w) || (re->tmp_out->cache_entry.h < h)) + { + evas_cache_image_drop(&re->tmp_out->cache_entry); + re->tmp_out = NULL; + } + } + + if (!re->tmp_out) + { + Soft16_Image *im; + + im = (Soft16_Image *) evas_cache_image_empty(evas_common_soft16_image_cache_get()); + im->flags.have_alpha = 0; + evas_cache_image_surface_alloc(&im->cache_entry, w, h); + + re->tmp_out = im; + } +} + +static void* +_sdl16_output_setup(int w, int h, int rotation, int fullscreen, int noframe, int hwsurface) +{ + Render_Engine *re = calloc(1, sizeof(Render_Engine)); + SDL_Surface *surface; + + /* if we haven't initialized - init (automatic abort if already done) */ + evas_common_cpu_init(); + evas_common_blend_init(); + evas_common_image_init(); + evas_common_convert_init(); + evas_common_scale_init(); + evas_common_rectangle_init(); + evas_common_gradient_init(); + evas_common_polygon_init(); + evas_common_line_init(); + evas_common_font_init(); + evas_common_draw_init(); + evas_common_tilebuf_init(); + evas_common_soft16_image_init(); + + if (w <= 0) w = 640; + if (h <= 0) h = 480; + + re->cache = evas_cache_engine_image_init(&_sdl16_cache_engine_image_cb, evas_common_soft16_image_cache_get()); + if (!re->cache) + { + fprintf(stderr, "Evas_Cache_Engine_Image allocation failed!\n"); + exit(-1); + } + + re->tb = evas_common_tilebuf_new(w, h); + /* in preliminary tests 16x16 gave highest framerates */ + evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE); + re->w = w; + re->h = h; + re->rot = rotation; + re->flags.hwsurface = hwsurface; + re->flags.fullscreen = fullscreen; + re->flags.noframe = noframe; + re->flags.end = 0; + + re->update_rects_count = 0; + re->update_rects_limit = 0; + re->update_rects = NULL; + + surface = SDL_SetVideoMode(w, h, 16, + (hwsurface ? SDL_HWSURFACE : SDL_SWSURFACE) + | (fullscreen ? SDL_FULLSCREEN : 0) + | (noframe ? SDL_NOFRAME : 0)); + if (!surface) + { + fprintf(stderr, "SDL_SetVideoMode [ %i x %i x 16 ] failed\n", w, h); + exit(-1); + } + + SDL_SetAlpha(surface, SDL_RLEACCEL, 0); + SDL_FillRect(surface, NULL, 0); + + re->soft16_engine_image = (SDL_Engine_Image_Entry *) evas_cache_engine_image_engine(re->cache, surface); + if (!re->soft16_engine_image) + { + fprintf(stderr, "Soft16_Image allocation from SDL failed\n"); + exit(-1); + } + + return re; +} + + +static void +evas_engine_sdl16_setup(Evas *e, void *in) +{ + Evas_Engine_Info_SDL_16 *info = (Evas_Engine_Info_SDL_16 *) in; + + if (evas_output_method_get(e) != evas_render_method_lookup("software_16_sdl")) + return ; + + SDL_Init(SDL_INIT_NOPARACHUTE); + + if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) + { + fprintf(stderr, "SDL_Init failed with %s\n", SDL_GetError()); + exit(-1); + } + + e->engine.data.output = _sdl16_output_setup(e->output.w, e->output.h, + info->info.rotation, + info->info.fullscreen, + info->info.noframe, + info->info.hwsurface); + if (!e->engine.data.output) + return; + + e->engine.func = &func; + e->engine.data.context = e->engine.func->context_new(e->engine.data.output); +} + +static void +evas_engine_sdl16_output_free(void *data) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + if (re->tb) evas_common_tilebuf_free(re->tb); + if (re->rects) evas_common_tilebuf_free_render_rects(re->rects); + if (re->tmp_out) evas_cache_image_drop(&re->tmp_out->cache_entry); + if (re->soft16_engine_image) evas_cache_engine_image_drop(&re->soft16_engine_image->cache_entry); + free(re); + +/* evas_common_font_shutdown(); */ + evas_common_image_shutdown(); + evas_common_soft16_image_shutdown(); +} + +static void +evas_engine_sdl16_output_resize(void *data, int w, int h) +{ + Render_Engine *re = data; + SDL_Surface *surface; + + if ((re->w == w) && (re->h == h)) return; + + evas_cache_engine_image_drop(&re->soft16_engine_image->cache_entry); + + evas_common_tilebuf_free(re->tb); + re->w = w; + re->h = h; + re->tb = evas_common_tilebuf_new(w, h); + if (re->tb) + evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE); + + surface = SDL_SetVideoMode(w, h, 16, + (re->flags.hwsurface ? SDL_HWSURFACE : SDL_SWSURFACE) + | (re->flags.fullscreen ? SDL_FULLSCREEN : 0) + | (re->flags.noframe ? SDL_NOFRAME : 0)); + if (!surface) + { + fprintf(stderr, "Unable to change the resolution to : %ix%i\n", w, h); + exit(-1); + } + re->soft16_engine_image = (SDL_Engine_Image_Entry *) evas_cache_engine_image_engine(re->cache, surface); + if (!re->soft16_engine_image) + { + fprintf(stderr, "RGBA_Image allocation from SDL failed\n"); + exit(-1); + } + + SDL_FillRect(surface, NULL, 0); + + if (re->tmp_out) + { + evas_cache_image_drop(&re->tmp_out->cache_entry); + re->tmp_out = NULL; + } +} + +static void +evas_engine_sdl16_output_tile_size_set(void *data, int w, int h) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_tilebuf_set_tile_size(re->tb, w, h); +} + +static void +evas_engine_sdl16_output_redraws_rect_add(void *data, int x, int y, int w, int h) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_tilebuf_add_redraw(re->tb, x, y, w, h); +} + +static void +evas_engine_sdl16_output_redraws_rect_del(void *data, int x, int y, int w, int h) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_tilebuf_del_redraw(re->tb, x, y, w, h); +} + +static void +evas_engine_sdl16_output_redraws_clear(void *data) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_tilebuf_clear(re->tb); +} + +static void * +evas_engine_sdl16_output_redraws_next_update_get(void *data, + int *x, int *y, int *w, int *h, + int *cx, int *cy, int *cw, int *ch) +{ + Render_Engine *re = data; + Tilebuf_Rect *tb_rect; + SDL_Rect rect; + + if (re->flags.end) + { + re->flags.end = 0; + return NULL; + } + if (!re->rects) + { + re->rects = evas_common_tilebuf_get_render_rects(re->tb); + re->cur_rect = re->rects; + if (re->rot != 0) _tmp_out_alloc(re); /* grows if required */ + } + if (!re->cur_rect) + { + if (re->rects) evas_common_tilebuf_free_render_rects(re->rects); + re->rects = NULL; + return NULL; + } + + tb_rect = re->cur_rect; + *cx = *x = tb_rect->x; + *cy = *y = tb_rect->y; + *cw = *w = tb_rect->w; + *ch = *h = tb_rect->h; + re->cur_rect = (Tilebuf_Rect *)(re->cur_rect->_list_data.next); + if (!re->cur_rect) + { + evas_common_tilebuf_free_render_rects(re->rects); + re->rects = NULL; + re->flags.end = 1; + } + + if (re->rot != 0) + { + *cx = 0; + *cy = 0; + } + + rect.x = *x; + rect.y = *y; + rect.w = *w; + rect.h = *h; + + SDL_FillRect(re->soft16_engine_image->surface, &rect, 0); + + /* Return the "fake" surface so it is passed to the drawing routines. */ + return re->soft16_engine_image; +} + +static void +_blit_rot_90(Soft16_Image *dst, const Soft16_Image *src, + int out_x, int out_y, int w, int h) +{ + DATA16 *dp, *sp; + int x, y; + + sp = src->pixels; + dp = dst->pixels + (out_x + + (w + out_y - 1) * dst->stride); + + for (y = 0; y < h; y++) + { + DATA16 *dp_itr, *sp_itr; + + sp_itr = sp; + dp_itr = dp; + + for (x = 0; x < w; x++) + { + *dp_itr = *sp_itr; + + sp_itr++; + dp_itr -= dst->stride; + } + sp += src->stride; + dp++; + } +} + +static void +_blit_rot_180(Soft16_Image *dst, const Soft16_Image *src, + int out_x, int out_y, int w, int h) +{ + DATA16 *dp, *sp; + int x, y; + + sp = src->pixels; + dp = dst->pixels + ((w + out_x - 1) + + (h + out_y - 1) * dst->stride); + + for (y = 0; y < h; y++) + { + DATA16 *dp_itr, *sp_itr; + + sp_itr = sp; + dp_itr = dp; + + for (x = 0; x < w; x++) + { + *dp_itr = *sp_itr; + + sp_itr++; + dp_itr--; + } + sp += src->stride; + dp -= dst->stride; + } +} + +static void +_blit_rot_270(Soft16_Image *dst, const Soft16_Image *src, + int out_x, int out_y, int w, int h) +{ + DATA16 *dp, *sp; + int x, y; + + sp = src->pixels; + dp = dst->pixels + ((h + out_x - 1) + + out_y * dst->stride); + + for (y = 0; y < h; y++) + { + DATA16 *dp_itr, *sp_itr; + + sp_itr = sp; + dp_itr = dp; + + for (x = 0; x < w; x++) + { + *dp_itr = *sp_itr; + + sp_itr++; + dp_itr += dst->stride; + } + sp += src->stride; + dp--; + } +} + +static void +_tmp_out_process(Render_Engine *re, int out_x, int out_y, int w, int h) +{ + Soft16_Image *d, *s; + DATA16 *dp, *sp; + int y, x, d_dir; + + d = (Soft16_Image *) re->soft16_engine_image->cache_entry.src; + s = re->tmp_out; + + if ((w < 1) || (h < 1) + || (out_x >= d->cache_entry.w) || (out_y >= d->cache_entry.h)) + return; + + if (re->rot == 90) + _blit_rot_90(d, s, out_x, out_y, w, h); + else if (re->rot == 180) + _blit_rot_180(d, s, out_x, out_y, w, h); + else if (re->rot == 270) + _blit_rot_270(d, s, out_x, out_y, w, h); +} + +static void +evas_engine_sdl16_output_redraws_next_update_push(void *data, void *surface, + int x, int y, int w, int h) +{ + Render_Engine *re = data; + SDL_Rect rect; + + if (re->update_rects_count + 1 > re->update_rects_limit) + { + re->update_rects_limit += 8; + re->update_rects = realloc(re->update_rects, sizeof (SDL_Rect) * re->update_rects_limit); + } + + rect.x = x; + rect.y = y; + rect.w = w; + rect.h = h; + + switch (re->rot) + { + case 0: + break; + case 90: + rect.x = y; + rect.y = re->w - w - x; + rect.w = h; + rect.h = w; + break; + case 180: + rect.x = re->w - w - x; + rect.y = re->h - h - y; + break; + case 270: + rect.x = re->h - h - y; + rect.y = x; + rect.w = h; + rect.h = w; + break; + default: + abort(); + } + + re->update_rects[re->update_rects_count] = rect; + + if (re->rot != 0) + _tmp_out_process(re, rect.x, rect.y, w, h); + + ++re->update_rects_count; +} + +static void +evas_engine_sdl16_output_flush(void *data) +{ + Render_Engine *re = data; + + if (re->update_rects_count > 0) + SDL_UpdateRects(re->soft16_engine_image->surface, re->update_rects_count, re->update_rects); + + re->update_rects_count = 0; +} + +static void +evas_engine_sdl16_output_idle_flush(void *data) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + if (re->tmp_out) + { + evas_cache_image_drop(&re->tmp_out->cache_entry); + re->tmp_out = NULL; + } +} + +static void* +evas_engine_sdl16_image_load(void *data, const char *file, const char *key, int *error, Evas_Image_Load_Opts *lo) +{ + Render_Engine* re = (Render_Engine*) data;; + + *error = 0; + return evas_cache_engine_image_request(re->cache, file, key, lo, NULL, error); +} + +static int +evas_engine_sdl16_image_alpha_get(void *data, void *image) +{ + SDL_Engine_Image_Entry *eim = image; + Soft16_Image *im; + + (void) data; + + if (!eim) return 1; + im = (Soft16_Image *) eim->cache_entry.src; + if (im->flags.have_alpha) return 1; + return 0; +} + +static void +evas_engine_sdl16_image_size_get(void *data, void *image, int *w, int *h) +{ + SDL_Engine_Image_Entry *eim; + + (void) data; + + eim = image; + if (w) *w = eim->cache_entry.w; + if (h) *h = eim->cache_entry.h; +} + +static int +evas_engine_sdl16_image_colorspace_get(void *data, void *image) +{ + (void) data; + (void) image; + + return EVAS_COLORSPACE_RGB565_A5P; +} + +static void +evas_engine_sdl16_image_colorspace_set(void *data, void *image, int cspace) +{ + (void) data; + (void) image; + + /* FIXME: Not implemented. */ +} + +static void* +evas_engine_sdl16_image_new_from_copied_data(void *data, + int w, int h, + DATA32* image_data, + int alpha, int cspace) +{ + Render_Engine *re = data; + + if (cspace != EVAS_COLORSPACE_RGB565_A5P) + { + fprintf(stderr, "Unsupported colorspace %d in %s() (%s:%d)\n", + cspace, __FUNCTION__, __FILE__, __LINE__); + return NULL; + } + + fprintf(stderr, "s image_data: %p\n", image_data); + + return evas_cache_engine_image_copied_data(re->cache, + w, h, + image_data, + alpha, cspace, NULL); +} + +static void* +evas_engine_sdl16_image_new_from_data(void *data, int w, int h, DATA32* image_data, int alpha, int cspace) +{ + Render_Engine *re = data; + + if (cspace != EVAS_COLORSPACE_RGB565_A5P) + { + fprintf(stderr, "Unsupported colorspace %d in %s() (%s:%d)\n", + cspace, __FUNCTION__, __FILE__, __LINE__); + return NULL; + } + + return evas_cache_engine_image_data(re->cache, + w, h, + image_data, + alpha, cspace, NULL); +} + +static void +evas_engine_sdl16_image_free(void *data, void *image) +{ + SDL_Engine_Image_Entry *eim = image; + + (void) data; + + evas_cache_engine_image_drop(&eim->cache_entry); +} + +static void* +evas_engine_sdl16_image_size_set(void *data, void *image, int w, int h) +{ + SDL_Engine_Image_Entry *eim = image; + + (void) data; + + return evas_cache_engine_image_size_set(&eim->cache_entry, w, h); +} + +static void* +evas_engine_sdl16_image_dirty_region(void *data, + void *image, + int x, int y, int w, int h) +{ + SDL_Engine_Image_Entry *eim = image; + + (void) data; + + return evas_cache_engine_image_dirty(&eim->cache_entry, x, y, w, h); +} + +static void* +evas_engine_sdl16_image_data_get(void *data, void *image, + int to_write, DATA32** image_data) +{ + SDL_Engine_Image_Entry *eim = image; + Soft16_Image *im; + + (void) data; + + if (!eim) + { + *image_data = NULL; + return NULL; + } + im = (Soft16_Image *) eim->cache_entry.src; + evas_cache_image_load_data(&im->cache_entry); + + if (to_write) + eim = (SDL_Engine_Image_Entry *) evas_cache_engine_image_alone(&eim->cache_entry, + NULL); + + /* FIXME: Handle colorspace convertion correctly. */ + if (image_data) *image_data = (DATA32 *) im->pixels; + + return eim; +} + +static void* +evas_engine_sdl16_image_data_put(void *data, void *image, DATA32* image_data) +{ + SDL_Engine_Image_Entry *eim = image; + SDL_Engine_Image_Entry *eim_new; + Render_Engine *re = data; + Soft16_Image *im; + + if (!eim) return NULL; + im = (Soft16_Image *) eim->cache_entry.src; + + /* FIXME: Handle colorspace convertion correctly. */ + if ((DATA16 *) image_data == im->pixels) return eim; + + eim_new = (SDL_Engine_Image_Entry *) evas_cache_engine_image_data(re->cache, + eim->cache_entry.w, eim->cache_entry.h, + image_data, + func.image_alpha_get(data, eim), + func.image_colorspace_get(data, eim), + NULL); + evas_cache_engine_image_drop(&eim->cache_entry); + + return eim_new; +} + +static void* +evas_engine_sdl16_image_alpha_set(void *data, void *image, int has_alpha) +{ + SDL_Engine_Image_Entry *eim = image; + Soft16_Image *im; + + (void) data; + + if (!eim) return NULL; + + im = (Soft16_Image *) eim->cache_entry.src; + + if (im->flags.have_alpha == has_alpha) return eim; + + eim = (SDL_Engine_Image_Entry *) evas_cache_engine_image_alone(&eim->cache_entry, + NULL); + + im = (Soft16_Image *) eim->cache_entry.src; + + im->flags.have_alpha = has_alpha; + eim = (SDL_Engine_Image_Entry *) evas_cache_engine_image_dirty(&eim->cache_entry, 0, 0, eim->cache_entry.w, eim->cache_entry.h); + + return eim; +} + +static void* +evas_engine_sdl16_image_border_set(void *data, void *image, int l, int r, int t, int b) +{ + return image; +} + +static void +evas_engine_sdl16_image_border_get(void *data, void *image, int *l, int *r, int *t, int *b) +{ + /* FIXME: need to know what evas expect from this call */ +} + +static void +evas_engine_sdl16_image_draw(void *data, void *context, void *surface, void *image, + int src_region_x, int src_region_y, int src_region_w, int src_region_h, + int dst_region_x, int dst_region_y, int dst_region_w, int dst_region_h, + int smooth) +{ + SDL_Engine_Image_Entry *eim = image; + SDL_Engine_Image_Entry *dst = surface; + int mustlock_im = 0; + int mustlock_dst = 0; + + (void) data; + + evas_cache_engine_image_load_data(&eim->cache_entry); + + /* Fallback to software method */ + if (SDL_MUSTLOCK(dst->surface)) + { + mustlock_dst = 1; + SDL_LockSurface(dst->surface); + _SDL_UPDATE_PIXELS(dst); + } + + if (eim->surface && SDL_MUSTLOCK(eim->surface)) + { + mustlock_im = 1; + SDL_LockSurface(eim->surface); + _SDL_UPDATE_PIXELS(eim); + } + + soft16_image_draw((Soft16_Image *) eim->cache_entry.src, + (Soft16_Image *) dst->cache_entry.src, + context, + src_region_x, src_region_y, src_region_w, src_region_h, + dst_region_x, dst_region_y, dst_region_w, dst_region_h, + smooth); + + if (mustlock_im) + SDL_UnlockSurface(eim->surface); + + if (mustlock_dst) + SDL_UnlockSurface(dst->surface); +} + +static void +evas_engine_sdl16_image_cache_flush(void *data) +{ + Render_Engine *re = (Render_Engine*) data; + int size; + + size = evas_cache_engine_image_get(re->cache); + evas_cache_engine_image_set(re->cache, 0); + evas_cache_engine_image_set(re->cache, size); +} + +static void +evas_engine_sdl16_image_cache_set(void *data, int bytes) +{ + Render_Engine *re = (Render_Engine*) data; + + evas_cache_engine_image_set(re->cache, bytes); +} + +static int +evas_engine_sdl16_image_cache_get(void *data) +{ + Render_Engine *re = (Render_Engine*) data; + + return evas_cache_engine_image_get(re->cache); +} + +static char* +evas_engine_sdl16_image_comment_get(void *data, void *image, char *key) +{ + (void) data; + (void) image; + (void) key; + + return NULL; +} + +static char* +evas_engine_sdl16_image_format_get(void *data, void *image) +{ + /* FIXME: need to know what evas expect from this call */ + return NULL; +} + +static void +evas_engine_sdl16_font_draw(void *data, void *context, void *surface, void *font, int x, int y, int w, int h, int ow, int oh, const char *text) +{ + static RGBA_Image *im = NULL; + SDL_Engine_Image_Entry *eim = surface; + Soft16_Image *dst = (Soft16_Image *) eim->cache_entry.src; + int mustlock_im = 0; + + if (!im) + im = (RGBA_Image *) evas_cache_image_empty(evas_common_image_cache_get()); + evas_cache_image_surface_alloc(&im->cache_entry, dst->cache_entry.w, dst->cache_entry.h); + + if (eim->surface && SDL_MUSTLOCK(eim->surface)) + { + mustlock_im = 1; + SDL_LockSurface(eim->surface); + _SDL_UPDATE_PIXELS(eim); + } + evas_common_draw_context_font_ext_set(context, + dst, + soft16_font_glyph_new, + soft16_font_glyph_free, + soft16_font_glyph_draw); + evas_common_font_draw(im, context, font, x, y, text); + evas_common_draw_context_font_ext_set(context, + NULL, + NULL, + NULL, + NULL); + + if (mustlock_im) + SDL_UnlockSurface(eim->surface); +} + +static void +evas_engine_sdl16_line_draw(void *data, void *context, void *surface, int x1, int y1, int x2, int y2) +{ + SDL_Engine_Image_Entry *eim = surface; + int mustlock_im = 0; + + if (eim->surface && SDL_MUSTLOCK(eim->surface)) + { + mustlock_im = 1; + SDL_LockSurface(eim->surface); + _SDL_UPDATE_PIXELS(eim); + } + + soft16_line_draw((Soft16_Image *) eim->cache_entry.src, + context, + x1, y1, x2, y2); + + if (mustlock_im) + SDL_UnlockSurface(eim->surface); +} + +static void +evas_engine_sdl16_rectangle_draw(void *data, void *context, void *surface, int x, int y, int w, int h) +{ + SDL_Engine_Image_Entry *eim = surface; +#if ENGINE_SDL_PRIMITIVE + RGBA_Draw_Context *dc = context; +#endif + Soft16_Image *im; + int mustlock_im = 0; + +#if ENGINE_SDL_PRIMITIVE + if (A_VAL(&dc->col.col) != 0x00) + { + if (A_VAL(&dc->col.col) != 0xFF) + { +#endif + if (eim->surface && SDL_MUSTLOCK(eim->surface)) + { + mustlock_im = 1; + SDL_LockSurface(eim->surface); + _SDL_UPDATE_PIXELS(eim); + } + + im = (Soft16_Image *) eim->cache_entry.src; + + soft16_rectangle_draw(im, context, x, y, w, h); + + if (mustlock_im) + SDL_UnlockSurface(eim->surface); +#if ENGINE_SDL_PRIMITIVE + } + else + { + SDL_Rect dstrect; + + if (dc->clip.use) + { + SDL_Rect cliprect; + + cliprect.x = dc->clip.x; + cliprect.y = dc->clip.y; + cliprect.w = dc->clip.w; + cliprect.h = dc->clip.h; + + SDL_SetClipRect(eim->surface, &cliprect); + } + + dstrect.x = x; + dstrect.y = y; + dstrect.w = w; + dstrect.h = h; + + SDL_FillRect(eim->surface, &dstrect, SDL_MapRGBA(eim->surface->format, R_VAL(&dc->col.col), G_VAL(&dc->col.col), B_VAL(&dc->col.col), 0xFF)); + + if (dc->clip.use) + SDL_SetClipRect(eim->surface, NULL); + } + } +#endif +} + +static void +evas_engine_sdl16_polygon_draw(void *data, void *context, void *surface, void *polygon) +{ + SDL_Engine_Image_Entry *eim = surface; + int mustlock_im = 0; + + if (eim->surface && SDL_MUSTLOCK(eim->surface)) + { + mustlock_im = 1; + SDL_LockSurface(eim->surface); + _SDL_UPDATE_PIXELS(eim); + } + + soft16_polygon_draw((Soft16_Image *) eim->cache_entry.src, context, polygon); + + if (mustlock_im) + SDL_UnlockSurface(eim->surface); +} + +static void +evas_engine_sdl16_image_stride_get(void *data, void *image, int *stride) +{ + SDL_Engine_Image_Entry *eim = image; + + if (stride) *stride = 0; + if (!image) return; + if (stride) *stride = ((Soft16_Image*) eim->cache_entry.src)->stride; +} + +/* module advertising code */ +EAPI int +module_open(Evas_Module *em) +{ + if (!em) return 0; + /* get whatever engine module we inherit from */ + if (!_evas_module_engine_inherit(&pfunc, "software_16")) return 0; + /* store it for later use */ + func = pfunc; + /* now to override methods */ +#define ORD(f) EVAS_API_OVERRIDE(f, &func, evas_engine_sdl16_) + ORD(info); + ORD(info_free); + ORD(setup); + ORD(output_free); + ORD(output_resize); + ORD(output_tile_size_set); + ORD(output_redraws_rect_add); + ORD(output_redraws_rect_del); + ORD(output_redraws_clear); + ORD(output_redraws_next_update_get); + ORD(output_redraws_next_update_push); + ORD(output_flush); + ORD(output_idle_flush); + ORD(image_load); + ORD(image_alpha_get); + ORD(image_size_get); + ORD(image_colorspace_get); + ORD(image_colorspace_set); + ORD(image_new_from_copied_data); + ORD(image_new_from_data); + ORD(image_free); + ORD(image_size_set); + ORD(image_dirty_region); + ORD(image_data_get); + ORD(image_data_put); + ORD(image_alpha_set); + ORD(image_border_set); + ORD(image_border_get); + ORD(image_draw); + ORD(image_cache_flush); + ORD(image_cache_set); + ORD(image_cache_get); + ORD(image_comment_get); + ORD(image_format_get); + ORD(image_stride_get); + ORD(font_draw); + ORD(line_draw); + ORD(rectangle_draw); + ORD(polygon_draw); + /* now advertise out own api */ + em->functions = (void *)(&func); + return 1; +} + +EAPI void +module_close(void) +{ +} + +EAPI Evas_Module_Api evas_modapi = +{ + EVAS_MODULE_API_VERSION, + EVAS_MODULE_TYPE_ENGINE, + "software_16_sdl", + "none" +}; + +static Engine_Image_Entry* +_sdl16_image_alloc(void) +{ + SDL_Engine_Image_Entry *new; + + new = calloc(1, sizeof (SDL_Engine_Image_Entry)); + + return (Engine_Image_Entry *) new; +} + +static void +_sdl16_image_delete(Engine_Image_Entry *eim) +{ + free(eim); +} + +static int +_sdl16_image_constructor(Engine_Image_Entry *ie, void* data) +{ + SDL_Surface *sdl = NULL; + SDL_Engine_Image_Entry *eim = (SDL_Engine_Image_Entry *) ie; + Soft16_Image *im; + + im = (Soft16_Image *) ie->src; + + if (im->pixels) + { + /* FIXME: Take care of CSPACE */ + sdl = SDL_CreateRGBSurfaceFrom(im->pixels, + ie->w, ie->h, + 16, ie->w * 2, + RMASK565, GMASK565, BMASK565, AMASK565); + eim->surface = sdl; + eim->flags.engine_surface = 0; + } + + return 0; +} + +static void +_sdl16_image_destructor(Engine_Image_Entry *eim) +{ + SDL_Engine_Image_Entry *seie = (SDL_Engine_Image_Entry *) eim; + + if (seie->surface && !seie->flags.engine_surface) + SDL_FreeSurface(seie->surface); + seie->surface = NULL; +} + +static void +_sdl16_image_dirty_region(Engine_Image_Entry *eim, int x, int y, int w, int h) +{ + SDL_Engine_Image_Entry *dst; + + dst = (SDL_Engine_Image_Entry *) eim; + + SDL_UpdateRect(dst->surface, x, y, w, h); +} + +static int +_sdl16_image_dirty(Engine_Image_Entry *dst, const Engine_Image_Entry *src) +{ + SDL_Engine_Image_Entry *eim = (SDL_Engine_Image_Entry *) dst; + SDL_Surface *sdl = NULL; + Soft16_Image *im; + + im = (Soft16_Image *) dst->src; + + /* FIXME: Take care of CSPACE */ + sdl = SDL_CreateRGBSurfaceFrom(im->pixels, + dst->w, dst->h, + 16, dst->w * 2, + RMASK565, GMASK565, BMASK565, AMASK565); + eim->surface = sdl; + eim->flags.engine_surface = 0; + + return 0; +} + +static int +_sdl16_image_size_set(Engine_Image_Entry *dst, const Engine_Image_Entry *src) +{ + SDL_Engine_Image_Entry *eim = (SDL_Engine_Image_Entry *) dst; + SDL_Surface *sdl; + Soft16_Image *im; + + im = (Soft16_Image *) dst->src; + + /* FIXME: handle im == NULL */ + sdl = SDL_CreateRGBSurfaceFrom(im->pixels, + dst->w, dst->h, + 16, dst->w * 2, + RMASK565, GMASK565, BMASK565, AMASK565); + + eim->surface = sdl; + + return 0; +} + +static int +_sdl16_image_update_data(Engine_Image_Entry* dst, void* engine_data) +{ + SDL_Engine_Image_Entry *eim = (SDL_Engine_Image_Entry *) dst; + SDL_Surface *sdl = NULL; + Soft16_Image *im; + + im = (Soft16_Image *) dst->src; + + if (engine_data) + { + sdl = engine_data; + + if (im) + { + im->pixels = sdl->pixels; + im->stride = sdl->pitch / 2; + im->flags.free_pixels = 0; +/* im->alpha = calloc(1, sizeof (DATA8) * _calc_stride(sdl->w) * sdl->h); */ +/* im->flags.free_alpha = 0; */ +/* im->flags.have_alpha = 1; */ + im->alpha = NULL; + im->flags.free_alpha = 0; + im->flags.have_alpha = 0; + + dst->src->w = sdl->w; + dst->src->h = sdl->h; + } + dst->w = sdl->w; + dst->h = sdl->h; + } + else + { + SDL_FreeSurface(eim->surface); + /* FIXME: Take care of CSPACE */ + sdl = SDL_CreateRGBSurfaceFrom(im->pixels, + dst->w, dst->h, + 16, dst->w * 2, + RMASK565, GMASK565, BMASK565, AMASK565); + } + + eim->surface = sdl; + + return 0; +} + +static void +_sdl16_image_load(Engine_Image_Entry *eim, const Image_Entry* ie_im) +{ + SDL_Engine_Image_Entry *load = (SDL_Engine_Image_Entry *) eim; + SDL_Surface *sdl; + + if (!load->surface) + { + Soft16_Image *im; + + im = (Soft16_Image *) ie_im; + + sdl = SDL_CreateRGBSurfaceFrom(im->pixels, + eim->w, eim->h, + 16, eim->w * 2, + RMASK565, GMASK565, BMASK565, AMASK565); + load->surface = sdl; + } +} + +static int +_sdl16_image_mem_size_get(Engine_Image_Entry *eim) +{ + SDL_Engine_Image_Entry *seie = (SDL_Engine_Image_Entry *) eim; + int size = 0; + + /* FIXME: Count surface size. */ + if (seie->surface) + size = sizeof (SDL_Surface) + sizeof (SDL_PixelFormat); + + return size; +} + +#ifdef DEBUG_SDL +static void +_sdl16_image_debug(const char* context, Engine_Image_Entry* im) +{ +} +#endif diff --git a/legacy/evas/src/modules/engines/software_16_sdl/evas_engine.h b/legacy/evas/src/modules/engines/software_16_sdl/evas_engine.h new file mode 100644 index 0000000000..03a1e36adc --- /dev/null +++ b/legacy/evas/src/modules/engines/software_16_sdl/evas_engine.h @@ -0,0 +1,54 @@ +#ifndef EVAS_ENGINE_SDL_16_H +#define EVAS_ENGINE_SDL_16_H + +#include "evas_common.h" +#include "evas_private.h" +#include "evas_common_soft16.h" +#include "Evas_Engine_SDL_16.h" + +typedef struct _SDL_Engine_Image_Entry SDL_Engine_Image_Entry; +struct _SDL_Engine_Image_Entry +{ + Engine_Image_Entry cache_entry; + + SDL_Surface *surface; + + struct + { + unsigned int engine_surface : 1; + } flags; +}; + + +typedef struct _Render_Engine Render_Engine; +struct _Render_Engine +{ + SDL_Engine_Image_Entry *soft16_engine_image; + + Evas_Cache_Engine_Image *cache; + + Soft16_Image *tmp_out; + + int w; + int h; + int rot; + + Tilebuf *tb; + Tilebuf_Rect *rects; + Tilebuf_Rect *cur_rect; + + SDL_Rect *update_rects; + int update_rects_count; + int update_rects_limit; + + struct + { + unsigned int fullscreen : 1; + unsigned int noframe : 1; + unsigned int alpha : 1; + unsigned int hwsurface : 1; + unsigned int end : 1; + } flags; +}; + +#endif