Hi all,
I have made my own packfile format, which uses zlib compression behind the scenes.

I would like to release the source codes for the TPackFileReader and TPackFileWriter classes, but I can't till I add in some password protection - I am using it in my PGAnnual competition entry to project some music files...

So I tried adding simple password protection, but I have some issues...

I am currently doing this (writing packfiles):

  • load file to be packed
  • encrypt it
  • compress into packfile


and this when reading packfiles:

  • decompress file from packfile
  • decrypt it


This DOES work, but because I encrypt the files PRIOR to the compression, the packfile size blows out way larger (around 3 x larger!) because of the 'garbled' file data from encrypting it.

I would now somehow like to compress the data and THEN encrypt it prior to storing in the packfile (writing to packfiles), and then decrypt and decompress reading from packfiles).

Below are my two routines I use to compress and decompress streams using the zlib library:

[pascal]Procedure CompressStream(Const SrcStream,DstStream : TStream);
Var
CompressionStream : TCompressionStream;
Begin
CompressionStream := TCompressionStream.Create(clMax,DstStream);
Try
CompressionStream.CopyFrom(SrcStream,0);
Finally
CompressionStream.Free;
End;
End;
{................................................. .............................}

{................................................. .............................}
Procedure DecompressStream(Const SrcStream,DstStream : TStream;
Const Size : Int64);
Var
DecompressionStream : TDecompressionStream;
Begin
DecompressionStream := TDecompressionStream.Create(SrcStream);
Try
DstStream.CopyFrom(DecompressionStream,Size);
Finally
DecompressionStream.Free;
DstStream.Seek(0,soFromBeginning);
End;
End;[/pascal]

I want to somehow put in a intermediate buffer (TMemoryStream, Dynamic Array, etc) in the routines I can compress to, then encrypt, and write, or read from, decrypt and then decompress to make the final file size smaller.

I hope I'm making sense?

any ideas?

Below you can find the attempt at myself doing this, but I am getting read stream errors:

[pascal]
Procedure CompressStream(Const SrcStream,DstStream : TStream);
Var
CompressionStream : TCompressionStream;
Buffer : TMemoryStream;
BufferSize : Int64;
Begin
Buffer := TMemoryStream.Create;
Try
CompressionStream := TCompressionStream.Create(clMax,Buffer);
Try
CompressionStream.CopyFrom(SrcStream,0);
Buffer.Seek(0,soFromBeginning);
BufferSize := Buffer.Size;
DstStream.Write(BufferSize,SizeOf(BufferSize));
DstStream.CopyFrom(Buffer,0);
Finally
CompressionStream.Free;
End;
Finally
Buffer.Free;
End;
End;
{................................................. .............................}

{................................................. .............................}
Procedure DecompressStream(Const SrcStream,DstStream : TStream;
Const Size : Int64);
Var
DecompressionStream : TDecompressionStream;
Buffer : TMemoryStream;
BufferSize : Int64;
Begin
Buffer := TMemoryStream.Create;
Try
SrcStream.Read(BufferSize,SizeOf(BufferSize));
Buffer.CopyFrom(SrcStream,BufferSize);

DecompressionStream := TDecompressionStream.Create(SrcStream);
Try
Buffer.CopyFrom(DecompressionStream,BufferSize);
Buffer.Seek(0,soFromBeginning);
DstStream.CopyFrom(Buffer,0);
Finally
DecompressionStream.Free;
DstStream.Seek(0,soFromBeginning);
End;
Finally
Buffer.Free;
End;
End;[/pascal]

Once I get these routines working (with buffer), I can then easily add in the encryption/decryption on the buffers

cheers,
Paul