Experimenting with our bitmap to bitarray convertion.
1 /***************************************************************************
2 * Arrays of Arbitrary Bit Length
5 * Purpose : Provides object with methods for creation and manipulation of
6 * arbitrary length arrays of bits.
8 * Bit arrays are implemented as vectors of unsigned chars. Bit
9 * 0 is the MSB of char 0, and the last bit is the least
10 * significant (non-spare) bit of the last unsigned char.
12 * Example: array of 20 bits (0 through 19) with 8 bit unsigned
13 * chars requires 3 unsigned chars (0 through 2) to
17 * +--------+--------+--------+
19 * +--------+--------+--------+
20 * bit 01234567 8911111111111XXXX
23 * Author : Michael Dipperstein
24 * Date : July 23, 2004
26 ****************************************************************************
29 * $Id: bitarray.cpp,v 1.7 2010/02/04 03:31:43 michael Exp $
30 * $Log: bitarray.cpp,v $
31 * Revision 1.7 2010/02/04 03:31:43 michael
32 * Replaced vector<unsigned char> with an array of unsigned char.
34 * Made updates for GCC 4.4.
36 * Revision 1.5 2007/08/06 05:23:29 michael
37 * Updated for LGPL Version 3.
39 * All methods that don't modify object have been made
40 * const to increase functionality of const bit_array_c.
42 * All assignment operators return a reference to the object being assigned a value so that operator chaining will work.
44 * Added >> and << operators.
46 * Revision 1.3 2006/04/30 23:34:07 michael
47 * Improved performance by incorporating Benjamin Schindler's
48 * <bschindler@student.ethz.ch> changes to pass arguments as a reference.
50 * Revision 1.2 2004/08/05 22:16:49 michael
51 * Add overloads for bitwise operators returning values.
52 * Add a more natural looking way to set bit values.
54 * Revision 1.1.1.1 2004/08/04 13:28:20 michael
57 ****************************************************************************
59 * Bitarray: An ANSI C++ class for manipulating arbitrary length bit arrays
60 * Copyright (C) 2004, 2006-2007, 2010 by
61 * Michael Dipperstein (mdipper@alumni.engr.ucsb.edu)
63 * This file is part of the bit array library.
65 * The bit array library is free software; you can redistribute it and/or
66 * modify it under the terms of the GNU Lesser General Public License as
67 * published by the Free Software Foundation; either version 3 of the
68 * License, or (at your option) any later version.
70 * The bit array library is distributed in the hope that it will be useful,
71 * but WITHOUT ANY WARRANTY; without even the implied warranty of
72 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
73 * General Public License for more details.
75 * You should have received a copy of the GNU Lesser General Public License
76 * along with this program. If not, see <http://www.gnu.org/licenses/>.
78 ***************************************************************************/
80 /***************************************************************************
82 ***************************************************************************/
89 /***************************************************************************
91 ***************************************************************************/
93 /* make CHAR_BIT 8 if it's not defined in limits.h */
95 #warning CHAR_BIT not defined. Assuming 8 bits.
99 /* position of bit within character */
100 #define BIT_CHAR(bit) ((bit) / CHAR_BIT)
102 /* array index for character containing bit */
103 //SL: We had to change that macro since bits in our frame buffer are the other way around
104 //TODO: Find a solution to tackle that problem
105 //#define BIT_IN_CHAR(bit) (1 << (CHAR_BIT - 1 - ((bit) % CHAR_BIT)))
106 #define BIT_IN_CHAR(bit) (1 << (((bit) % CHAR_BIT)))
108 /* number of characters required to contain number of bits */
109 #define BITS_TO_CHARS(bits) ((((bits) - 1) / CHAR_BIT) + 1)
111 /* most significant bit in a character */
112 #define MS_BIT (1 << (CHAR_BIT - 1))
114 /***************************************************************************
116 ***************************************************************************/
118 /***************************************************************************
119 * Method : bit_array_c - constructor
120 * Description: This is the bit_array_c constructor. It reserves memory
121 * for the vector storing the array.
122 * Parameters : numBits - number of bits in the array
123 * Effects : Allocates vectory for array bits
125 ***************************************************************************/
126 BitArray::BitArray(const int numBits):
129 m_SizeInBytes = BITS_TO_CHARS(numBits);
132 /* allocate space for bit array */
133 m_Array = new unsigned char[m_SizeInBytes];
135 /* set all bits to 0 */
136 fill_n(m_Array, m_SizeInBytes, 0);
139 /***************************************************************************
140 * Method : bit_array_c - constructor
141 * Description: This is the bit_array_c constructor. It copies the
142 * for contents of a vector of unsigned char into the
144 * Parameters : vect - vector to be copied
145 * numBits - number of bits in the array
146 * Effects : Allocates vectory for array bits
148 ***************************************************************************/
149 BitArray::BitArray(unsigned char *array, const int numBits):
155 /***************************************************************************
156 * Method : ~bit_array_c - destructor
157 * Description: This is the bit_array_c destructor. At this point it's
158 * just a place holder.
162 ***************************************************************************/
163 BitArray::~BitArray(void)
168 /***************************************************************************
170 * Description: This method dumps the conents of a bit array to stdout.
171 * The format of the dump is a series of bytes represented in
173 * Parameters : outStream - stream to write to
174 * Effects : Array contents are dumped to stdout
176 ***************************************************************************/
177 void BitArray::Dump(std::ostream &outStream)
181 size = BITS_TO_CHARS(m_NumBits);
185 outStream << uppercase << hex << (int)(m_Array[0]); /* first byte */
187 for (int i = 1; i < size; i++)
189 /* remaining bytes with a leading space */
193 outStream << (int)(m_Array[i]);
199 /***************************************************************************
201 * Description: This method sets every bit in the bit array to 1. This
202 * method uses UCHAR_MAX to determine what it means to set
203 * all bits in an unsigned char, so it is crucial that the
204 * machine implementation of unsigned char utilizes all of
205 * the bits in the memory allocated for an unsigned char.
207 * Effects : Each of the bits used in the bit array are set to 1.
208 * Unused (spare) bits are set to 0.
210 ***************************************************************************/
211 void BitArray::SetAll(void)
216 size = BITS_TO_CHARS(m_NumBits);
218 /* set bits in all bytes to 1 */
219 fill_n(m_Array, size, UCHAR_MAX);
221 /* zero any spare bits so increment and decrement are consistent */
222 bits = m_NumBits % CHAR_BIT;
225 mask = UCHAR_MAX << (CHAR_BIT - bits);
226 m_Array[BIT_CHAR(m_NumBits - 1)] = mask;
230 /***************************************************************************
232 * Description: This method sets every bit in the bit array to 0.
234 * Effects : Each of the bits in the bit array are set to 0.
236 ***************************************************************************/
237 void BitArray::ClearAll(void)
241 size = BITS_TO_CHARS(m_NumBits);
243 /* set bits in all bytes to 0 */
244 fill_n(m_Array, size, 0);
247 /***************************************************************************
249 * Description: This method sets a bit in the bit array to 1.
250 * Parameters : bit - the number of the bit to set
251 * Effects : The specified bit will be set to 1.
253 ***************************************************************************/
254 void BitArray::SetBit(const unsigned int bit)
256 if (m_NumBits <= bit)
258 return; /* bit out of range */
261 m_Array[BIT_CHAR(bit)] |= BIT_IN_CHAR(bit);
266 void BitArray::SetBitValue(const unsigned int bit, bool aValue)
278 /***************************************************************************
280 * Description: This method sets a bit in the bit array to 0.
281 * Parameters : bit - the number of the bit to clear
282 * Effects : The specified bit will be set to 0.
284 ***************************************************************************/
285 void BitArray::ClearBit(const unsigned int bit)
289 if (m_NumBits <= bit)
291 return; /* bit out of range */
294 /* create a mask to zero out desired bit */
295 mask = BIT_IN_CHAR(bit);
298 m_Array[BIT_CHAR(bit)] &= mask;
301 /***************************************************************************
302 * Method : operator()
303 * Description: Overload of the () operator. This method approximates
304 * array indices used for assignment. It returns a
305 * bit_array_index_c which includes an = method used to
307 * Parameters : bit - index of array bit
309 * Returned : bit_array_index_c (pointer to bit)
310 ***************************************************************************/
311 BitArrayIndex BitArray::operator()(const unsigned int bit)
313 BitArrayIndex result(this, bit);
318 /***************************************************************************
319 * Method : operator[]
320 * Description: Overload of the [] operator. This method returns the
321 * value of a bit in the bit array.
322 * Parameters : bit - index of array bit
324 * Returned : The value of the specified bit.
325 ***************************************************************************/
326 bool BitArray::operator[](const unsigned int bit) const
328 return((m_Array[BIT_CHAR(bit)] & BIT_IN_CHAR(bit)) != 0);
331 /***************************************************************************
332 * Method : operator==
333 * Description: overload of the == operator
334 * Parameters : other - bit array to compare
336 * Returned : True if this == other. Otherwise false.
337 ***************************************************************************/
338 bool BitArray::operator==(const BitArray &other) const
340 if (m_NumBits != other.m_NumBits)
346 return (this->m_Array == other.m_Array);
349 /***************************************************************************
350 * Method : operator!=
351 * Description: overload of the != operator
352 * Parameters : other - bit array to compare
354 * Returned : True if this != other. Otherwise false.
355 ***************************************************************************/
356 bool BitArray::operator!=(const BitArray &other) const
358 if (m_NumBits != other.m_NumBits)
364 return (this->m_Array != other.m_Array);
367 /***************************************************************************
369 * Description: overload of the < operator
370 * Parameters : other - bit array to compare
372 * Returned : True if this < other. Otherwise false.
373 ***************************************************************************/
374 bool BitArray::operator<(const BitArray &other) const
376 if (m_NumBits != other.m_NumBits)
382 return (this->m_Array < other.m_Array);
385 /***************************************************************************
386 * Method : operator<=
387 * Description: overload of the <= operator
388 * Parameters : other - bit array to compare
390 * Returned : True if this <= other. Otherwise false.
391 ***************************************************************************/
392 bool BitArray::operator<=(const BitArray &other) const
394 if (m_NumBits != other.m_NumBits)
400 return (this->m_Array <= other.m_Array);
403 /***************************************************************************
405 * Description: overload of the > operator
406 * Parameters : other - bit array to compare
408 * Returned : True if this > other. Otherwise false.
409 ***************************************************************************/
410 bool BitArray::operator>(const BitArray &other) const
412 if (m_NumBits != other.m_NumBits)
418 return (this->m_Array > other.m_Array);
421 /***************************************************************************
422 * Method : operator>=
423 * Description: overload of the >= operator
424 * Parameters : other - bit array to compare
426 * Returned : True if this >= other. Otherwise false.
427 ***************************************************************************/
428 bool BitArray::operator>=(const BitArray &other) const
430 if (m_NumBits != other.m_NumBits)
436 return (this->m_Array >= other.m_Array);
439 /***************************************************************************
441 * Description: overload of the ~ operator. Negates all non-spare bits in
445 * Returned : value of this after bitwise not
446 ***************************************************************************/
447 BitArray BitArray::operator~(void) const
449 BitArray result(this->m_NumBits);
456 /***************************************************************************
458 * Description: overload of the & operator. Performs a bitwise and
459 * between the source array and this bit array.
460 * Parameters : other - bit array on righthand side of &
462 * Returned : value of bitwise and of this and other.
463 ***************************************************************************/
464 BitArray BitArray::operator&(const BitArray &other) const
466 BitArray result(this->m_NumBits);
474 /***************************************************************************
476 * Description: overload of the ^ operator. Performs a bitwise xor
477 * between the source array and this bit array.
478 * Parameters : other - bit array on righthand side of ^
480 * Returned : value of bitwise xor of this and other.
481 ***************************************************************************/
482 BitArray BitArray::operator^(const BitArray &other) const
484 BitArray result(this->m_NumBits);
491 /***************************************************************************
493 * Description: overload of the | operator. Performs a bitwise or
494 * between the source array and this bit array.
495 * Parameters : other - bit array on righthand side of |
497 * Returned : value of bitwise or of this and other.
498 ***************************************************************************/
499 BitArray BitArray::operator|(const BitArray &other) const
501 BitArray result(this->m_NumBits);
508 /***************************************************************************
509 * Method : operator<<
510 * Description: overload of the << operator. Performs a bitwise left
511 * shift of this bit array.
512 * Parameters : count - the number of bits to shift left
514 * Returned : result of bitwise left shift
515 ***************************************************************************/
516 BitArray BitArray::operator<<(const unsigned int count) const
518 BitArray result(this->m_NumBits);
525 /***************************************************************************
526 * Method : operator>>
527 * Description: overload of the >> operator. Performs a bitwise right
528 * shift of this bit array.
529 * Parameters : count - the number of bits to shift right
531 * Returned : result of bitwise right shift
532 ***************************************************************************/
533 BitArray BitArray::operator>>(const unsigned int count) const
535 BitArray result(this->m_NumBits);
542 /***************************************************************************
543 * Method : operator++ (prefix)
544 * Description: overload of the ++ operator. Increments the contents of
545 * a bit array. Overflows cause rollover.
547 * Effects : Bit array contents are incremented
548 * Returned : Reference to this array after increment
549 ***************************************************************************/
550 BitArray& BitArray::operator++(void)
553 unsigned char maxValue; /* maximum value for current char */
554 unsigned char one; /* least significant bit in current char */
558 return *this; /* nothing to increment */
561 /* handle arrays that don't use every bit in the last character */
562 i = (m_NumBits % CHAR_BIT);
565 maxValue = UCHAR_MAX << (CHAR_BIT - i);
566 one = 1 << (CHAR_BIT - i);
570 maxValue = UCHAR_MAX;
574 for (i = BIT_CHAR(m_NumBits - 1); i >= 0; i--)
576 if (m_Array[i] != maxValue)
578 m_Array[i] = m_Array[i] + one;
583 /* need to carry to next byte */
586 /* remaining characters must use all bits */
587 maxValue = UCHAR_MAX;
595 /***************************************************************************
596 * Method : operator++ (postfix)
597 * Description: overload of the ++ operator. Increments the contents of
598 * a bit array. Overflows cause rollover.
599 * Parameters : dumy - needed for postfix increment
600 * Effects : Bit array contents are incremented
601 * Returned : Reference to this array after increment
602 ***************************************************************************/
603 BitArray& BitArray::operator++(int dummy)
609 /***************************************************************************
610 * Method : operator-- (prefix)
611 * Description: overload of the -- operator. Decrements the contents of
612 * a bit array. Underflows cause rollover.
614 * Effects : Bit array contents are decremented
616 ***************************************************************************/
617 BitArray& BitArray::operator--(void)
620 unsigned char maxValue; /* maximum value for current char */
621 unsigned char one; /* least significant bit in current char */
625 return *this; /* nothing to decrement */
628 /* handle arrays that don't use every bit in the last character */
629 i = (m_NumBits % CHAR_BIT);
632 maxValue = UCHAR_MAX << (CHAR_BIT - i);
633 one = 1 << (CHAR_BIT - i);
637 maxValue = UCHAR_MAX;
641 for (i = BIT_CHAR(m_NumBits - 1); i >= 0; i--)
643 if (m_Array[i] >= one)
645 m_Array[i] = m_Array[i] - one;
650 /* need to borrow from the next byte */
651 m_Array[i] = maxValue;
653 /* remaining characters must use all bits */
654 maxValue = UCHAR_MAX;
662 /***************************************************************************
663 * Method : operator-- (postfix)
664 * Description: overload of the -- operator. Decrements the contents of
665 * a bit array. Underflows cause rollover.
666 * Parameters : dumy - needed for postfix decrement
667 * Effects : Bit array contents are decremented
669 ***************************************************************************/
670 BitArray& BitArray::operator--(int dummy)
676 /***************************************************************************
678 * Description: overload of the = operator. Copies source contents into
680 * Parameters : src - Source bit array
681 * Effects : Source bit array contents are copied into this array
682 * Returned : Reference to this array after copy
683 ***************************************************************************/
684 BitArray& BitArray::operator=(const BitArray &src)
688 /* don't do anything for a self assignment */
692 if (m_NumBits != src.m_NumBits)
694 /* don't do assignment with different array sizes */
698 if ((m_NumBits == 0) || (src.m_NumBits == 0))
700 /* don't do assignment with unallocated array */
704 /* copy bits from source */
706 size = BITS_TO_CHARS(m_NumBits);
708 copy(src.m_Array, &src.m_Array[size], this->m_Array);
712 /***************************************************************************
713 * Method : operator&=
714 * Description: overload of the &= operator. Performs a bitwise and
715 * between the source array and this bit array. This bit
716 * array will contain the result.
717 * Parameters : src - Source bit array
718 * Effects : Results of bitwise and are stored in this array
719 * Returned : Reference to this array after and
720 ***************************************************************************/
721 BitArray& BitArray::operator&=(const BitArray &src)
725 size = BITS_TO_CHARS(m_NumBits);
727 if (m_NumBits != src.m_NumBits)
729 /* don't do assignment with different array sizes */
733 /* AND array one unsigned char at a time */
734 for(int i = 0; i < size; i++)
736 m_Array[i] = m_Array[i] & src.m_Array[i];
742 /***************************************************************************
743 * Method : operator^=
744 * Description: overload of the ^= operator. Performs a bitwise xor
745 * between the source array and this bit array. This bit
746 * array will contain the result.
747 * Parameters : src - Source bit array
748 * Effects : Results of bitwise xor are stored in this array
749 * Returned : Reference to this array after xor
750 ***************************************************************************/
751 BitArray& BitArray::operator^=(const BitArray &src)
755 size = BITS_TO_CHARS(m_NumBits);
757 if (m_NumBits != src.m_NumBits)
759 /* don't do assignment with different array sizes */
763 /* XOR array one unsigned char at a time */
764 for(int i = 0; i < size; i++)
766 m_Array[i] = m_Array[i] ^ src.m_Array[i];
772 /***************************************************************************
773 * Method : operator|=
774 * Description: overload of the |= operator. Performs a bitwise or
775 * between the source array and this bit array. This bit
776 * array will contain the result.
777 * Parameters : src - Source bit array
778 * Effects : Results of bitwise or are stored in this array
779 * Returned : Reference to this array after or
780 ***************************************************************************/
781 BitArray& BitArray::operator|=(const BitArray &src)
785 size = BITS_TO_CHARS(m_NumBits);
787 if (m_NumBits != src.m_NumBits)
789 /* don't do assignment with different array sizes */
793 /* OR array one unsigned char at a time */
794 for(int i = 0; i < size; i++)
796 m_Array[i] = m_Array[i] | src.m_Array[i];
802 /***************************************************************************
804 * Description: Negates all non-spare bits in bit array.
806 * Effects : Contents of bit array are negated. Any spare bits are
808 * Returned : Reference to this array after not
809 ***************************************************************************/
810 BitArray& BitArray::Not(void)
816 size = BITS_TO_CHARS(m_NumBits);
820 /* don't do not with unallocated array */
824 /* NOT array one unsigned char at a time */
825 for(int i = 0; i < size; i++)
827 m_Array[i] = ~m_Array[i];
830 /* zero any spare bits so increment and decrement are consistent */
831 bits = m_NumBits % CHAR_BIT;
834 mask = UCHAR_MAX << (CHAR_BIT - bits);
835 m_Array[BIT_CHAR(m_NumBits - 1)] &= mask;
841 /***************************************************************************
842 * Method : operator<<=
843 * Description: overload of the <<= operator. Performs a left shift on
844 * this bit array. This bit array will contain the result.
845 * Parameters : shifts - number of bit positions to shift
846 * Effects : Results of the shifts are stored in this array
847 * Returned : Reference to this array after shift
848 ***************************************************************************/
849 BitArray& BitArray::operator<<=(const unsigned int shifts)
852 int chars = shifts / CHAR_BIT; /* number of whole byte shifts */
854 if (shifts >= m_NumBits)
856 /* all bits have been shifted off */
861 /* first handle big jumps of bytes */
866 size = BITS_TO_CHARS(m_NumBits);
868 for (i = 0; (i + chars) < size; i++)
870 m_Array[i] = m_Array[i + chars];
873 /* now zero out new bytes on the right */
874 for (i = size; chars > 0; chars--)
876 m_Array[i - chars] = 0;
880 /* now we have at most CHAR_BIT - 1 bit shifts across the whole array */
881 for (i = 0; i < (int)(shifts % CHAR_BIT); i++)
883 for (unsigned int j = 0; j < BIT_CHAR(m_NumBits - 1); j++)
887 /* handle shifts across byte bounds */
888 if (m_Array[j + 1] & MS_BIT)
894 m_Array[BIT_CHAR(m_NumBits - 1)] <<= 1;
900 /***************************************************************************
901 * Method : operator>>=
902 * Description: overload of the >>= operator. Performs a right shift on
903 * this bit array. This bit array will contain the result.
904 * Parameters : shifts - number of bit positions to shift
905 * Effects : Results of the shifts are stored in this array
906 * Returned : Reference to this array after shift
907 ***************************************************************************/
908 BitArray& BitArray::operator>>=(const unsigned int shifts)
912 int chars = shifts / CHAR_BIT; /* number of whole byte shifts */
914 if (shifts >= m_NumBits)
916 /* all bits have been shifted off */
921 /* first handle big jumps of bytes */
924 for (i = BIT_CHAR(m_NumBits - 1); (i - chars) >= 0; i--)
926 m_Array[i] = m_Array[i - chars];
929 /* now zero out new bytes on the right */
930 for (; chars > 0; chars--)
932 m_Array[chars - 1] = 0;
936 /* now we have at most CHAR_BIT - 1 bit shifts across the whole array */
937 for (i = 0; i < (int)(shifts % CHAR_BIT); i++)
939 for (unsigned int j = BIT_CHAR(m_NumBits - 1); j > 0; j--)
943 /* handle shifts across byte bounds */
944 if (m_Array[j - 1] & 0x01)
946 m_Array[j] |= MS_BIT;
953 /***********************************************************************
954 * zero any spare bits that are shifted beyond the end of the bit array
955 * so that increment and decrement are consistent.
956 ***********************************************************************/
957 i = m_NumBits % CHAR_BIT;
960 mask = UCHAR_MAX << (CHAR_BIT - i);
961 m_Array[BIT_CHAR(m_NumBits - 1)] &= mask;
967 /***************************************************************************
968 * Method : bit_array_index_c - constructor
969 * Description: This is the bit_array_index_c constructor. It stores a
970 * pointer to the bit array and the bit index.
971 * Parameters : array - pointer to bit array
972 * index - index of bit in array
973 * Effects : Pointer to bit array and bit index are stored.
975 ***************************************************************************/
976 BitArrayIndex::BitArrayIndex(BitArray *array,
977 const unsigned int index)
983 /***************************************************************************
985 * Description: overload of the = operator. Sets the bit array bit to
987 * Parameters : src - bit value
988 * Effects : Bit pointed to by this object is set to the value of
991 ***************************************************************************/
992 void BitArrayIndex::operator=(const bool src)
994 if (m_BitArray == NULL)
996 return; /* no array */
999 if (m_BitArray->SizeInBits() <= m_Index)
1001 return; /* index is out of bounds */
1006 m_BitArray->SetBit(m_Index);
1010 m_BitArray->ClearBit(m_Index);