Einzelnen Beitrag anzeigen

DieDolly

Registriert seit: 22. Jun 2018
2.175 Beiträge
 
#1

d7zip / sevenzip.pas von mail2nnv - Fragen zur Funktionsweise, DictionarySize, ...

  Alt 29. Apr 2023, 10:12
Ich gehe gerade weg von JclCompression hin zu einem anderen ebenfalls kostenlosen Wrapper für die 7z.dll.
Dabei ist der aktuellsten den ich finden kann ein Fork vom originalen d7zip von mail2nnv https://github.com/mail2nnv/d7zip

Ich habe den ein wenig angepasst
- AddBk ist weg es gibt jetzt nur noch den SysUtils-Aufruf IncludeTrailingPathDelimiter
- ForceDirectories auch weg, nur noch SysUtils direkt
- SetDateTimeFile wurde durch TFile.SetCreationTime() ersetzt
- LZMA habe ich aus TZipCompressionMethod entfernt, da das scheinbar inkompatibel ist?

Das funktioniert soweit ganz gut. Aber ich habe noch keine Ahnung, was für Werte bei SetDictionarySize einzufügen sind. Bei 7z ist 63 die Obergrenze, bei Zip 32. Alles andere knallt.

Hier mein erster Versuch der funktioniert. Das ist jetzt nur alles reingeschrieben, keine Benutzeroberfläche (nur ein Button und eine ProgressBar). Es geht nur um den Test.
Wie funktioniet das mit der Wörterbuchgröße? In dieser Dokumentation wird von ganz anderen Werten gesprochen https://sevenzip.osdn.jp/chm/cmdline...DictionarySize

Was ich auch nicht verstehe:
- Kompressionsverfahren ist Copy, Kompressionsstärke 0 (Speichern). Wenn ich bei 7z die sonstigen Optionen auslassen, wird das Archiv auch nicht komprimiert. Schalte ich aber Multithreading dazu, wird es trotzdem komprimiert
- schalte ich alle Optionen ab und nur SetDictionnarySize() an, gibt es einen Fehler bei der Bereichsprüfung. Setze ich den Wert einfach mal auf 1, geht es. Aber woher soll ich das Maximum wissen?
Verwende ich das falsch?

Delphi-Quellcode:
function ProgressCallback(Sender: Pointer; Total: Boolean; Value: Int64): HRESULT; stdcall;
begin
 BytesCopied := Value; // Test

 if Total then
  Form1.ProgressBar1.Max := 100
 else
  Form1.ProgressBar1.Position := GetPercent(BytesToCopy, BytesCopied);

 Result := S_OK;
end;

function CompressionStrength(cs: TCompressStrength): Cardinal;
begin
 case cs of
  SAVE:
   Result := 0;
  FASTEST:
   Result := 1;
  FAST:
   Result := 3;
  NORMAL:
   Result := 5;
  MAXIMUM:
   Result := 7;
  ULTRA:
   Result := 9;
 else
  Result := 5;
 end;
end;

procedure X;
begin
var
 Archivformat: TGUID;
 Archivename: string;
 Arch: I7zOutArchive;
begin
 Archivformat := CLSID_CFormat7z;
 Arch := CreateOutArchive(Archivformat);

 Archivename := 'archive.7z';

 // Add a progress bar ...
 Arch.SetProgressCallback(nil, ProgressCallback);

 Arch.AddFile('1.mp4', '1.mp4');
 Arch.AddFile('2.mp4', '2.mp4');
 BytesToCopy := TFile.GetSize('1.mp4') + TFile.GetSize('2.mp4'); // Test

 // Compression level 0-9
 SetCompressionLevel(Arch, CompressionStrength(TCompressStrength.ULTRA));

 // 7z options
 if Archivformat = CLSID_CFormat7z then
  begin
   // ==============================================================================================================================================
   // Compression method
   SevenZipSetCompressionMethod(Arch, T7zCompressionMethod.m7LZMA);

   // Multithreading
   SetMultiThreading(Arch, CPUCount);

   // Compress headers
   SevenZipCompressHeaders(Arch, True);

   SetDictionnarySize(Arch, 63); // 0-63

   // Encrypt headers
   SevenZipEncryptHeaders(Arch, True);

   // Encrpytion method is always AES265
   // ==============================================================================================================================================
  end
 else
  // ZIP options
  if Archivformat = CLSID_CFormatZip then
   begin
    // ==============================================================================================================================================
    // Compression method (LZMA not available)
    SetCompressionMethod(Arch, TZipCompressionMethod.mzBZip2);

    // Multithreading
    SetMultiThreading(Arch, CPUCount);

    // Dictionnary size
    SetDictionnarySize(Arch, 32); // 0-32

    // Encryption method
    SetEncryptionMethod(Arch, TZipEncryptionMethod.emAES256);

    // Number deflate passes
    SetDeflateNumPasses(Arch, 2); // 1-?

    // Number fast bytes
    SetNumFastBytes(Arch, 256); // max 0-?
    // ==============================================================================================================================================
   end;

  // Set a password if necessary
  Arch.SetPassword('password');

  // Save to file
  Arch.SaveToFile(Archivename);
 end;
Procedure SetCompressionLevel abgeändert in das da unten funktioniert auch nicht. Immer Fehler Bereichsprüfung.
Delphi-Quellcode:
procedure SetCompressionLevel(Arch: I7zOutArchive; level: Cardinal);
begin
  SetCardinalProperty(arch, 'X', level);
  
  // TEST

  if level <= 9 then
   begin
    if level >= 9 then
     SetDictionnarySize(Arch, kLzmaDicSizeX9)
    else if level >= 7 then
     SetDictionnarySize(Arch, kLzmaDicSizeX7)
    else if level >= 5 then
     SetDictionnarySize(Arch, kLzmaDicSizeX5)
    else if level >= 3 then
     SetDictionnarySize(Arch, kLzmaDicSizeX3)
    else
     SetDictionnarySize(Arch, kLzmaDicSizeX1);
   end
  else
   raise Exception.Create(RsCompressionUnavailableProperty);
end;

Geändert von DieDolly (29. Apr 2023 um 10:39 Uhr)
  Mit Zitat antworten Zitat