colors

extract colors from pictures
git clone git://git.2f30.org/colors
Log | Files | Refs | README | LICENSE

hex2col.c (5636B)


      1 /* See LICENSE file for copyright and license details. */
      2 #include <stdio.h>
      3 #include <stdlib.h>
      4 #include <unistd.h>
      5 #include <string.h>
      6 
      7 /*
      8  * X.org 256 colors palette
      9  * http://www.calmar.ws/vim/256-xterm-24bit-rgb-color-chart.html
     10  */
     11 int map[256][3] = {
     12     {  0,  0,  0}, {128,  0,  0}, {  0,128,  0}, {128,128,  0}, {  0,  0,128}, {128,  0,128}, {  0,128,128}, {192,192,192},
     13     {128,128,128}, {255,  0,  0}, {  0,255,  0}, {255,255,  0}, {  0,  0,255}, {255,  0,255}, {  0,255,255}, {255,255,255},
     14     {  0,  0,  0}, {  0,  0, 95}, {  0,  0,135}, {  0,  0,175}, {  0,  0,215}, {  0,  0,255}, {  0, 95,  0}, {  0, 95, 95},
     15     {  0, 95,135}, {  0, 95,175}, {  0, 95,215}, {  0, 95,255}, {  0,135,  0}, {  0,135, 95}, {  0,135,135}, {  0,135,175},
     16     {  0,135,215}, {  0,135,255}, {  0,175,  0}, {  0,175, 95}, {  0,175,135}, {  0,175,175}, {  0,175,215}, {  0,175,255},
     17     {  0,215,  0}, {  0,215, 95}, {  0,215,135}, {  0,215,175}, {  0,215,215}, {  0,215,255}, {  0,255,  0}, {  0,255, 95},
     18     {  0,255,135}, {  0,255,175}, {  0,255,215}, {  0,255,255}, { 95,  0,  0}, { 95,  0, 95}, { 95,  0,135}, { 95,  0,175},
     19     { 95,  0,215}, { 95,  0,255}, { 95, 95,  0}, { 95, 95, 95}, { 95, 95,135}, { 95, 95,175}, { 95, 95,215}, { 95, 95,255},
     20     { 95,135,  0}, { 95,135, 95}, { 95,135,135}, { 95,135,175}, { 95,135,215}, { 95,135,255}, { 95,175,  0}, { 95,175, 95},
     21     { 95,175,135}, { 95,175,175}, { 95,175,215}, { 95,175,255}, { 95,215,  0}, { 95,215, 95}, { 95,215,135}, { 95,215,175},
     22     { 95,215,215}, { 95,215,255}, { 95,255,  0}, { 95,255, 95}, { 95,255,135}, { 95,255,175}, { 95,255,215}, { 95,255,255},
     23     {135,  0,  0}, {135,  0, 95}, {135,  0,135}, {135,  0,175}, {135,  0,215}, {135,  0,255}, {135, 95,  0}, {135, 95, 95},
     24     {135, 95,135}, {135, 95,175}, {135, 95,215}, {135, 95,255}, {135,135,  0}, {135,135, 95}, {135,135,135}, {135,135,175},
     25     {135,135,215}, {135,135,255}, {135,175,  0}, {135,175, 95}, {135,175,135}, {135,175,175}, {135,175,215}, {135,175,255},
     26     {135,215,  0}, {135,215, 95}, {135,215,135}, {135,215,175}, {135,215,215}, {135,215,255}, {135,255,  0}, {135,255, 95},
     27     {135,255,135}, {135,255,175}, {135,255,215}, {135,255,255}, {175,  0,  0}, {175,  0, 95}, {175,  0,135}, {175,  0,175},
     28     {175,  0,215}, {175,  0,255}, {175, 95,  0}, {175, 95, 95}, {175, 95,135}, {175, 95,175}, {175, 95,215}, {175, 95,255},
     29     {175,135,  0}, {175,135, 95}, {175,135,135}, {175,135,175}, {175,135,215}, {175,135,255}, {175,175,  0}, {175,175, 95},
     30     {175,175,135}, {175,175,175}, {175,175,215}, {175,175,255}, {175,215,  0}, {175,215, 95}, {175,215,135}, {175,215,175},
     31     {175,215,215}, {175,215,255}, {175,255,  0}, {175,255, 95}, {175,255,135}, {175,255,175}, {175,255,215}, {175,255,255},
     32     {215,  0,  0}, {215,  0, 95}, {215,  0,135}, {215,  0,175}, {215,  0,215}, {215,  0,255}, {215, 95,  0}, {215, 95, 95},
     33     {215, 95,135}, {215, 95,175}, {215, 95,215}, {215, 95,255}, {215,135,  0}, {215,135, 95}, {215,135,135}, {215,135,175},
     34     {215,135,215}, {215,135,255}, {215,175,  0}, {215,175, 95}, {215,175,135}, {215,175,175}, {215,175,215}, {215,175,255},
     35     {215,215,  0}, {215,215, 95}, {215,215,135}, {215,215,175}, {215,215,215}, {215,215,255}, {215,255,  0}, {215,255, 95},
     36     {215,255,135}, {215,255,175}, {215,255,215}, {215,255,255}, {255,  0,  0}, {255,  0, 95}, {255,  0,135}, {255,  0,175},
     37     {255,  0,215}, {255,  0,255}, {255, 95,  0}, {255, 95, 95}, {255, 95,135}, {255, 95,175}, {255, 95,215}, {255, 95,255},
     38     {255,135,  0}, {255,135, 95}, {255,135,135}, {255,135,175}, {255,135,215}, {255,135,255}, {255,175,  0}, {255,175, 95},
     39     {255,175,135}, {255,175,175}, {255,175,215}, {255,175,255}, {255,215,  0}, {255,215, 95}, {255,215,135}, {255,215,175},
     40     {255,215,215}, {255,215,255}, {255,255,  0}, {255,255, 95}, {255,255,135}, {255,255,175}, {255,255,215}, {255,255,255},
     41     {  8,  8,  8}, { 18, 18, 18}, { 28, 28, 28}, { 38, 38, 38}, { 48, 48, 48}, { 58, 58, 58}, { 68, 68, 68}, { 78, 78, 78},
     42     { 88, 88, 88}, { 96, 96, 96}, {102,102,102}, {118,118,118}, {128,128,128}, {138,138,138}, {148,148,148}, {158,158,158}
     43 };
     44 
     45 /*
     46  * takes a 24 bits colors as an argument, and return the nearest color from our
     47  * 256 X colors palette using the color quantization method.
     48  * check https://en.wikipedia.org/wiki/Color_quantization for more infos
     49  */
     50 int
     51 quantization(int rgb[3])
     52 {
     53 	int i, tmp, index;
     54 	int distance = 442 * 442; /* it's always 442 somewhere */
     55 
     56 	for (i = 0, tmp = 0; i < 256; i++) {
     57 		tmp = (rgb[0] - map[i][0]) * (rgb[0] - map[i][0]) +
     58 		      (rgb[1] - map[i][1]) * (rgb[1] - map[i][1]) +
     59 		      (rgb[2] - map[i][2]) * (rgb[2] - map[i][2]);
     60 		if (tmp < distance) {
     61 			distance = tmp;
     62 			index = i;
     63 		}
     64 	}
     65 	return index;
     66 }
     67 
     68 /*
     69  * converts an hexadecimal representation of a color into a 3 dimensionnal
     70  * array (RGB decomposition)
     71  */
     72 void
     73 hex2rgb(char *hex, int *rgb)
     74 {
     75 	int i;
     76 	char tmp[2];
     77 	for (i = 0; i < 3; i++) {
     78 		strncpy(tmp, hex + 1 + 2 * i, 2);
     79 		rgb[i] = strtol(tmp, NULL, 16);
     80 	}
     81 }
     82 
     83 int
     84 main(int argc, char *argv[])
     85 {
     86 	char hex[8];
     87 	int rgb[3], color = 0, truemod = 0;
     88 
     89 	/* either use the "true-colors" ANSI escape (works only with Xterm) */
     90 	if (argc > 1 && strncmp(argv[1], "-t", 2) == 0)
     91 		truemod = 1;
     92 
     93 	while (fgets(hex, 8, stdin)) {
     94 		if (hex[0] == '#') {
     95 			hex2rgb(hex, rgb);
     96 			color = quantization(rgb);
     97 
     98 			if (truemod) {
     99 				printf("[48;2;%d;%d;%dm%8s ", rgb[0],rgb[1],rgb[2], "");
    100 				printf("[38;2;%d;%d;%dm%s ",  rgb[0],rgb[1],rgb[2], hex);
    101 			} else {
    102 				printf("[48;5;%dm%8s ", color, "");
    103 				printf("[38;5;%dm%s",   color, hex);
    104 			}
    105 			printf("\n");
    106 		}
    107 	}
    108 
    109 	printf("");
    110 	return 0;
    111 }