type
TByteArray = array of byte;
function BooleansToByteArray(const IB: array of boolean): TByteArray;
{ entrée = [ bit n ..., bit 3, bit 2, bit 1] (de droite a gauche)
sortie = [ bit 1 a 8, bit 9 a n, ... ] (de gauche a droite)
}
var BIndex, BIndexStop,
RIndex, RIndexStop,
Shift, IBLen : integer;
begin
{ nombre d'elements dans IB }
IBLen := Length(IB);
{ ajustement de la taille du tableau en sortie }
if (IBLen mod 8) <> 0 then
{ si il reste quelque chose on ajoute 1 element au resultat}
SetLength(result, (IBLen div 8) + 1)
else
{ sinon c'est parfait }
SetLength(result, IBLen div 8);
{ index de fin du tableau en sortie }
RIndexStop := High(Result);
{ index de depart du tableau en entrée }
BIndex := IBLen-1;
{ on mets tout a zero par defaut
on peu utiliser fillchar mais bon ...
ça evite un call de FillChar( Result, RIndexStop+1, 0) }
for RIndex := 0 to RIndexStop do
result[RIndex] := 0;
{ index de depart du tableau en sortie }
RIndex := 0;
{ tant que qu'on as de la place en sortie }
while RIndex <= RIndexStop do
begin
{ index de limite du tableau en entrée }
BIndexStop := BIndex - 7;
{ init de la valeur de decalage pour shl }
Shift := 0;
{ tant qu'on as des elements en entrée }
while BIndex >= BIndexStop do
begin
{ ça sert a rien de decaler des zeros (0 shl n = 0) }
if IB[BIndex] then
{ oui on pourrait calculer les puissances de deux,
utiliser pow() et d'autre truc bien lourd aussi (ceil, round, trunc, etc),
mais un or et un shl suffisent }
result[RIndex] := result[RIndex] or ($1 shl Shift);
{ plus rapide hein ?
1 shl 0 = pow(2,0) = 1 = 00000001
1 shl 1 = pow(2,1) = 2 = 00000010
1 shl 2 = pow(2,2) = 4 = 00000100
1 shl 3 = pow(2,3) = 8 = 00001000
1 shl 4 = pow(2,4) = 16 = 00010000
etc.
}
Shift := Shift + 1;
{ decremente l'index du tableau en entrée
(le binaire se lit de droite a gauche (Intel) }
BIndex := BIndex - 1;
end;
{ incremente l'index du tableau en sortie }
RIndex := RIndex + 1;
end;
end;