Home > Software engineering >  How check if is GZip compression algorithm?
How check if is GZip compression algorithm?

Time:11-22

I have this C# code that is able to verify if a MemoryStream is compressed with GZip before decompression:

// Ref: https://stackoverflow.com/a/6059342/16631852
if (input.ReadByte() == 0x1f && input.ReadByte() == 0x8b)

public MemoryStream Decompress(MemoryStream input)
{
    MemoryStream wmfStream;

    input.Position = 0;

    if (input.ReadByte() == 0x1f && input.ReadByte() == 0x8b)
    {
        input.Position = 0;

        wmfStream = new MemoryStream();
        var buffer = new byte[1024];
        var compressedFile = new GZipStream(input, CompressionMode.Decompress, true);
        int bytesRead;

        while ((bytesRead = compressedFile.Read(buffer, 0, buffer.Length)) > 0)
        {
            wmfStream.Write(buffer, 0, bytesRead);
        }
    }
    else
    {
        wmfStream = input;
    }

    wmfStream.Position = 0;

    return wmfStream;
}

Later i found a possible Delphi variant of this code (in my opinion) to make GZip decompression using System.Zlib:

uses System.ZLib;

const
  ZLIB_GZIP_WINDOWBITS    = 31;
  ZLIB_DEFLATE_WINDOWBITS = 15;

procedure ZLibDecompressStream(Source, Dest: TStream;
  const GZipFormat: Boolean = True); overload;
  
procedure ZLibDecompressStream(Source, Dest: TStream; const GZipFormat: Boolean);
var
  WindowBits: Integer;
  UnZip: TDecompressionStream;
begin
  if GZipFormat then
    WindowBits := ZLIB_GZIP_WINDOWBITS
  else
    WindowBits := ZLIB_DEFLATE_WINDOWBITS;

  UnZip := TDecompressionStream.Create(Source, WindowBits);
  try
    Dest.CopyFrom(UnZip, 0);
  finally
    FreeAndNil(UnZip);
  end;
end;

Then how verify (on Delphi code) if MemoryStream is compressed with GZip before initialize decompression (similar to C# code above)?

CodePudding user response:

The C# code is checking for the GZip header, which is two bytes:

0x1f 0x8b

You can do the same in Delphi:

function IsGZipStream(Stream: TStream): Boolean;
var
  B1, B2: Byte;
begin
  Result := False;
  if Stream.Size >= 2 then
  begin
    Stream.Read(B1, 1);
    Stream.Read(B2, 1);
    Result := (B1 = $1F) and (B2 = $8B);
    Stream.Seek(-2, soFromCurrent);
  end;
end;
  • Related