color_insrt.c 3.1 KB

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