bitmap.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. #include <stdlib.h>
  2. #include <windows.h>
  3. #include "general.h"
  4. #include "debug.h"
  5. static unsigned MxfsCountWordBits(uint32_t v)
  6. {
  7. v = v - ((v >> 1) & 0x55555555); // reuse input as temporary
  8. v = (v & 0x33333333) + ((v >> 2) & 0x33333333); // temp
  9. return (((v + (v >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24; // count
  10. }
  11. unsigned MxfsCountBitsSet(MX_BITMAP *Bm)
  12. {
  13. unsigned i, Result = 0;
  14. for(i = 0; i < Bm->Size; ++i)
  15. Result += MxfsCountWordBits(Bm->Buffer[i]);
  16. return Result;
  17. }
  18. void MxfsInitBitmap(MX_BITMAP *Bm, uint32_t *Buffer, unsigned BitsCount)
  19. {
  20. ASSERT(MxfsCountWordBits(0) == 0);
  21. ASSERT(MxfsCountWordBits(0x11111111) == 8);
  22. ASSERT(MxfsCountWordBits(0xFFFFFFFF) == 32);
  23. Bm->Buffer = Buffer;
  24. Bm->Size = BitsCount / 32;
  25. Bm->Hint = 0;
  26. }
  27. void MxfsDestroyBitmap(MX_BITMAP *Bm)
  28. {
  29. MxfsFree(Bm->Buffer);
  30. Bm->Buffer = NULL;
  31. }
  32. int MxfsFindClearBit(MX_BITMAP *Bm)
  33. {
  34. unsigned i, j;
  35. for(i = 0; i < Bm->Size; ++i)
  36. {
  37. if(Bm->Buffer[i] != 0xFFFFFFFF)
  38. break;
  39. }
  40. if(i == Bm->Size)
  41. {
  42. ERR("Bitmap is full!\n");
  43. return -ERROR_DISK_FULL;
  44. }
  45. for(j = 0; j < 32; ++j)
  46. {
  47. unsigned Bit = Bm->Buffer[i] & (1 << j);
  48. if(!Bit) break;
  49. }
  50. ASSERT(j < 32);
  51. return i * 32 + j;
  52. }
  53. int MxfsSetBit(MX_BITMAP *Bm, unsigned Bit)
  54. {
  55. unsigned i = Bit / 32;
  56. Bit = Bit & 31;
  57. if(i >= Bm->Size)
  58. return -ERROR_INVALID_PARAMETER;
  59. Bm->Buffer[i] |= (1 << Bit);
  60. return 0;
  61. }
  62. int MxfsClearBit(MX_BITMAP *Bm, unsigned Bit)
  63. {
  64. unsigned i = Bit / 32;
  65. Bit = Bit & 31;
  66. if(i >= Bm->Size)
  67. return -ERROR_INVALID_PARAMETER;
  68. Bm->Buffer[i] &= ~(1 << Bit);
  69. return 0;
  70. }
  71. int MxfsGetBit(MX_BITMAP *Bm, unsigned Bit)
  72. {
  73. unsigned i = Bit / 32;
  74. Bit = Bit & 31;
  75. if(i >= Bm->Size)
  76. return -ERROR_INVALID_PARAMETER;
  77. if(Bm->Buffer[i] & (1 << Bit))
  78. return 1;
  79. else
  80. return 0;
  81. }