Recent

Author Topic: 7zip DLL is super broken  (Read 1745 times)

domasz

  • Hero Member
  • *****
  • Posts: 550
7zip DLL is super broken
« on: September 11, 2024, 10:11:04 am »
Has anyone actually used 7zip DLL in a Delphi/Lazarus application?

In both Delphi and Lazarus it's super broken.
The lib is available in many places, here's one:
https://github.com/PascalVault/Lazarus_7zip

Here's a sample code:
Code: Pascal  [Select][+][-]
  1. var
  2.    Arch: I7zOutArchive;
  3.    Str: TFileSTream;
  4.  begin
  5.    Arch := CreateOutArchive(CLSID_CFormat7z);
  6.  
  7.    Arch.AddFile('C:\7z.dll', '7z.dll');
  8.    Arch.AddFile('C:\change.log', 'change.log');
  9.  
  10.    SetCompressionLevel(Arch, 9);
  11.  
  12.    SevenZipSetCompressionMethod(Arch, m7LZMA);
  13.  
  14.    Arch.SetPropertie('MT', 'off'); //disabled multi-threading. When MT is on progress bar doesn't work
  15.  
  16.    Arch.SetProgressCallback(nil, @ProgressCallback);
  17.  
  18.    Str := TFileSTream.Create('C:\tesssst.7z', fmCreate);
  19.  
  20.    Arch.SaveToStream(Str);
  21.    Str.Free;
  22. end;

This does work but it compresses using LZMA2 not LZMA. And the compression level is not 9. It's always the same.
« Last Edit: September 11, 2024, 10:14:36 am by domasz »

rvk

  • Hero Member
  • *****
  • Posts: 6530
