diff options
author | Michael Drake <tlsa@netsurf-browser.org> | 2012-09-27 13:46:10 +0100 |
---|---|---|
committer | Michael Drake <tlsa@netsurf-browser.org> | 2012-09-27 13:46:10 +0100 |
commit | 46f3c9ea3793d146337c81bf8858d99238c05e86 (patch) | |
tree | 7fd5c6aaeed21e01f8ea5565d9b65016f34657ec /src | |
parent | 1983c37933d2a753c4c913527c94392682bf7b98 (diff) | |
download | libnsfb-46f3c9ea3793d146337c81bf8858d99238c05e86.tar.gz libnsfb-46f3c9ea3793d146337c81bf8858d99238c05e86.tar.bz2 |
Add palette object. Optimise matching colour in case where we chose the palette. In other cases, we still have to seach all the colours, but that doesn't ever seem to be used.
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile | 2 | ||||
-rw-r--r-- | src/libnsfb.c | 5 | ||||
-rw-r--r-- | src/palette.c | 89 | ||||
-rw-r--r-- | src/plot/8bpp.c | 32 | ||||
-rw-r--r-- | src/surface/sdl.c | 52 |
5 files changed, 115 insertions, 65 deletions
diff --git a/src/Makefile b/src/Makefile index 283a99f..3c6e2f0 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,4 +1,4 @@ # Sources -DIR_SOURCES := libnsfb.c dump.c cursor.c +DIR_SOURCES := libnsfb.c dump.c cursor.c palette.c include $(NSBUILD)/Makefile.subdir diff --git a/src/libnsfb.c b/src/libnsfb.c index 6f14c99..a341088 100644 --- a/src/libnsfb.c +++ b/src/libnsfb.c @@ -15,6 +15,7 @@ #include "libnsfb_plot.h" #include "libnsfb_event.h" #include "nsfb.h" +#include "palette.h" #include "surface.h" /* exported interface documented in libnsfb.h */ @@ -50,6 +51,10 @@ int nsfb_free(nsfb_t *nsfb) { int ret; + + if (nsfb->palette != NULL) + nsfb_palette_free(nsfb->palette); + ret = nsfb->surface_rtns->finalise(nsfb); free(nsfb); return ret; diff --git a/src/palette.c b/src/palette.c new file mode 100644 index 0000000..eba95cd --- /dev/null +++ b/src/palette.c @@ -0,0 +1,89 @@ +/* + * Copyright 2012 Michael Drake <tlsa@netsurf-browser.org> + * + * This file is part of libnsfb, http://www.netsurf-browser.org/ + * Licenced under the MIT License, + * http://www.opensource.org/licenses/mit-license.php + */ + +/** \file + * Palette (implementation). + */ + +#include <assert.h> +#include <stdbool.h> +#include <stdlib.h> + +#include "palette.h" + + +/** Create an empty palette object. */ +bool nsfb_palette_new(struct nsfb_palette_s **palette) +{ + *palette = malloc(sizeof(struct nsfb_palette_s)); + if (*palette == NULL) { + return false; + } + + (*palette)->type = NSFB_PALETTE_EMPTY; + (*palette)->last = 0; + + return true; +} + +/** Free a palette object. */ +void nsfb_palette_free(struct nsfb_palette_s *palette) +{ + if (palette != NULL) + free(palette); +} + +/** Generate libnsfb 8bpp default palette. */ +void nsfb_palette_generate_nsfb_8bpp(struct nsfb_palette_s *palette) +{ + int rloop, gloop, bloop; + int loop = 0; + uint8_t r, g, b; + + /* Build a linear 6-8-5 levels RGB colour cube palette. + * This accounts for 240 colours */ +#define RLIM 6 +#define GLIM 8 +#define BLIM 5 + for (rloop = 0; rloop < RLIM; rloop++) { + for (gloop = 0; gloop < GLIM; gloop++) { + for (bloop = 0; bloop < BLIM; bloop++) { + r = ((rloop * 255 * 2) + RLIM - 1) / + (2 * (RLIM - 1)); + g = ((gloop * 255 * 2) + GLIM - 1) / + (2 * (GLIM - 1)); + b = ((bloop * 255 * 2) + BLIM - 1) / + (2 * (BLIM - 1)); + + palette->data[loop] = r | g << 8 | b << 16; + loop++; + } + } + } +#undef RLIM +#undef GLIM +#undef BLIM + + /* Should have 240 colours set */ + assert(loop == 240); + + /* Fill index 240 to index 255 with grayscales */ + /* Note: already have full black and full white from RGB cube */ + for (; loop < 256; loop++) { + int ngray = loop - 240 + 1; + r = ngray * 15; /* 17*15 = 255 */ + + g = b = r; + + palette->data[loop] = r | g << 8 | b << 16; + } + + /* Set palette details */ + palette->type = NSFB_PALETTE_NSFB_8BPP; + palette->last = 255; +} diff --git a/src/plot/8bpp.c b/src/plot/8bpp.c index b72303d..05574d8 100644 --- a/src/plot/8bpp.c +++ b/src/plot/8bpp.c @@ -10,7 +10,6 @@ #include <stdbool.h> #include <endian.h> #include <stdlib.h> -#include <limits.h> #include <string.h> #include "libnsfb.h" @@ -18,6 +17,7 @@ #include "libnsfb_plot_util.h" #include "nsfb.h" +#include "palette.h" #include "plot.h" static inline uint8_t *get_xy_loc(nsfb_t *nsfb, int x, int y) @@ -28,34 +28,18 @@ static inline uint8_t *get_xy_loc(nsfb_t *nsfb, int x, int y) static inline nsfb_colour_t pixel_to_colour(nsfb_t *nsfb, uint8_t pixel) { - return nsfb->palette[pixel]; + if (nsfb->palette == NULL) + return 0; + + return nsfb->palette->data[pixel]; } static uint8_t colour_to_pixel(nsfb_t *nsfb, nsfb_colour_t c) { - nsfb_colour_t palent; - int col; - - int dr, dg, db; /* delta red, green blue values */ - - int cur_distance; - int best_distance = INT_MAX; - uint8_t best_col = 0; - - for (col = 0; col < 256; col++) { - palent = nsfb->palette[col]; - - dr = (c & 0xFF) - (palent & 0xFF); - dg = ((c >> 8) & 0xFF) - ((palent >> 8) & 0xFF); - db = ((c >> 16) & 0xFF) - ((palent >> 16) & 0xFF); - cur_distance = ((dr * dr) + (dg * dg) + (db *db)); - if (cur_distance < best_distance) { - best_distance = cur_distance; - best_col = col; - } - } + if (nsfb->palette == NULL) + return 0; - return best_col; + return nsfb_palette_best_match(nsfb->palette, c); } #define PLOT_TYPE uint8_t diff --git a/src/surface/sdl.c b/src/surface/sdl.c index d598b8a..7a86dc1 100644 --- a/src/surface/sdl.c +++ b/src/surface/sdl.c @@ -6,7 +6,6 @@ * http://www.opensource.org/licenses/mit-license.php */ -#include <assert.h> #include <stdbool.h> #include <stdlib.h> #include <SDL/SDL.h> @@ -18,6 +17,7 @@ #include "nsfb.h" #include "surface.h" +#include "palette.h" #include "plot.h" #include "cursor.h" @@ -353,49 +353,19 @@ set_palette(nsfb_t *nsfb) { SDL_Surface *sdl_screen = nsfb->surface_priv; SDL_Color palette[256]; - int rloop, gloop, bloop; int loop = 0; - /* Build a linear 6-8-5 levels RGB colour cube palette. - * This accounts for 240 colours */ -#define RLIM 6 -#define GLIM 8 -#define BLIM 5 - for (rloop = 0; rloop < RLIM; rloop++) { - for (gloop = 0; gloop < GLIM; gloop++) { - for (bloop = 0; bloop < BLIM; bloop++) { - palette[loop].r = ((rloop * 255 * 2) + RLIM - 1) / (2 * (RLIM - 1)); - palette[loop].g = ((gloop * 255 * 2) + GLIM - 1) / (2 * (GLIM - 1)); - palette[loop].b = ((bloop * 255 * 2) + BLIM - 1) / (2 * (BLIM - 1)); - - nsfb->palette[loop] = palette[loop].r | - palette[loop].g << 8 | - palette[loop].b << 16; - loop++; - } - } - } -#undef RLIM -#undef GLIM -#undef BLIM - - /* Should have 240 colours set */ - assert(loop == 240); + /* Get libnsfb palette */ + nsfb_palette_generate_nsfb_8bpp(nsfb->palette); - /* Fill index 240 to index 255 with grayscales */ - /* Note: already have full black and full white from RGB cube */ - for (; loop < 256; loop++) { - int ngray = loop - 240 + 1; - palette[loop].r = ngray * 15; /* 17*15 = 255 */ - - palette[loop].g = palette[loop].b = palette[loop].r; - - nsfb->palette[loop] = palette[loop].r | - palette[loop].g << 8 | - palette[loop].b << 16; + /* Create SDL palette from nsfb palette */ + for (loop = 0; loop < 256; loop++) { + palette[loop].r = (nsfb->palette->data[loop] ) & 0xFF; + palette[loop].g = (nsfb->palette->data[loop] >> 8) & 0xFF; + palette[loop].b = (nsfb->palette->data[loop] >> 16) & 0xFF; } - /* Set palette */ + /* Set SDL palette */ SDL_SetColors(sdl_screen, palette, 0, 256); } @@ -487,8 +457,10 @@ static int sdl_initialise(nsfb_t *nsfb) nsfb->surface_priv = sdl_screen; - if (nsfb->bpp == 8) + if (nsfb->bpp == 8) { + nsfb_palette_new(&nsfb->palette); set_palette(nsfb); + } nsfb->ptr = sdl_screen->pixels; nsfb->linelen = sdl_screen->pitch; |