Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright 2012 Michael Drake <tlsa@netsurf-browser.org>
  3.  *
  4.  * This file is part of libnsfb, http://www.netsurf-browser.org/
  5.  * Licenced under the MIT License,
  6.  *                http://www.opensource.org/licenses/mit-license.php
  7.  */
  8.  
  9. /** \file
  10.  * Palette (implementation).
  11.  */
  12.  
  13. #include <assert.h>
  14. #include <stdbool.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17.  
  18. #include "palette.h"
  19.  
  20.  
  21. /** Create an empty palette object. */
  22. bool nsfb_palette_new(struct nsfb_palette_s **palette, int width)
  23. {
  24.         *palette = malloc(sizeof(struct nsfb_palette_s));
  25.         if (*palette == NULL) {
  26.                 return false;
  27.         }
  28.  
  29.         (*palette)->type = NSFB_PALETTE_EMPTY;
  30.         (*palette)->last = 0;
  31.  
  32.         (*palette)->dither = false;
  33.         (*palette)->dither_ctx.data_len = width * 3;
  34.         (*palette)->dither_ctx.data = malloc(width * 3 * sizeof(int));
  35.         if ((*palette)->dither_ctx.data == NULL) {
  36.                 nsfb_palette_free(*palette);
  37.                 return false;
  38.         }
  39.  
  40.         return true;
  41. }
  42.  
  43. /** Free a palette object. */
  44. void nsfb_palette_free(struct nsfb_palette_s *palette)
  45. {
  46.         if (palette != NULL) {
  47.                 if (palette->dither_ctx.data != NULL) {
  48.                         free(palette->dither_ctx.data);
  49.                 }
  50.                 free(palette);
  51.         }
  52. }
  53.  
  54. /** Init error diffusion for a plot. */
  55. void nsfb_palette_dither_init(struct nsfb_palette_s *palette, int width)
  56. {
  57.         palette->dither = true;
  58.         memset(palette->dither_ctx.data, 0, palette->dither_ctx.data_len);
  59.         palette->dither_ctx.width = width * 3;
  60.         palette->dither_ctx.current = 0;
  61. }
  62.  
  63. /** Finalise error diffusion after a plot. */
  64. void nsfb_palette_dither_fini(struct nsfb_palette_s *palette)
  65. {
  66.         palette->dither = false;
  67. }
  68.  
  69. /** Generate libnsfb 8bpp default palette. */
  70. void nsfb_palette_generate_nsfb_8bpp(struct nsfb_palette_s *palette)
  71. {
  72.         int rloop, gloop, bloop;
  73.         int loop = 0;
  74.         uint8_t r, g, b;
  75.  
  76.         /* Build a linear 6-8-5 levels RGB colour cube palette.
  77.          * This accounts for 240 colours */
  78. #define RLIM 6
  79. #define GLIM 8
  80. #define BLIM 5
  81.         for (rloop = 0; rloop < RLIM; rloop++) {
  82.                 for (gloop = 0; gloop < GLIM; gloop++) {
  83.                         for (bloop = 0; bloop < BLIM; bloop++) {
  84.                                 r = ((rloop * 255 * 2) + RLIM - 1) /
  85.                                                 (2 * (RLIM - 1));
  86.                                 g = ((gloop * 255 * 2) + GLIM - 1) /
  87.                                                 (2 * (GLIM - 1));
  88.                                 b = ((bloop * 255 * 2) + BLIM - 1) /
  89.                                                 (2 * (BLIM - 1));
  90.  
  91.                                 palette->data[loop] = r | g << 8 | b << 16;
  92.                                 loop++;
  93.                         }
  94.                 }
  95.         }
  96. #undef RLIM
  97. #undef GLIM
  98. #undef BLIM
  99.  
  100.         /* Should have 240 colours set */
  101.         assert(loop == 240);
  102.  
  103.         /* Fill index 240 to index 255 with grayscales */
  104.         /* Note: already have full black and full white from RGB cube */
  105.         for (; loop < 256; loop++) {
  106.                 int ngray = loop - 240 + 1;
  107.                 r = ngray * 15; /* 17*15 = 255 */
  108.  
  109.                 g = b = r;
  110.  
  111.                 palette->data[loop] = r | g << 8 | b << 16;
  112.         }
  113.  
  114.         /* Set palette details */
  115.         palette->type = NSFB_PALETTE_NSFB_8BPP;
  116.         palette->last = 255;
  117. }
  118.