00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "w_defines.h"
00031
00032
00033
00034 #define BITMAP_C
00035
00036 #ifdef __GNUC__
00037 #pragma implementation "bitmap.h"
00038 #endif
00039
00040 #include <cstdlib>
00041 #include <w_stream.h>
00042 #include "basics.h"
00043 #include "bitmap.h"
00044 #include <w_debug.h>
00045
00046 inline int div8(int x) { return x >> 3; }
00047 inline int mod8(int x) { return x & 7; }
00048 inline int div32(int x) { return x >> 5; }
00049 inline int mod32(int x) { return x & 31; }
00050
00051 const int OVERFLOW_MASK = 0x100;
00052
00053
00054 void bm_zero(u_char* bm, int size)
00055 {
00056 int n = div8(size - 1) + 1;
00057 for (int i = 0; i < n; i++, bm++)
00058 *bm = 0;
00059 }
00060
00061 void bm_fill(u_char* bm, int size)
00062 {
00063 int n = div8(size - 1) + 1;
00064 for (int i = 0; i < n; i++, bm++)
00065 *bm = ~0;
00066 }
00067
00068 bool bm_is_set(const u_char* bm, int offset)
00069 {
00070 return (bm[div8(offset)] & (1 << mod8(offset))) != 0;
00071 }
00072
00073 void bm_set(u_char* bm, int offset)
00074 {
00075 bm[div8(offset)] |= (1 << mod8(offset));
00076 }
00077
00078 void bm_clr(u_char* bm, int offset)
00079 {
00080 bm[div8(offset)] &= ~(1 << mod8(offset));
00081 }
00082
00083 int bm_first_set(const u_char* bm, int size, int start)
00084 {
00085 #if W_DEBUG_LEVEL > 2
00086 const u_char *bm0 = bm;
00087 #endif
00088 register int mask;
00089
00090 w_assert3(start >= 0 && start <= size);
00091
00092 bm += div8(start);
00093 mask = 1 << mod8(start);
00094
00095 for (size -= start; size; start++, size--) {
00096 if (*bm & mask) {
00097 w_assert3(bm_is_set(bm0, start));
00098 return start;
00099 }
00100 if ((mask <<= 1) == OVERFLOW_MASK) {
00101 mask = 1;
00102 bm++;
00103 }
00104 }
00105
00106 return -1;
00107 }
00108
00109 int bm_first_clr(const u_char* bm, int size, int start)
00110 {
00111 w_assert3(start >= 0 && start <= size);
00112 register int mask;
00113 #if W_DEBUG_LEVEL > 2
00114 const u_char *bm0 = bm;
00115 #endif
00116
00117 bm += div8(start);
00118 mask = 1 << mod8(start);
00119
00120 for (size -= start; size; start++, size--) {
00121 if ((*bm & mask) == 0) {
00122 w_assert3(bm_is_clr(bm0, start));
00123 return start;
00124 }
00125 if ((mask <<= 1) == OVERFLOW_MASK) {
00126 mask = 1;
00127 bm++;
00128 }
00129 }
00130
00131 return -1;
00132 }
00133
00134
00135 int bm_last_set(const u_char* bm, int size, int start)
00136 {
00137 register unsigned mask;
00138 #if W_DEBUG_LEVEL > 2
00139 const u_char *bm0 = bm;
00140 #endif
00141
00142 w_assert3(start >= 0 && start < size);
00143
00144 bm += div8(start);
00145 mask = 1 << mod8(start);
00146
00147 for (size = start+1; size; start--, size--) {
00148 if (*bm & mask) {
00149 w_assert3(bm_is_set(bm0, start));
00150 return start;
00151 }
00152 if ((mask >>= 1) == 0) {
00153 mask = 0x80;
00154 bm--;
00155 }
00156 }
00157
00158 return -1;
00159 }
00160
00161
00162 int bm_last_clr(const u_char* bm, int size, int start)
00163 {
00164 register unsigned mask;
00165 #if W_DEBUG_LEVEL > 2
00166 const u_char *bm0 = bm;
00167 #endif
00168
00169 w_assert3(start >= 0 && start < size);
00170
00171 bm += div8(start);
00172 mask = 1 << mod8(start);
00173
00174 for (size = start+1; size; start--, size--) {
00175 if ((*bm & mask) == 0) {
00176 w_assert3(bm_is_clr(bm0, start));
00177 return start;
00178 }
00179 if ((mask >>= 1) == 0) {
00180 mask = 0x80;
00181 bm--;
00182 }
00183 }
00184
00185 return -1;
00186 }
00187
00188
00189 int bm_num_set(const u_char* bm, int size)
00190 {
00191 int count;
00192 int mask;
00193 for (count = 0, mask = 1; size; size--) {
00194 if (*bm & mask)
00195 count++;
00196 if ((mask <<= 1) == OVERFLOW_MASK) {
00197 mask = 1;
00198 bm++;
00199 }
00200 }
00201 return count;
00202 }
00203
00204 void bm_print(u_char* bm, int size)
00205 {
00206 for (int i = 0; i < size; i++) {
00207 cout << (bm_is_set(bm, i) != 0);
00208 }
00209 }
00210