/* * Copyright 2012 Michael Drake * * 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 #include #include #include #include "palette.h" /** Create an empty palette object. */ bool nsfb_palette_new(struct nsfb_palette_s **palette, int width) { *palette = malloc(sizeof(struct nsfb_palette_s)); if (*palette == NULL) { return false; } (*palette)->type = NSFB_PALETTE_EMPTY; (*palette)->last = 0; (*palette)->dither = false; (*palette)->dither_ctx.data_len = width * 3 * sizeof(int); (*palette)->dither_ctx.data = malloc(width * 3 * sizeof(int)); if ((*palette)->dither_ctx.data == NULL) { nsfb_palette_free(*palette); return false; } return true; } /** Free a palette object. */ void nsfb_palette_free(struct nsfb_palette_s *palette) { if (palette != NULL) { if (palette->dither_ctx.data != NULL) { free(palette->dither_ctx.data); } free(palette); } } /** Init error diffusion for a plot. */ void nsfb_palette_dither_init(struct nsfb_palette_s *palette, int width) { palette->dither = true; memset(palette->dither_ctx.data, 0, palette->dither_ctx.data_len); palette->dither_ctx.width = width * 3; palette->dither_ctx.current = 0; } /** Finalise error diffusion after a plot. */ void nsfb_palette_dither_fini(struct nsfb_palette_s *palette) { palette->dither = false; } /** 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; }