00001 /* 00002 00003 Copyright (c) 2003, Cornell University 00004 All rights reserved. 00005 00006 Redistribution and use in source and binary forms, with or without 00007 modification, are permitted provided that the following conditions are met: 00008 00009 - Redistributions of source code must retain the above copyright notice, 00010 this list of conditions and the following disclaimer. 00011 - Redistributions in binary form must reproduce the above copyright 00012 notice, this list of conditions and the following disclaimer in the 00013 documentation and/or other materials provided with the distribution. 00014 - Neither the name of Cornell University nor the names of its 00015 contributors may be used to endorse or promote products derived from 00016 this software without specific prior written permission. 00017 00018 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00019 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00020 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00021 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00022 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00023 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00024 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00025 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00026 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00027 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 00028 THE POSSIBILITY OF SUCH DAMAGE. 00029 00030 */ 00031 00032 00033 ///////////////////////////////////////////////////////////////////// 00034 /// 00035 /// Bitmap.cpp 00036 /// 00037 ///////////////////////////////////////////////////////////////////// 00038 00039 #include "Bitmap.h" 00040 #include <stdlib.h> 00041 #include <limits.h> 00042 #include <math.h> 00043 #include <iostream> 00044 #include <assert.h> 00045 00046 ///////////////////////////////////////////////////////////////////// 00047 /// @addtogroup BitmapProcessing 00048 /** @{ */ 00049 00050 #define BYTE_COUNT (sizeof(unsigned int) / sizeof(unsigned char)) 00051 00052 ///////////////////////////////////////////////////////////////////// 00053 /// Allocate the memory for the bitmap 00054 /// 00055 /// @param numBits number of bits in the Bitmap 00056 ///////////////////////////////////////////////////////////////////// 00057 Bitmap::Bitmap(int numBits) { 00058 // Convert bitsize to number of ints 00059 _size = (numBits / 32) + 1; 00060 _compSize = (int)(_size * 1.25) + 1; 00061 _memory = new unsigned int[ _size ]; 00062 _compMemory = new unsigned int[_compSize ]; 00063 _compUsed = 0; 00064 _count = 0; 00065 00066 int index; 00067 00068 // fill bitmap with zeroes 00069 for (index = 0; index < _size; index++) 00070 _memory[index] = 0; 00071 00072 // fill compressed bitmap with zeroes 00073 for (index = 0; index < _compSize; index++) 00074 _compMemory[index] = 0; 00075 } 00076 00077 ///////////////////////////////////////////////////////////////////// 00078 /// Copy constructor 00079 /// 00080 /// @param b bitmap to copy 00081 ///////////////////////////////////////////////////////////////////// 00082 Bitmap::Bitmap(Bitmap &b): BaseBitmap(b) { 00083 _size = b._size; 00084 _compSize = b._compSize; 00085 _compUsed = b._compUsed; 00086 _memory = new unsigned int[ _size ]; 00087 _compMemory = new unsigned int[ _compSize ]; 00088 _count = b._count; 00089 00090 int index; 00091 for ( index = 0; index < b._size; index++) 00092 _memory[index] = b._memory[index]; 00093 00094 for ( index = 0; index < b._compSize; index++) 00095 _compMemory[index] = b._compMemory[index]; 00096 } 00097 00098 00099 ///////////////////////////////////////////////////////////////////// 00100 /// Deallocate memory for the Bitmap 00101 ///////////////////////////////////////////////////////////////////// 00102 Bitmap::~Bitmap() { 00103 delete [] _compMemory; 00104 } 00105 00106 ///////////////////////////////////////////////////////////////////// 00107 /// Fill in a 1 in a certain position in COMPRESSED data 00108 /// 00109 /// @param j bit position in Bitmap to be changed 00110 ///////////////////////////////////////////////////////////////////// 00111 void Bitmap::FillCompEmptyPosition(int j) { 00112 // Locate correct int in the bitmap 00113 int i = j / 32; 00114 00115 // switch on correct bit 00116 _compMemory[i] = _compMemory[i] | BitTable[(j % 32)]; 00117 } 00118 00119 ///////////////////////////////////////////////////////////////////// 00120 /// Count the number of ones in the Compressed bitmap 00121 /// 00122 /// @return the count of ones in the bitmap 00123 ///////////////////////////////////////////////////////////////////// 00124 int Bitmap::SmallCount(int &CountCounts) { 00125 int final = 0; 00126 unsigned char *p; 00127 CountCounts++; 00128 00129 for (int i = 0; i < _compUsed; i++) { 00130 p = (unsigned char *) & _compMemory[i]; 00131 00132 // count 1s by dividing into chars and using a lookup table 00133 final += CountTable[*p]; 00134 p++; 00135 final += CountTable[*p]; 00136 p++; 00137 final += CountTable[*p]; 00138 p++; 00139 final += CountTable[*p]; 00140 } 00141 00142 // set the count for the bitmap 00143 _count = final; 00144 return final; 00145 } 00146 00147 ///////////////////////////////////////////////////////////////////// 00148 /// Bitwise AND 2 compressed bitmaps and store the result 00149 /// 00150 /// @param B1 first bitmap 00151 /// @param B2 second bitmap 00152 /// @param CountSmallAnds [output] counter of ANDs on compressed data 00153 ///////////////////////////////////////////////////////////////////// 00154 void Bitmap::AndCompOnly( 00155 const Bitmap &B1, 00156 const Bitmap &B2, 00157 int &CountSmallAnds) { 00158 00159 CountSmallAnds++; 00160 unsigned int *b1ptr, *b2ptr; 00161 00162 b1ptr = B1._compMemory; 00163 b2ptr = B2._compMemory; 00164 _compUsed = B1._compUsed; 00165 00166 // AND the small bitmaps 00167 for (int i = 0; i < B1._compUsed; i++) { 00168 // and each INT bitwise 00169 _compMemory[i] = (*b1ptr) & (*b2ptr); 00170 00171 b1ptr++; 00172 b2ptr++; 00173 } 00174 } 00175 00176 ///////////////////////////////////////////////////////////////////// 00177 /// Bitwise AND 2 compressed bitmaps and the negation and store the result 00178 /// 00179 /// @param B1 first bitmap 00180 /// @param B2 second bitmap 00181 /// @param CountSmallAnds [output] counter of ANDs on compressed data 00182 ///////////////////////////////////////////////////////////////////// 00183 void Bitmap::NotAndCompOnly( 00184 const Bitmap &B1, 00185 const Bitmap &B2, 00186 int &CountSmallAnds) { 00187 00188 CountSmallAnds++; 00189 unsigned int *b1ptr, *b2ptr; 00190 00191 b1ptr = B1._compMemory; 00192 b2ptr = B2._compMemory; 00193 _compUsed = B1._compUsed; 00194 00195 // AND the small bitmaps 00196 for (int i = 0; i < B1._compUsed; i++) { 00197 // and each INT bitwise 00198 _compMemory[i] = (*b1ptr) & ~(*b2ptr); 00199 00200 b1ptr++; 00201 b2ptr++; 00202 } 00203 } 00204 00205 ///////////////////////////////////////////////////////////////////// 00206 /// Compress this bitmap relative to the source - has a bit for each 00207 /// trans in source 00208 /// 00209 /// @param source the bitmap you are compressing relative to 00210 ///////////////////////////////////////////////////////////////////// 00211 void Bitmap::BuildRelComp(Bitmap &source) { 00212 int i; 00213 int bc; 00214 00215 // index into current int (how much of current int has been filled) 00216 int d = 0; 00217 00218 // zero your compressed contents 00219 _compUsed = source._compUsed; 00220 for (i = 0; i < _compUsed; i++) 00221 _compMemory[i] = 0; 00222 00223 unsigned int *result = _compMemory; 00224 unsigned int tempResult; 00225 unsigned char *p_s, *p_t; 00226 00227 p_s = (unsigned char *) source._memory; 00228 p_t = (unsigned char *) _memory; 00229 00230 // for each byte of the ORIGINAL bitmaps 00231 for (i = 0; i < (_size * 4); i++) { 00232 // find out how many bits needed to represent this byte 00233 // in compressed form 00234 // (# of 1's in the ORIGINAL data of the SOURCE) 00235 bc = CountTable[(*p_s)]; 00236 00237 // if there is anything when byte compressed 00238 if (bc > 0) { 00239 // check if enough space in current int of COMPRESSED data 00240 // for the compressed byte result 00241 if ((32 - d) >= bc) { 00242 // compress and append compressed result for this byte to 00243 // rest of compressed data 00244 tempResult = CompTable[(*p_s)][(*p_t)] >> d; 00245 *result = (*result) | tempResult; 00246 d += bc; 00247 } else { 00248 // go to the next int in compressed data, compress and 00249 // append compressed result there 00250 result++; 00251 tempResult = CompTable[(*p_s)][(*p_t)]; 00252 *result = (*result) | tempResult; 00253 d = bc; 00254 } 00255 00256 } 00257 00258 // go to the byte in the ORIGINAL bitmaps 00259 p_s++; 00260 p_t++; 00261 } 00262 } 00263 00264 ///////////////////////////////////////////////////////////////////// 00265 /// Fill the compressed bitmap with ones 00266 ///////////////////////////////////////////////////////////////////// 00267 void Bitmap::BuildSource() { 00268 unsigned int *whatever = _compMemory; 00269 00270 // find out how many INTs will be used in the compressed data 00271 int scaledSup = (int)ceil( ((float)_count * 1.25) / (float)32 ); 00272 for (int i = 0; i < scaledSup; i++) { 00273 // fill the int with all ones 00274 (*whatever) = UINT_MAX; 00275 whatever++; 00276 } 00277 00278 _compUsed = scaledSup; 00279 } 00280 00281 /** @} */