Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
3584 sourcerer 1
/*
2
 * Copyright 2012 Michael Drake 
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 
14
#include 
15
#include 
16
#include 
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
}