libretro-prboom/data/rd_palette.c
2015-08-27 07:36:16 +02:00

92 lines
1.5 KiB
C

// 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 <stdlib.h>
#include <stdio.h>
#include <string.h>
#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;
}