Tema: ImgToBase64
Ver Mensaje Individual
  #12  
Antiguo 15-03-2016
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.197
Reputación: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Hay un bug en la unit BASE64, concretamente en Decode64, que no afecta al funcionamiento pero si altera en 1 o 2 bytes el tamaño del buffer. Vuelvo a publicar la unit completa y un ejemplo de como conseguir usar Streams.
Código Delphi [-]
unit BASE64;

interface

type
  TAByte = Array of Byte;
  PAByte = ^TAByte;

  function Decode64(S: String): TAByte;
  function Encode64(Bin: PByte; Count: integer): String;

implementation

const
 SB64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';

type
  SAByte = Array[0..0] of Byte;
  PSAByte = ^SAByte;

function find(C: CHAR): integer;
begin
  Result:= 0;
  while (SB64[Result+1] <> C) and (Result < 64) do inc(Result);
end;

function Decode64(S: String): TAByte;
var
  B0, B1, B2, B3: BYTE;
  L, n, i: integer;
begin
  n:= 1;
  i:= 0;
  L:= Length(S);
  if S[L] = '=' then dec(L);
  if S[L] = '=' then dec(L);
  SetLength(Result, (L*3) div 4);
  repeat
    B0:= find(S[n]);
    B1:= find(S[n+1]);
    B2:= find(S[n+2]);
    B3:= find(S[n+3]);

    Result[i]:=   (B0 shl 2) or (B1 shr 4);
    if B2 = 64 then break;
    Result[i+1]:= (B1 shl 4) or (B2 shr 2);
    if B3 = 64 then break;
    Result[i+2]:= (B2 shl 6) or B3;
    inc(n, 4);
    inc(i, 3);
  until n>L;
end;


function Encode64(Bin: PByte; Count: integer): String;
var
  B0, B1, B2: BYTE;
  ABin: PSAByte;
  Add, L, n, i: integer;
begin
  if Count = 0 then exit;
  ABin:= PSAByte(Bin);
  n:= 0;
  i:=1;
  L:= ((Count+2) div 3)*4;
  SetLength(Result, L);
  repeat
    B0:= ABin^[n];
    B1:= 0; B2:= 0;
    if (Count - n) > 0 then B1:= ABin^[n+1];
    if (Count - n) > 1 then B2:= ABin^[n+2];
    Result[i]:=   SB64[(B0 shr 2) and $003F +1];
    Result[i+1]:= SB64[((B0 shl 4) or (B1 shr 4)) and $003F +1];
    Result[i+2]:= SB64[((B1 shl 2) or (B2 shr 6)) and $003F +1];
    Result[i+3]:= SB64[(B2 and $3F) +1];
    inc(n,3);
    inc(i,4);
  until n >= Count;
  if n - Count >= 1 then Result[L]:=   '=';
  if n - Count = 2  then Result[L-1]:= '=';
end;

end.

Para usar TMemoryStream sin modificar la Unit puedes implementar algo como esto:
Código Delphi [-]
function StreamEncode64(var MStream: TMemoryStream): string;
begin
  Result:= Encode64(MStream.Memory, MStream.Size);
end;

procedure StreamDencode64(var S: String; var MStream: TMemoryStream);
var
  Bytes: TAByte;
  Size: integer;
begin
  Bytes:= Decode64(S);
  Size:= Length(Bytes);
  MStream.SetSize(Size);
  Move(Bytes[0], MStream.Memory^, Size);
  SetLength(Bytes,0);
end;


Saludos.
Responder Con Cita