4 ms·
A faster alternative, using a LUT (lookup table): - At initialization time, from the given palette (e.g. the CSS palette), build a 16-bit (RGB565) to 8-bit LUT
by faragon 9y ago
A faster alternative, using a LUT (lookup table):
- At initialization time, from the given palette (e.g. the CSS palette), build a 16-bit (RGB565) to 8-bit LUT, and find for every 2^16 entry the nearest palette color. Time complexity: O(n^2), but done once, and can be avoided if having the LUT pre-calculated as a constant.
- At the image conversion, with per-pixel O(1) time complexity: for every RGB888 pixel, pack the pixel to RGB565, and use the LUT to find de palette index i.e. pal_index = lut[RGB888to565(pixel)]. With e.g. a 3 GHz modern 4-way OooE CPU you can convert pixels at > 1 Gpixel per second (> 10^9 pixels per second), because of the LUT high cache hit ratio.
In case of requiring more precision, you could use a 24-bit LUT (uint8_t[2²⁴] -> 16 MiB of memory, instead of the uint8_t[2¹⁶] -> 64 KiB of memory), or a intermediate case of willing to avoid running out of the L2/L3 cache e.g. a 21-bit LUT (RGB685, uint8_t[2^²¹] -> 2MiB). The 16-bit table would allow you run in the L1 data cache, being very fast (you could use even a smaller table, e.g. 15-bit RGB555 (32 KiB), or 14-bit RGB554 (16KiB), with similar results regarding color conversion, but with even lower L1 data cache requirements.