Skip to content

Instantly share code, notes, and snippets.

@harieamjari
Created June 13, 2023 17:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save harieamjari/509f665081f52b3dbdfc892b39cc3eab to your computer and use it in GitHub Desktop.
Save harieamjari/509f665081f52b3dbdfc892b39cc3eab to your computer and use it in GitHub Desktop.
Converts RGB values to VGA 256
/* rgb2vga.c - converts rgb values to vga 256. */
/* Copyright (c) 2023 Al-buharie Amjari */
/* Released under MIT License */
#include <math.h>
#include <stdint.h>
#include <stdio.h>
#define F(x) ((float)x)
float ndx_vgapal[256][3] = {
/* colors 0-15 */
{F(0x00), F(0x00), F(0x00)},
{F(0x00), F(0x00), F(0xAA)},
{F(0x00), F(0xAA), F(0x00)},
{F(0x00), F(0xAA), F(0xAA)},
{F(0xAA), F(0x00), F(0x00)},
{F(0xAA), F(0x00), F(0xAA)},
{F(0xAA), F(0x55), F(0x00)},
{F(0xAA), F(0xAA), F(0xAA)},
{F(0x55), F(0x55), F(0x55)},
{F(0x55), F(0x55), F(0xFF)},
{F(0x55), F(0xFF), F(0x55)},
{F(0x55), F(0xFF), F(0xFF)},
{F(0xFF), F(0x55), F(0x55)},
{F(0xFF), F(0x55), F(0xFF)},
{F(0xFF), F(0xFF), F(0x55)},
{F(0xFF), F(0xFF), F(0xFF)},
/* grayscale 16-31 (non gamma corrected) */
{F(0x00), F(0x00), F(0x00)},
{F(0x14), F(0x14), F(0x14)},
{F(0x20), F(0x20), F(0x20)},
{F(0x2C), F(0x2C), F(0x2C)},
{F(0x38), F(0x38), F(0x38)},
{F(0x45), F(0x45), F(0x45)},
{F(0x51), F(0x51), F(0x51)},
{F(0x61), F(0x61), F(0x61)},
{F(0x71), F(0x71), F(0x71)},
{F(0x82), F(0x82), F(0x82)},
{F(0x92), F(0x92), F(0x92)},
{F(0xA2), F(0xA2), F(0xA2)},
{F(0xB6), F(0xB6), F(0xB6)},
{F(0xCB), F(0xCB), F(0xCB)},
{F(0xE3), F(0xE3), F(0xE3)},
{F(0xFF), F(0xFF), F(0xFF)},
// HERE ------> 1
/* hue mix 32-55 (1) */
{F(0x00), F(0x00), F(0xFF)},
{F(0x41), F(0x00), F(0xFF)},
{F(0x7D), F(0x00), F(0xFF)},
{F(0xBE), F(0x00), F(0xFF)},
{F(0xFF), F(0x00), F(0xFF)},
{F(0xFF), F(0x00), F(0xBE)},
{F(0xFF), F(0x00), F(0x7D)},
{F(0xFF), F(0x00), F(0x41)},
{F(0xFF), F(0x00), F(0x00)},
{F(0xFF), F(0x41), F(0x00)},
{F(0xFF), F(0x7D), F(0x00)},
{F(0xFF), F(0xBE), F(0x00)},
{F(0xFF), F(0xFF), F(0x00)},
{F(0xBE), F(0xFF), F(0x00)},
{F(0x7D), F(0xFF), F(0x00)},
{F(0x41), F(0xFF), F(0x00)},
{F(0x00), F(0xFF), F(0x00)},
{F(0x00), F(0xFF), F(0x41)},
{F(0x00), F(0xFF), F(0x7D)},
{F(0x00), F(0xFF), F(0xBE)},
{F(0x00), F(0xFF), F(0xFF)},
{F(0x00), F(0xBE), F(0xFF)},
{F(0x00), F(0x7D), F(0xFF)},
{F(0x00), F(0x41), F(0xFF)},
/* hue mix 56-79 (2) */
{F(0x7D), F(0x7D), F(0xFF)},
{F(0x9E), F(0x7D), F(0xFF)},
{F(0xBE), F(0x7D), F(0xFF)},
{F(0xDF), F(0x7D), F(0xFF)},
{F(0xFF), F(0x7D), F(0xFF)},
{F(0xFF), F(0x7D), F(0xDF)},
{F(0xFF), F(0x7D), F(0xBE)},
{F(0xFF), F(0x7D), F(0x9E)},
{F(0xFF), F(0x7D), F(0x7D)},
{F(0xFF), F(0x9E), F(0x7D)},
{F(0xFF), F(0xBE), F(0x7D)},
{F(0xFF), F(0xDF), F(0x7D)},
{F(0xFF), F(0xFF), F(0x7D)},
{F(0xDF), F(0xFF), F(0x7D)},
{F(0xBE), F(0xFF), F(0x7D)},
{F(0x9E), F(0xFF), F(0x7D)},
{F(0x7D), F(0xFF), F(0x7D)},
{F(0x7D), F(0xFF), F(0x9E)},
{F(0x7D), F(0xFF), F(0xBE)},
{F(0x7D), F(0xFF), F(0xDF)},
{F(0x7D), F(0xFF), F(0xFF)},
{F(0x7D), F(0xDF), F(0xFF)},
{F(0x7D), F(0xBE), F(0xFF)},
{F(0x7D), F(0x9E), F(0xFF)},
/* hue mix 80-103 (3) */
{F(0xB6), F(0xB6), F(0xFF)},
{F(0xC7), F(0xB6), F(0xFF)},
{F(0xDB), F(0xB6), F(0xFF)},
{F(0xEB), F(0xB6), F(0xFF)},
{F(0xFF), F(0xB6), F(0xFF)},
{F(0xFF), F(0xB6), F(0xEB)},
{F(0xFF), F(0xB6), F(0xDB)},
{F(0xFF), F(0xB6), F(0xC7)},
{F(0xFF), F(0xB6), F(0xB6)},
{F(0xFF), F(0xC7), F(0xB6)},
{F(0xFF), F(0xDB), F(0xB6)},
{F(0xFF), F(0xEB), F(0xB6)},
{F(0xFF), F(0xFF), F(0xB6)},
{F(0xEB), F(0xFF), F(0xB6)},
{F(0xDB), F(0xFF), F(0xB6)},
{F(0xC7), F(0xFF), F(0xB6)},
{F(0xB6), F(0xFF), F(0xB6)},
{F(0xB6), F(0xFF), F(0xC7)},
{F(0xB6), F(0xFF), F(0xDB)},
{F(0xB6), F(0xFF), F(0xEB)},
{F(0xB6), F(0xFF), F(0xFF)},
{F(0xB6), F(0xEB), F(0xFF)},
{F(0xB6), F(0xDB), F(0xFF)},
{F(0xB6), F(0xC7), F(0xFF)},
// HERE ------> 2
/* hue mix 104-127 (4) dark 1 */
{F(0x00), F(0x00), F(0x71)},
{F(0x1C), F(0x00), F(0x71)},
{F(0x38), F(0x00), F(0x71)},
{F(0x55), F(0x00), F(0x71)},
{F(0x71), F(0x00), F(0x71)},
{F(0x71), F(0x00), F(0x55)},
{F(0x71), F(0x00), F(0x38)},
{F(0x71), F(0x00), F(0x1C)},
{F(0x71), F(0x00), F(0x00)},
{F(0x71), F(0x1C), F(0x00)},
{F(0x71), F(0x38), F(0x00)},
{F(0x71), F(0x55), F(0x00)},
{F(0x71), F(0x71), F(0x00)},
{F(0x55), F(0x71), F(0x00)},
{F(0x38), F(0x71), F(0x00)},
{F(0x1C), F(0x71), F(0x00)},
{F(0x00), F(0x71), F(0x00)},
{F(0x00), F(0x71), F(0x1C)},
{F(0x00), F(0x71), F(0x38)},
{F(0x00), F(0x71), F(0x55)},
{F(0x00), F(0x71), F(0x71)},
{F(0x00), F(0x55), F(0x71)},
{F(0x00), F(0x38), F(0x71)},
{F(0x00), F(0x1C), F(0x71)},
/* hue mix 56-79 (2) */
{F(0x38), F(0x38), F(0x71)},
{F(0x45), F(0x38), F(0x71)},
{F(0x55), F(0x38), F(0x71)},
{F(0x61), F(0x38), F(0x71)},
{F(0x71), F(0x38), F(0x71)},
{F(0x71), F(0x38), F(0x61)},
{F(0x71), F(0x38), F(0x55)},
{F(0x71), F(0x38), F(0x45)},
{F(0x71), F(0x38), F(0x38)},
{F(0x71), F(0x45), F(0x38)},
{F(0x71), F(0x55), F(0x38)},
{F(0x71), F(0x61), F(0x38)},
{F(0x71), F(0x71), F(0x38)},
{F(0x61), F(0x71), F(0x38)},
{F(0x55), F(0x71), F(0x38)},
{F(0x45), F(0x71), F(0x38)},
{F(0x38), F(0x71), F(0x38)},
{F(0x38), F(0x71), F(0x45)},
{F(0x38), F(0x71), F(0x55)},
{F(0x38), F(0x71), F(0x61)},
{F(0x38), F(0x71), F(0x71)},
{F(0x38), F(0x61), F(0x71)},
{F(0x38), F(0x55), F(0x71)},
{F(0x38), F(0x45), F(0x71)},
/* hue mix 80-103 (3) */
{F(0x51), F(0x51), F(0x71)},
{F(0x59), F(0x51), F(0x71)},
{F(0x61), F(0x51), F(0x71)},
{F(0x69), F(0x51), F(0x71)},
{F(0x71), F(0x51), F(0x71)},
{F(0x71), F(0x51), F(0x69)},
{F(0x71), F(0x51), F(0x61)},
{F(0x71), F(0x51), F(0x59)},
{F(0x71), F(0x51), F(0x51)},
{F(0x71), F(0x59), F(0x51)},
{F(0x71), F(0x61), F(0x51)},
{F(0x71), F(0x69), F(0x51)},
{F(0x71), F(0x71), F(0x51)},
{F(0x69), F(0x71), F(0x51)},
{F(0x61), F(0x71), F(0x51)},
{F(0x59), F(0x71), F(0x51)},
{F(0x51), F(0x71), F(0x51)},
{F(0x51), F(0x71), F(0x59)},
{F(0x51), F(0x71), F(0x61)},
{F(0x51), F(0x71), F(0x69)},
{F(0x51), F(0x71), F(0x71)},
{F(0x51), F(0x69), F(0x71)},
{F(0x51), F(0x61), F(0x71)},
{F(0x51), F(0x59), F(0x71)},
// HERE ------> 3
/* hue mix 104-127 (4) dark 1 */
{F(0x00), F(0x00), F(0x41)},
{F(0x10), F(0x00), F(0x41)},
{F(0x20), F(0x00), F(0x41)},
{F(0x30), F(0x00), F(0x41)},
{F(0x41), F(0x00), F(0x41)},
{F(0x41), F(0x00), F(0x30)},
{F(0x41), F(0x00), F(0x20)},
{F(0x41), F(0x00), F(0x10)},
{F(0x41), F(0x00), F(0x00)},
{F(0x41), F(0x10), F(0x00)},
{F(0x41), F(0x20), F(0x00)},
{F(0x41), F(0x30), F(0x00)},
{F(0x41), F(0x41), F(0x00)},
{F(0x30), F(0x41), F(0x00)},
{F(0x20), F(0x41), F(0x00)},
{F(0x10), F(0x41), F(0x00)},
{F(0x00), F(0x41), F(0x00)},
{F(0x00), F(0x41), F(0x10)},
{F(0x00), F(0x41), F(0x20)},
{F(0x00), F(0x41), F(0x30)},
{F(0x00), F(0x41), F(0x41)},
{F(0x00), F(0x30), F(0x41)},
{F(0x00), F(0x20), F(0x41)},
{F(0x00), F(0x10), F(0x41)},
/* hue mix 56-79 (2) */
{F(0x20), F(0x20), F(0x41)},
{F(0x28), F(0x20), F(0x41)},
{F(0x30), F(0x20), F(0x41)},
{F(0x3C), F(0x20), F(0x41)},
{F(0x41), F(0x20), F(0x41)},
{F(0x41), F(0x20), F(0x3C)},
{F(0x41), F(0x20), F(0x30)},
{F(0x41), F(0x20), F(0x28)},
{F(0x41), F(0x20), F(0x20)},
{F(0x41), F(0x28), F(0x20)},
{F(0x41), F(0x30), F(0x20)},
{F(0x41), F(0x3C), F(0x20)},
{F(0x41), F(0x41), F(0x20)},
{F(0x3C), F(0x41), F(0x20)},
{F(0x30), F(0x41), F(0x20)},
{F(0x28), F(0x41), F(0x20)},
{F(0x20), F(0x41), F(0x20)},
{F(0x20), F(0x41), F(0x28)},
{F(0x20), F(0x41), F(0x30)},
{F(0x20), F(0x41), F(0x3C)},
{F(0x20), F(0x41), F(0x41)},
{F(0x20), F(0x3C), F(0x41)},
{F(0x20), F(0x30), F(0x41)},
{F(0x20), F(0x28), F(0x41)},
/* hue mix 80-103 (3) */
{F(0x2C), F(0x2C), F(0x41)},
{F(0x30), F(0x2C), F(0x41)},
{F(0x34), F(0x2C), F(0x41)},
{F(0x3C), F(0x2C), F(0x41)},
{F(0x41), F(0x2C), F(0x41)},
{F(0x41), F(0x2C), F(0x3C)},
{F(0x41), F(0x2C), F(0x34)},
{F(0x41), F(0x2C), F(0x30)},
{F(0x41), F(0x2C), F(0x2C)},
{F(0x41), F(0x30), F(0x2C)},
{F(0x41), F(0x34), F(0x2C)},
{F(0x41), F(0x3C), F(0x2C)},
{F(0x41), F(0x41), F(0x2C)},
{F(0x3C), F(0x41), F(0x2C)},
{F(0x34), F(0x41), F(0x2C)},
{F(0x30), F(0x41), F(0x2C)},
{F(0x2C), F(0x41), F(0x2C)},
{F(0x2C), F(0x41), F(0x30)},
{F(0x2C), F(0x41), F(0x34)},
{F(0x2C), F(0x41), F(0x3C)},
{F(0x2C), F(0x41), F(0x41)},
{F(0x2C), F(0x3C), F(0x41)},
{F(0x2C), F(0x34), F(0x41)},
{F(0x2C), F(0x30), F(0x41)},
/* all black */
{F(0), F(0), F(0)},
{F(0), F(0), F(0)},
{F(0), F(0), F(0)},
{F(0), F(0), F(0)},
{F(0), F(0), F(0)},
{F(0), F(0), F(0)},
{F(0), F(0), F(0)},
{F(0), F(0), F(0)},
};
uint8_t rgb2vga(int r, int g, int b) {
float rf = (float)r, gf = (float)g, bf = (float)b;
float closest = +INFINITY;
int ndx = 0, done = 0;
// This is slow. For some reasons, those pragmas made it extra slow.
// #pragma omp parallel for
for (int i = 0; i < 248; i++) {
// if (done) continue;
float *sample = ndx_vgapal[i];
float rs = sample[0];
float gs = sample[1];
float bs = sample[2];
float dst =
sqrt(powf(rs - rf, 2.0) + powf(gs - gf, 2.0) + powf(bs - bf, 2.0));
// #pragma omp critical
{
if (closest > dst) {
closest = dst;
ndx = i;
} else if (dst < 0.05) {
done = 1;
ndx = i;
break;
}
}
}
return (uint8_t)ndx;
}
int main() {
FILE *fp = stdin;
while (!feof(fp)) {
int r = getc(fp);
int g = getc(fp);
int b = getc(fp);
putchar(rgb2vga(r, g, b));
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment