Mega Code Archive

 
Categories / Delphi / Examples
 

BitCompression

Title: BitCompression Question: Why using whole byte to store bynary data when single bit is enough? With this unit you can compress boolean array into byte array in one move. Answer: For boolean array we make compressed array of bytes where original boolean values are stored in every bit of byte array, so we save up to 7/8 of original memory space required for storing this array. This could be usefull when you use very large boolean arrays (especially in Pascal) which you cannot define. With this unit you can access particular boolean values with procedure GetBitValue and function SetBitValue. It's almost the same like with ordinary boolean arrays. Just in case, I made decopression routines too. unit BitCompressionUnit; //1.0 (* unit by Storm Software Branislav Stojkovic http://branislav.8bit.co.uk stormbringer@mail.com *) interface type TCompressedArray=array of byte; TBooleanArray=array of boolean; var CompArray:TCompressedArray; BoolArray:TBooleanArray; BitLength:Integer; function LocateBit(Index:integer; var Cell, Bit:integer):boolean; procedure SetBitValue(Value:boolean; Index:integer; var CompArray:TCompressedArray); function GetBitValue(Index:integer; var CompArray:TCompressedArray):boolean; procedure BitCompress(BoolArray:TBooleanArray; var CompArray:TCompressedArray); procedure BitDecompress(CompArray:TCompressedArray; var BoolArray:TBooleanArray); implementation function LocateBit(Index:integer; var Cell, Bit:integer): boolean; begin if ((Index div 8)-1 High(CompArray)) or (Index //index is out of bounds, report error Result := False else begin //locate array element to write/read and bit index Cell := Index div 8; Bit := Index mod 8; if Bit = 0 then begin Dec(Cell); Bit := 8; end; Result := True; end; end; procedure SetBitValue(Value:boolean; Index:integer; var CompArray:TCompressedArray); var Cell, Bit : integer; begin //change element in necessary if Value then begin if LocateBit(Index, Cell, Bit) then CompArray[Cell] := CompArray[Cell] or (1 shl (Bit-1)) end else if LocateBit(Index, Cell, Bit) then //if target bit is 1 and needs to be set to 0 if Odd(CompArray[Cell] shr (Bit-1)) then CompArray[Cell] := CompArray[Cell] - (1 shl (Bit-1)); end; function GetBitValue(Index:integer; var CompArray:TCompressedArray): boolean; var Cell, Bit : integer; begin //get value, shift number to get desired bit to last position //if it's odd last bit is 1, otherwise it's 0...simple isn't it if LocateBit(Index, Cell, Bit) then Result := Odd(CompArray[Cell] shr (Bit-1)) else Result := False; end; procedure BitCompress(BoolArray:TBooleanArray; var CompArray:TCompressedArray); var i : integer; begin //reserve enough bytes to store array of bytes Finalize(CompArray); SetLength(CompArray, (High(BoolArray) div 8) + 1); //remember array length for later use, when decompressing BitLength := High(BoolArray); //compress for i := 0 to High(BoolArray) do SetBitValue(BoolArray[i], i+1, CompArray); end; procedure BitDecompress(CompArray:TCompressedArray; var BoolArray:TBooleanArray); var i : integer; begin //reserve enough bytes to store array of booleans Finalize(BoolArray); SetLength(BoolArray, (High(CompArray)+1)*8); //decompress for i := 0 to High(BoolArray) do BoolArray[i]:=GetBitValue(i+1, CompArray); end; end.