Delphi Xe4. There is a set of components for data compression : ABBREVIA (http://tpabbrevia.sourceforge.net) It implements LZMA compression, and a module AbLZMA.pas (Lzma compression / decompression routines).
Use it :
...
Uses ablzma;
...
procedure TForm1.Button1Click(Sender: TObject);
var f1,f2:tfilestream;
begin
f1:=tfilestream.Create('d:\1.test',fmOpenRead);
f2:=tfilestream.Create('d:\1.lzma',fmCreate);
LzmaEncodeStream(f1,f2,f1.Size);
f2.Free;
f1.Free;
end;
...
Everything is working fine.
Questions:
- how to add code to display percent complete operation?
- how to add code to the abort of the compression process?
In module AbLZMA.pas (also tried to use AbLZMAStream.pas) is the main procedure LzmaEnc_Encode, who works at a call LzmaEncodeStream:
function LzmaEnc_Encode(p: CLzmaEncHandle; outStream: PISeqOutStream;
inStream: PISeqInStream; Progress: PICompressProgress;
Alloc, allocBig: PISzAlloc): SRes; cdecl; external;
It has a parameter "Progress: PICompressProgress;", where
ICompressProgress = packed record
Progress: function(p: Pointer; inSize, outSize: Int64): SRes; cdecl;
end;
PICompressProgress = ^ICompressProgress;
I tried to add a procedure in the module AbLZMA.pas:
function MyProgress(p: Pointer; inSize, outSize: Int64): SRes;cdecl;
begin
// what is "p"?
// form1.caption:=result //?
end;
...
procedure LzmaEncodeStream(ASourceStream, ATargetStream: TStream; ASourceSize: Int64);
var
...
PMyProgress:PICompressProgress;
begin
...
PMyProgress.Progress:=MyProgress;
...
LzmaCheck(LzmaEnc_Encode(LEncHandle, @LOutStreamRec.Intf, @LInStreamRec.Intf,
{nil}PMyProgress // this
,@DelphiMMInterface, @DelphiMMInterface));
...
end;
In this case (even if the body of the procedure blank), getting Error AV. How to get the data from the current percentage of completion?
You have to allocate an
ICompressProgressvariable. You've declared a pointer to one, but then never pointed it at anything.Do it like this:
You are calling
LzmaEnc_Encodewhich is the raw LZMA C interface. The progress callback documentation should exist in the LZMA SDK, but I cannot as yet find any good documentation. I suspect that you'll need to read the C implementation of LZMA to get to the bottom of this.OK, here's the code that calls your progress callback:
The progress callback passes the
PICompressProgressin the first parameter. This allows you to declare yourICompressProgressrecord with extra fields and so allow your callback function to receive state information. TheinSizeparameter is the position in the input stream. You can make a progress value by dividinginSizeby the size of the input stream. And theoutSizeparameter is, presumably, the number of bytes written so far in the output file.If you return any value of than
SZ_OKthen the operation will be cancelled.