Re: 7zip DLL is super broken
« Reply #1 on: September 11, 2024, 12:05:27 pm »
In both Delphi and Lazarus it's super broken.
What makes you think the DLL itself is broken?
I have a unit in Delphi which uses LZMA and not LZMA2 in your example (although in my source the compression-level also doesn't do much).

So it's your pascal source which doesn't correctly address the DLL.


domasz

  • Hero Member
  • *****
  • Posts: 550
Re: 7zip DLL is super broken
« Reply #2 on: September 11, 2024, 12:56:22 pm »
If you use DLL from old 7zip (for example version 9.20) the default compression is LZMA. If you newest DLL (v. 24) the default compression is LZMA2.
Upgrade your project to newest DLL and see if it still compresses with LZMA.

rvk

  • Hero Member
  • *****
  • Posts: 6530
Re: 7zip DLL is super broken
« Reply #3 on: September 11, 2024, 01:18:42 pm »
Ha, yes. I did the test in Delphi (which is 32 bit) and had a rogue 7z.dll in my path  :-[

It does seem that the default is LZMA2 now.

But... you have this in the source:
Code: Pascal  [Select][+][-]
  1.   T7zCompressionMethod = (m7Copy, m7LZMA, m7BZip2, m7PPMd, m7Deflate, m7Deflate64);

m7LZMA will default to LZMA2 now.
How would you force LZMA then?

It still might not be a problem with the 7z.dll itself but with the passing of LZMA (and not the default) to that newer DLL.

In your case the m7LZMA should be probably be m7LZMA_default (or m7LZMA2) and you need to add a m7LZMA_old or something.

But I'm not sure what the correct value for property 0 is for LZMA.
Code: Pascal  [Select][+][-]
  1. type
  2.   T7zCompressionMethod = (m7Copy, m7LZMA, m7BZip2, m7PPMd, m7Deflate, m7Deflate64); // <-------
  3.  
  4. procedure SevenZipSetCompressionMethod(Arch: I7zOutArchive; method: T7zCompressionMethod);
  5. begin
  6.   Arch.SetPropertie('0', SevCompressionMethod[method]);
  7. end;

rvk

  • Hero Member
  • *****
  • Posts: 6530
Re: 7zip DLL is super broken
« Reply #4 on: September 11, 2024, 01:25:10 pm »
BTW mORMot2 has this:

Code: Pascal  [Select][+][-]
  1.   T7zCompressionMethod = (
  2.     m7Copy,
  3.     m7Lzma,
  4.     mzLzma2,
  5.     m7BZip2,
  6.     m7Ppmd,
  7.     m7Deflate,
  8.     m7Deflate64);
  9.  
  10.   SevCompressionMethod: array[T7zCompressionMethod] of WideString = (
  11.     'COPY', 'LZMA', 'LZMA2', 'BZIP2', 'PPMD', 'DEFLATE', 'DEFLATE64');
So there they do have a distinction between LZMA and LZMA2.

(Haven't tested it there yet with the latest dll, I will try later.)

domasz

  • Hero Member
  • *****
  • Posts: 550
Re: 7zip DLL is super broken
« Reply #5 on: September 11, 2024, 01:58:19 pm »
Thank you for testing!

rvk

  • Hero Member
  • *****
  • Posts: 6530
Re: 7zip DLL is super broken
« Reply #6 on: September 11, 2024, 02:36:01 pm »
Yes, mORMot2 does differentiate between LZMA and LZMA2 with the newer 7z.dll.

As mentioned above... it passes a widestring LZMA2 or LZMA.

I do find it strange because in your sevenzip7.pas it should also pass the string LZMA (and not LZMA2) so it should create a LZMA 7z.

rvk

  • Hero Member
  • *****
  • Posts: 6530
Re: 7zip DLL is super broken
« Reply #7 on: September 11, 2024, 02:40:29 pm »
Aaargh... have you tried setting the properties BEFORE you add the files ??? !!!

Code: Pascal  [Select][+][-]
  1.   Arch := CreateOutArchive(CLSID_CFormat7z);
  2.   SetCompressionLevel(Arch, 2);
  3.   Arch.SetPropertie('MT', 'off');
  4.   SevenZipSetCompressionMethod(Arch, m7LZMA);
  5.   Arch.AddFile('C:\7z.dll', '7z.dll');
  6.   Arch.AddFile('C:\change.log', 'change.log');
  7.   Arch.SetProgressCallback(nil, @ProgressCallback);
  8.   Str := TFileSTream.Create('C:\tesssst.7z', fmCreate);
  9.   Arch.SaveToStream(Str);
  10.   Str.Free;

That should do the trick  :P

domasz

  • Hero Member
  • *****
  • Posts: 550
Re: 7zip DLL is super broken
« Reply #8 on: September 11, 2024, 03:13:45 pm »
Aaargh... have you tried setting the properties BEFORE you add the files ??? !!!

That's how they do this in the first version of the wrapper:
https://github.com/geoffsmith82/d7zip

Compression level still doesn't work but method does- thanks!

rvk

  • Hero Member
  • *****
  • Posts: 6530
Re: 7zip DLL is super broken
« Reply #9 on: September 11, 2024, 03:21:56 pm »
Aaargh... have you tried setting the properties BEFORE you add the files ??? !!!

That's how they do this in the first version of the wrapper:
https://github.com/geoffsmith82/d7zip

Compression level still doesn't work but method does- thanks!
Also still works with setting the method after the AddFile.

The problem is the setting of MT to off. Apparently this resets the properties.
(BTW there is also a SetMultiThreading() for this)

When doing it before m7LZMA it works fine.
Code: Pascal  [Select][+][-]
  1.   Arch.SetPropertie('MT', 'off');
  2.   SevenZipSetCompressionMethod(Arch, m7LZMA);

But doing this will reset the method to m7LZMA2 !!
Code: Pascal  [Select][+][-]
  1.   SevenZipSetCompressionMethod(Arch, m7LZMA);
  2.   Arch.SetPropertie('MT', 'off');
  3.  

Not sure if the order for compression level is also effected (but you can check that easilly)  :D
But it's weird that setting this property resets things (as it is just a single property).
« Last Edit: September 11, 2024, 03:27:32 pm by rvk »

domasz

  • Hero Member
  • *****
  • Posts: 550
Re: 7zip DLL is super broken
« Reply #10 on: September 11, 2024, 03:40:27 pm »
Hah, crazy. This seems to work:

Code: Pascal  [Select][+][-]
  1.   Arch.SetPropertie('MT', 'off');
  2.    Arch.SetProgressCallback(nil, @ProgressCallback);
  3.  
  4.    // add a file
  5.    Arch.AddFile('...');
  6.    Arch.AddFile('...');
  7.  
  8.   SevenZipSetCompressionMethod(Arch, m7LZMA);
  9.   SetCompressionLevel(Arch, 9);
  10. //   Arch.SetPassword('password');
  11.  
  12.    Str := TFileSTream.Create....

rvk

  • Hero Member
  • *****
  • Posts: 6530
Re: 7zip DLL is super broken
« Reply #11 on: September 11, 2024, 03:42:44 pm »
Hah, crazy. This seems to work:
Yes (doing the SetMultiThreading before everything seems to work).

I have the feeling there is something overwritten when applying a ULONG as property.
Maybe that's why the compression level also doesn't work (it also uses ULONG/Cardinal).

Thaddy

  • Hero Member
  • *****
  • Posts: 16036
  • Censorship about opinions does not belong here.
Re: 7zip DLL is super broken
« Reply #12 on: September 11, 2024, 05:07:34 pm »
ULONG is correct as cardinal, but not as dword, wich translates to ulonglong.
If I smell bad code it usually is bad code and that includes my own code.

domasz

  • Hero Member
  • *****
  • Posts: 550
Re: 7zip DLL is super broken
« Reply #13 on: September 11, 2024, 05:13:04 pm »
ULONG is correct as cardinal, but not as dword, wich translates to ulonglong.

I don't get what you mean.

Ulong = UInt32
Cardinal = UInt32
Dword = UInt32
Ulongulong = UInt64

rvk

  • Hero Member
  • *****
  • Posts: 6530
Re: 7zip DLL is super broken
« Reply #14 on: September 11, 2024, 05:26:55 pm »
The ULONG (32 bit / 4 bytes) should be correct for the 7z api.
VT_UI4 (https://www.tc4shell.com/en/7zip/parameterapi/)

Setting compression level does seem to work if you don't set the LZMA (but leave default or set LZMA2).

So maybe setting method to LZMA will switch the default to X=9.

And setting X=9 afterwards will switch to default LZMA2  ;)

(I also wonder if 2 is a valid compression level because I never see it, only 0, 3, 5, 7 and 9.)

https://documentation.help/7-Zip-18.0/method.htm#7Z

BTW That page does mention LZMA2 for compression levels 3, 5, 7 and 9 (so maybe those forces LZMA2).
(and setting it back to LZMA forces the X to be 9 again, a catch 22  ;) )
https://documentation.help/7-Zip-18.0/method.htm#SevenZipX
« Last Edit: September 11, 2024, 05:32:26 pm by rvk »

 

TinyPortal © 2005-2018