color_insrt.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /* This routine is public only because source is in different files.
  2. * It should NEVER be called directly.
  3. * It is used by G_add_color_rule() and G__read_old_colors().
  4. * These routines know when it is approriate to call this routine.
  5. */
  6. #include <grass/gis.h>
  7. #define umalloc(n) (unsigned char *) G_malloc((size_t)n)
  8. #define urealloc(s,n) (unsigned char *) G_realloc(s,(size_t)n)
  9. #define LIMIT(x) if (x < 0) x = 0; else if (x > 255) x = 255;
  10. int G__insert_color_into_lookup(CELL cat,
  11. int red, int grn, int blu,
  12. struct _Color_Info_ *cp)
  13. {
  14. long nalloc;
  15. long i;
  16. long newlen, curlen, gap;
  17. LIMIT(red);
  18. LIMIT(grn);
  19. LIMIT(blu);
  20. /* first color? */
  21. if (!cp->lookup.active) {
  22. cp->lookup.active = 1;
  23. cp->lookup.nalloc = 256;
  24. cp->lookup.red = umalloc(cp->lookup.nalloc);
  25. cp->lookup.grn = umalloc(cp->lookup.nalloc);
  26. cp->lookup.blu = umalloc(cp->lookup.nalloc);
  27. cp->lookup.set = umalloc(cp->lookup.nalloc);
  28. cp->max = cp->min = cat;
  29. }
  30. /* extend the color table? */
  31. else if (cat > cp->max) {
  32. curlen = cp->max - cp->min + 1;
  33. newlen = cat - cp->min + 1;
  34. nalloc = newlen;
  35. if (nalloc != (int)nalloc) /* check for int overflow */
  36. return -1;
  37. if (nalloc > cp->lookup.nalloc) {
  38. while (cp->lookup.nalloc < nalloc)
  39. cp->lookup.nalloc += 256;
  40. nalloc = cp->lookup.nalloc;
  41. cp->lookup.red = urealloc((char *)cp->lookup.red, nalloc);
  42. cp->lookup.grn = urealloc((char *)cp->lookup.grn, nalloc);
  43. cp->lookup.blu = urealloc((char *)cp->lookup.blu, nalloc);
  44. cp->lookup.set = urealloc((char *)cp->lookup.set, nalloc);
  45. }
  46. /* fill in gap with white */
  47. for (i = curlen; i < newlen; i++) {
  48. cp->lookup.red[i] = 255;
  49. cp->lookup.grn[i] = 255;
  50. cp->lookup.blu[i] = 255;
  51. cp->lookup.set[i] = 0;
  52. }
  53. cp->max = cat;
  54. }
  55. else if (cat < cp->min) {
  56. curlen = cp->max - cp->min + 1;
  57. newlen = cp->max - cat + 1;
  58. gap = newlen - curlen;
  59. nalloc = newlen;
  60. if (nalloc != (int)nalloc) /* check for int overflow */
  61. return -1;
  62. if (nalloc > cp->lookup.nalloc) {
  63. while (cp->lookup.nalloc < nalloc)
  64. cp->lookup.nalloc += 256;
  65. nalloc = cp->lookup.nalloc;
  66. cp->lookup.red = urealloc((char *)cp->lookup.red, nalloc);
  67. cp->lookup.grn = urealloc((char *)cp->lookup.grn, nalloc);
  68. cp->lookup.blu = urealloc((char *)cp->lookup.blu, nalloc);
  69. cp->lookup.set = urealloc((char *)cp->lookup.set, nalloc);
  70. }
  71. /* shift the table to make room in front */
  72. for (i = 1; i <= curlen; i++) {
  73. cp->lookup.red[newlen - i] = cp->lookup.red[curlen - i];
  74. cp->lookup.grn[newlen - i] = cp->lookup.grn[curlen - i];
  75. cp->lookup.blu[newlen - i] = cp->lookup.blu[curlen - i];
  76. cp->lookup.set[newlen - i] = cp->lookup.set[curlen - i];
  77. }
  78. /* fill in gap with white */
  79. for (i = 1; i < gap; i++) {
  80. cp->lookup.red[i] = 255;
  81. cp->lookup.grn[i] = 255;
  82. cp->lookup.blu[i] = 255;
  83. cp->lookup.set[i] = 0;
  84. }
  85. cp->min = cat;
  86. }
  87. /* set the color! */
  88. i = cat - cp->min;
  89. cp->lookup.red[i] = red;
  90. cp->lookup.grn[i] = grn;
  91. cp->lookup.blu[i] = blu;
  92. cp->lookup.set[i] = 1;
  93. return 1;
  94. }