// Copyright (c) 1993-2011 PrBoom developers (see AUTHORS) // Licence: GPLv2 or later (see COPYING) // Chained hash lookup to convert rgb triples to palette indices #include #include #include #include "rd_util.h" #include "rd_palette.h" static unsigned char *palette_data; #define PAL_SIZE 256 static struct { unsigned char rgb[3]; int first, next; } hash[PAL_SIZE]; #define HASH(c) ((int)((c)[0])+(int)((c)[1])+(int)((c)[2])) // // make_hash // // killough-style chained hash // static void make_hash(void) { int i; unsigned char *rgb; for (i = PAL_SIZE, rgb = &palette_data[3*i]; rgb -= 3, --i >= 0; ) { memmove(hash[i].rgb, rgb, 3); hash[i].next = hash[i].first = PAL_SIZE; } for (i = PAL_SIZE, rgb = &palette_data[3*i]; rgb -= 3, --i >= 0; ) { int h = HASH(rgb) % PAL_SIZE; hash[i].next = hash[h].first; hash[h].first = i; } } // // loadpal // static void loadpal(const char *filename) { void *data = NULL; size_t size = read_or_die(&data, filename); if (size != 3*PAL_SIZE) die("Bad palette: %s\n", filename); palette_data = data; } // // palette_init // void palette_init(const char *filename) { loadpal(filename); make_hash(); } // // palette_getindex // int palette_getindex(const unsigned char *rgb) { int i; if (!palette_data) die("No palette loaded - please specify one with -palette\n"); i = hash[HASH(rgb) % PAL_SIZE].first; while (i < PAL_SIZE && memcmp(hash[i].rgb, rgb, 3) != 0) i = hash[i].next; return i < PAL_SIZE ? i : -1; }