rd_palette.c 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. // Copyright (c) 1993-2011 PrBoom developers (see AUTHORS)
  2. // Licence: GPLv2 or later (see COPYING)
  3. // Chained hash lookup to convert rgb triples to palette indices
  4. #include "config.h"
  5. #include <stdlib.h>
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include "rd_util.h"
  9. #include "rd_palette.h"
  10. static unsigned char *palette_data;
  11. #define PAL_SIZE 256
  12. static struct {
  13. unsigned char rgb[3];
  14. int first, next;
  15. } hash[PAL_SIZE];
  16. #define HASH(c) ((int)((c)[0])+(int)((c)[1])+(int)((c)[2]))
  17. //
  18. // make_hash
  19. //
  20. // killough-style chained hash
  21. //
  22. static void make_hash(void)
  23. {
  24. int i;
  25. unsigned char *rgb;
  26. for (i = PAL_SIZE, rgb = &palette_data[3*i]; rgb -= 3, --i >= 0; )
  27. {
  28. memmove(hash[i].rgb, rgb, 3);
  29. hash[i].next = hash[i].first = PAL_SIZE;
  30. }
  31. for (i = PAL_SIZE, rgb = &palette_data[3*i]; rgb -= 3, --i >= 0; )
  32. {
  33. int h = HASH(rgb) % PAL_SIZE;
  34. hash[i].next = hash[h].first;
  35. hash[h].first = i;
  36. }
  37. }
  38. //
  39. // loadpal
  40. //
  41. static void loadpal(const char *filename)
  42. {
  43. void *data = NULL;
  44. size_t size = read_or_die(&data, filename);
  45. if (size != 3*PAL_SIZE)
  46. die("Bad palette: %s\n", filename);
  47. palette_data = data;
  48. }
  49. //
  50. // palette_init
  51. //
  52. void palette_init(const char *filename)
  53. {
  54. loadpal(filename);
  55. make_hash();
  56. }
  57. //
  58. // palette_getindex
  59. //
  60. int palette_getindex(const unsigned char *rgb)
  61. {
  62. int i;
  63. if (!palette_data)
  64. die("No palette loaded - please specify one with -palette\n");
  65. i = hash[HASH(rgb) % PAL_SIZE].first;
  66. while (i < PAL_SIZE && memcmp(hash[i].rgb, rgb, 3) != 0)
  67. i = hash[i].next;
  68. return i < PAL_SIZE ? i : -1;
  69. }