Haio 0.2.X
Homebrew Asset IO/CDN
Loading...
Searching...
No Matches
haio_palette.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "haio_codec.hpp"
4
5#include <span>
6#include <string_view>
7
8namespace Haio {
9
10/**
11 * the palettes haio knows by name, and the way to ask for part of one.
12 *
13 * a name on its own is the whole palette, and a colon takes a slice of one:
14 *
15 * cga every colour it has
16 * cga:2 the second bank, where a bank is as wide as the picture needs
17 * cga:1..3 those colours, counted from one
18 * cga:1,4,7 the same, spelled out
19 * cga:1..3,7 and the two together
20 *
21 * a colon rather than brackets so that a shell leaves it alone: "<" and ">" are
22 * redirections, and a palette nobody can type without quoting is a palette nobody
23 * types.
24 *
25 * the bank form is why the picture has to be known before the palette is: a two bit
26 * image wants four colours, so its second bank is 5 to 8, while a three colour one
27 * has 4 to 6 there. saying it as a bank rather than a list is what lets the same
28 * spelling follow a picture that changes depth.
29 */
30Result<std::vector<uint32_t>> paletteNamed(std::string_view spec, size_t wanted);
31
32/** every name paletteNamed answers to, for the help text and the error message */
33std::span<const std::string_view> paletteNames();
34
35/**
36 * how a colour that is not in the palette becomes one that is.
37 *
38 * there is no default on purpose. every one of these changes the picture in a way
39 * somebody has to want: nearest flattens a gradient into bands, the dithers trade
40 * that for a pattern that is wrong at every single pixel, and strict refuses a
41 * picture that was not already in the palette. choosing for the caller would mean
42 * choosing what their art looks like.
43 */
44enum class Dither {
45 Nearest, /**< the closest colour there is */
46 Bayer, /**< ordered, a fixed 4x4 threshold: no state, same answer every time */
47 Floyd, /**< error diffusion: best on photographs, and serial by nature */
48 Strict, /**< every colour must already be in the palette, or it is an error */
49};
50
51/** the spelling used on the command line, or nothing when it is not one of them */
52std::optional<Dither> ditherNamed(std::string_view name);
53
54/**
55 * fits a true colour picture into a palette.
56 *
57 * the palette is given rather than derived: haio does not pick colours for anybody,
58 * it puts a picture into the colours it was handed.
59 */
60Result<Image<Color::PALETTE>> toPalette(const Image<Color::RGBA8888>& image,
61 std::vector<uint32_t> entries, Dither how);
62
63/**
64 * which colours to keep when a palette has more than was asked for.
65 *
66 * taking the first N is never right: a master palette is ordered by how the hardware
67 * addresses it, so the first sixteen of the nes are sixteen dark blues. counting
68 * which colours a picture would use is better, but counting alone has a bias of its
69 * own, and the two answers differ enough to be worth choosing between.
70 */
71enum class Limit {
72 /**
73 * the most used, plainly.
74 *
75 * right when the picture is the subject: a sprite sheet, a logo, anything where
76 * area and importance are the same thing.
77 */
79
80 /**
81 * the most used, less whatever a chosen colour already covers.
82 *
83 * a photograph is mostly background, so counting alone spends the whole budget on
84 * eighteen shades of sky and leaves the subject sharing one brown. this keeps the
85 * first colour by count and then, each time, takes the one whose count times its
86 * distance from everything already kept is largest. a colour that is rare but
87 * unlike anything chosen beats a common one that is nearly a duplicate.
88 */
90};
91
92/** "sort" or "spread", or nothing when it is neither */
93std::optional<Limit> limitNamed(std::string_view name);
94
95Result<std::vector<uint32_t>> limitPalette(const Image<Color::RGBA8888>& image,
96 std::vector<uint32_t> entries, size_t most, Limit how);
97
98}
Definition haio.hpp:11
Result< std::vector< uint32_t > > limitPalette(const Image< Color::RGBA8888 > &image, std::vector< uint32_t > entries, size_t most, Limit how)
Definition quantise.cpp:70
Result< Image< Color::PALETTE > > toPalette(const Image< Color::RGBA8888 > &image, std::vector< uint32_t > entries, Dither how)
Definition quantise.cpp:146
Result< std::vector< uint32_t > > paletteNamed(std::string_view spec, size_t wanted)
Definition known.cpp:91
std::expected< T, Error > Result
std::span< const std::string_view > paletteNames()
Definition known.cpp:82
std::optional< Dither > ditherNamed(std::string_view name)
Definition quantise.cpp:56
std::optional< Limit > limitNamed(std::string_view name)
Definition quantise.cpp:64