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