ADD: Zip - capability to change compression settings of all supported formats

This commit is contained in:
Alexander Koblov 2023-02-24 20:28:17 +03:00
commit 8c46e8b089
17 changed files with 541 additions and 175 deletions

View file

@ -7,7 +7,7 @@ uses
FPCAdds,
SysUtils,
Classes,
ZipFunc in 'ZipFunc.pas';
ZipFunc, ZipOpt;
exports
{ Mandatory }

View file

@ -1,30 +1,30 @@
object DialogBox: TDialogBox
Left = 518
Height = 325
Top = 108
Width = 455
Left = 693
Height = 353
Top = 345
Width = 438
AutoSize = True
BorderStyle = bsDialog
Caption = 'Zip plugin configuration'
ChildSizing.LeftRightSpacing = 10
ChildSizing.TopBottomSpacing = 10
ClientHeight = 325
ClientWidth = 455
ClientHeight = 353
ClientWidth = 438
OnShow = DialogBoxShow
Position = poOwnerFormCenter
LCLVersion = '2.0.8.0'
LCLVersion = '2.2.4.0'
object lblAbout: TLabel
AnchorSideLeft.Control = Owner
AnchorSideTop.Control = Owner
AnchorSideRight.Control = gbCompression
AnchorSideRight.Side = asrBottom
Left = 10
Height = 72
Height = 57
Top = 10
Width = 418
Width = 417
Alignment = taCenter
Anchors = [akTop, akLeft, akRight]
Caption = 'Zip plugin supports PKZIP-compatible, TAR, GZip and BZip2 data compression and archiving.'#10#10'Copyright (C) 2006-2020 Alexander Koblov (alexx2000@mail.ru)'
Caption = 'Zip plugin supports PKZIP-compatible, TAR, XZ, GZip, Zstandard and BZip2 data compression and archiving.'
ParentColor = False
WordWrap = True
end
@ -33,9 +33,9 @@ object DialogBox: TDialogBox
AnchorSideTop.Control = lblAbout
AnchorSideTop.Side = asrBottom
Left = 10
Height = 153
Top = 102
Width = 418
Height = 203
Top = 87
Width = 417
AutoSize = True
BorderSpacing.Top = 20
Caption = 'Compression'
@ -46,87 +46,93 @@ object DialogBox: TDialogBox
ChildSizing.EnlargeHorizontal = crsHomogenousChildResize
ChildSizing.Layout = cclLeftToRightThenTopToBottom
ChildSizing.ControlsPerLine = 2
ClientHeight = 126
ClientWidth = 412
ClientHeight = 183
ClientWidth = 415
TabOrder = 0
object lblCompressionMethodToUse: TLabel
AnchorSideTop.Side = asrCenter
object lblArchiveFormat: TLabel
Left = 10
Height = 26
Height = 35
Top = 10
Width = 202
Caption = 'Compression method:'
Width = 204
Caption = 'Archive format:'
Layout = tlCenter
ParentColor = False
end
object cbCompressionMethodToUse: TComboBox
AnchorSideRight.Side = asrBottom
Left = 237
Height = 26
object cbArchiveFormat: TComboBox
Left = 239
Height = 35
Top = 10
Width = 165
ItemHeight = 18
ItemIndex = 2
Items.Strings = (
'Store'
'Deflate'
'Optimal (2x slower)'
)
Width = 166
ItemHeight = 0
OnChange = ComboBoxChange
Style = csDropDownList
TabOrder = 0
end
object lblDeflationOption: TLabel
object lblCompressionMethod: TLabel
AnchorSideTop.Side = asrCenter
Left = 10
Height = 26
Top = 41
Width = 202
Caption = 'Compression level:'
Height = 35
Top = 50
Width = 204
Caption = 'Compression method:'
Layout = tlCenter
ParentColor = False
end
object cbDeflationOption: TComboBox
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Side = asrBottom
object cbCompressionMethod: TComboBox
AnchorSideRight.Side = asrBottom
Left = 237
Height = 26
Top = 41
Width = 165
BorderSpacing.Left = 20
ItemHeight = 18
ItemIndex = 0
Items.Strings = (
'Normal'
'Maximum'
'Fast'
'Fastest'
)
Left = 239
Height = 35
Top = 50
Width = 166
ItemHeight = 0
OnChange = ComboBoxChange
Style = csDropDownList
TabOrder = 1
end
object lblCompressionLevel: TLabel
AnchorSideTop.Side = asrCenter
Left = 10
Height = 35
Top = 90
Width = 204
Caption = 'Compression level:'
Layout = tlCenter
ParentColor = False
end
object cbCompressionLevel: TComboBox
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Side = asrBottom
AnchorSideRight.Side = asrBottom
Left = 239
Height = 35
Top = 90
Width = 166
BorderSpacing.Left = 20
ItemHeight = 0
OnChange = ComboBoxChange
Style = csDropDownList
TabOrder = 2
end
object chkTarAutoHandle: TCheckBox
AnchorSideLeft.Control = gbCompression
AnchorSideTop.Control = cbDeflationOption
AnchorSideTop.Control = cbCompressionLevel
AnchorSideTop.Side = asrBottom
Left = 10
Height = 24
Top = 77
Width = 392
Height = 23
Top = 135
Width = 395
BorderSpacing.Top = 10
Caption = 'Open *.tar.xyz archives at one step (slowly with big archives)'
TabOrder = 2
TabOrder = 3
end
end
object btnOK: TBitBtn
AnchorSideTop.Control = btnCancel
AnchorSideTop.Side = asrCenter
AnchorSideRight.Control = btnCancel
Left = 218
Height = 29
Top = 275
Left = 217
Height = 36
Top = 310
Width = 100
Anchors = [akTop, akRight]
AutoSize = True
@ -144,9 +150,9 @@ object DialogBox: TDialogBox
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = gbCompression
AnchorSideRight.Side = asrBottom
Left = 328
Height = 29
Top = 275
Left = 327
Height = 36
Top = 310
Width = 100
Anchors = [akTop, akRight]
AutoSize = True

View file

@ -3,7 +3,7 @@
-------------------------------------------------------------------------
WCX plugin for working with *.zip, *.gz, *.bz2, *.tar, *.tgz, *.tbz archives
Copyright (C) 2008-2014 Alexander Koblov (alexx2000@mail.ru)
Copyright (C) 2008-2023 Alexander Koblov (alexx2000@mail.ru)
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
@ -34,16 +34,161 @@ uses
SysUtils, Extension;
procedure CreateZipConfDlg;
procedure LoadConfig;
procedure SaveConfig;
implementation
uses ZipFunc, AbZipTyp, DCClassesUtf8;
uses
ZipFunc, ZipOpt, ZipLng, AbZipTyp;
function GetComboBox(pDlg: PtrUInt; DlgItemName: PAnsiChar): PtrInt;
var
Index: IntPtr;
begin
with gStartupInfo do
begin
Index:= SendDlgMsg(pDlg, DlgItemName, DM_LISTGETITEMINDEX, 0, 0);
Result:= SendDlgMsg(pDlg, DlgItemName, DM_LISTGETDATA, Index, 0);
end;
end;
procedure SetComboBox(pDlg: PtrUInt; DlgItemName: PAnsiChar; ItemData: PtrInt);
var
Index, Count: Integer;
begin
with gStartupInfo do
begin
Count:= SendDlgMsg(pDlg, DlgItemName, DM_LISTGETCOUNT, 0, 0);
for Index:= 0 to Count - 1 do
begin
if SendDlgMsg(pDlg, DlgItemName, DM_LISTGETDATA, Index, 0) = ItemData then
begin
SendDlgMsg(pDlg, DlgItemName, DM_LISTSETITEMINDEX, Index, 0);
Exit;
end;
end;
end;
end;
function ComboBoxAdd(pDlg: PtrUInt; DlgItemName: PAnsiChar; ItemText: String; ItemData: PtrInt): IntPtr;
var
P: PAnsiChar;
AText: IntPtr absolute P;
begin
P:= PAnsiChar(ItemText);
Result:= gStartupInfo.SendDlgMsg(pDlg, DlgItemName, DM_LISTADD, AText, ItemData);
end;
function AddCompressionLevel(pDlg: PtrUInt; const AName: String; ALevel: IntPtr): IntPtr;
var
AText: String;
begin
AText:= AName + ' (' + IntToStr(ALevel) + ')';
Result:= ComboBoxAdd(pDlg, 'cbCompressionLevel', AText, ALevel);
end;
procedure UpdateLevel(pDlg: PtrUInt; ALevel: IntPtr);
var
Index: IntPtr;
AFormat: TArchiveFormat;
AMethod: TAbZipCompressionMethod;
begin
with gStartupInfo do
begin
SendDlgMsg(pDlg, 'cbCompressionLevel', DM_LISTCLEAR, 0, 0);
AFormat:= TArchiveFormat(GetComboBox(pDlg, 'cbArchiveFormat'));
Index:= SendDlgMsg(pDlg, 'cbCompressionMethod', DM_LISTGETITEMINDEX, 0, 0);
AMethod:= TAbZipCompressionMethod(SendDlgMsg(pDlg, 'cbCompressionMethod', DM_LISTGETDATA, Index, 0));
if (AMethod = cmStored) then
begin
SendDlgMsg(pDlg, 'cbCompressionLevel', DM_ENABLE, 0, 0);
end
else begin
SendDlgMsg(pDlg, 'cbCompressionLevel', DM_ENABLE, 1, 0);
case AMethod of
cmDeflated,
cmEnhancedDeflated:
begin
AddCompressionLevel(pDlg, rsCompressionLevelFastest, 1);
AddCompressionLevel(pDlg, rsCompressionLevelFast, 3);
Index:= AddCompressionLevel(pDlg, rsCompressionLevelNormal, 6);
AddCompressionLevel(pDlg, rsCompressionLevelMaximum, 9);
end;
cmXz,
cmLZMA,
cmBzip2:
begin
AddCompressionLevel(pDlg, rsCompressionLevelFastest, 1);
AddCompressionLevel(pDlg, rsCompressionLevelFast, 3);
Index:= AddCompressionLevel(pDlg, rsCompressionLevelNormal, 5);
AddCompressionLevel(pDlg, rsCompressionLevelMaximum, 7);
AddCompressionLevel(pDlg, rsCompressionLevelUltra, 9);
end;
cmZstd:
begin
AddCompressionLevel(pDlg, rsCompressionLevelFastest, 3);
AddCompressionLevel(pDlg, rsCompressionLevelFast, 5);
Index:= AddCompressionLevel(pDlg, rsCompressionLevelNormal, 11);
AddCompressionLevel(pDlg, rsCompressionLevelMaximum, 17);
AddCompressionLevel(pDlg, rsCompressionLevelUltra, 22);
end;
end;
if ALevel < 0 then
SendDlgMsg(pDlg, 'cbCompressionLevel', DM_LISTSETITEMINDEX, Index, 0)
else begin
SetComboBox(pDlg, 'cbCompressionLevel', PluginConfig[AFormat].Level);
end;
end;
end;
end;
procedure UpdateMethod(pDlg: PtrUInt);
var
Index: IntPtr;
AFormat: TArchiveFormat;
begin
with gStartupInfo do
begin
SendDlgMsg(pDlg, 'cbCompressionMethod', DM_LISTCLEAR, 0, 0);
AFormat:= TArchiveFormat(GetComboBox(pDlg, 'cbArchiveFormat'));
case AFormat of
afGzip:
ComboBoxAdd(pDlg, 'cbCompressionMethod', 'Deflate', PtrInt(cmDeflated));
afXzip:
ComboBoxAdd(pDlg, 'cbCompressionMethod', 'LZMA2', PtrInt(cmXz));
afBzip2:
ComboBoxAdd(pDlg, 'cbCompressionMethod', 'BZip2', PtrInt(cmBzip2));
afZstd:
ComboBoxAdd(pDlg, 'cbCompressionMethod', 'Zstandard', PtrInt(cmZstd));
afZip:
begin
ComboBoxAdd(pDlg, 'cbCompressionMethod', rsCompressionMethodStore, PtrInt(cmStored));
ComboBoxAdd(pDlg, 'cbCompressionMethod', 'Deflate', PtrInt(cmDeflated));
ComboBoxAdd(pDlg, 'cbCompressionMethod', rsCompressionMethodOptimal, PtrInt(cmEnhancedDeflated));
end;
afZipx:
begin
ComboBoxAdd(pDlg, 'cbCompressionMethod', 'LZMA2', PtrInt(cmXz));
ComboBoxAdd(pDlg, 'cbCompressionMethod', 'Zstandard', PtrInt(cmZstd));
end;
end; // case
Index:= SendDlgMsg(pDlg, 'cbCompressionMethod', DM_LISTGETCOUNT, 0, 0);
if (Index = 1) then
begin
SendDlgMsg(pDlg, 'cbCompressionMethod', DM_LISTSETITEMINDEX, 0, 0);
SendDlgMsg(pDlg, 'cbCompressionMethod', DM_ENABLE, 0, 0);
end
else begin
SendDlgMsg(pDlg, 'cbCompressionMethod', DM_ENABLE, 1, 0);
SetComboBox(pDlg, 'cbCompressionMethod', PluginConfig[AFormat].Method);
end;
end;
UpdateLevel(pDlg, PluginConfig[AFormat].Level);
end;
function DlgProc (pDlg: PtrUInt; DlgItemName: PAnsiChar; Msg, wParam, lParam: PtrInt): PtrInt; dcpcall;
var
iIndex: Integer;
Index: IntPtr;
AFormat: TArchiveFormat;
begin
Result:= 0;
with gStartupInfo do
@ -51,51 +196,38 @@ begin
case Msg of
DN_INITDIALOG:
begin
case gCompressionMethodToUse of
smStored:
SendDlgMsg(pDlg, 'cbCompressionMethodToUse', DM_LISTSETITEMINDEX, 0, 0);
smDeflated:
SendDlgMsg(pDlg, 'cbCompressionMethodToUse', DM_LISTSETITEMINDEX, 1, 0);
smBestMethod:
SendDlgMsg(pDlg, 'cbCompressionMethodToUse', DM_LISTSETITEMINDEX, 2, 0);
end; // case
case gDeflationOption of
doNormal:
SendDlgMsg(pDlg, 'cbDeflationOption', DM_LISTSETITEMINDEX, 0, 0);
doMaximum:
SendDlgMsg(pDlg, 'cbDeflationOption', DM_LISTSETITEMINDEX, 1, 0);
doFast:
SendDlgMsg(pDlg, 'cbDeflationOption', DM_LISTSETITEMINDEX, 2, 0);
doSuperFast:
SendDlgMsg(pDlg, 'cbDeflationOption', DM_LISTSETITEMINDEX, 3, 0);
end; // case
ComboBoxAdd(pDlg, 'cbArchiveFormat', 'gz', PtrInt(afGzip));
ComboBoxAdd(pDlg, 'cbArchiveFormat', 'xz', PtrInt(afXzip));
ComboBoxAdd(pDlg, 'cbArchiveFormat', 'bz2', PtrInt(afBzip2));
ComboBoxAdd(pDlg, 'cbArchiveFormat', 'zst', PtrInt(afZstd));
Index:= ComboBoxAdd(pDlg, 'cbArchiveFormat', 'zip', PtrInt(afZip));
ComboBoxAdd(pDlg, 'cbArchiveFormat', 'zipx', PtrInt(afZipx));
SendDlgMsg(pDlg, 'cbArchiveFormat', DM_LISTSETITEMINDEX, Index, 0);
UpdateMethod(pDlg);
SendDlgMsg(pDlg, 'chkTarAutoHandle', DM_SETCHECK, PtrInt(gTarAutoHandle), 0);
end;
DN_CHANGE:
begin
if DlgItemName = 'cbArchiveFormat' then
begin
UpdateMethod(pDlg);
end
else if DlgItemName = 'cbCompressionMethod' then
begin
UpdateLevel(pDlg, -1);
end;
end;
DN_CLICK:
if DlgItemName = 'btnOK' then
begin
iIndex:= SendDlgMsg(pDlg, 'cbCompressionMethodToUse', DM_LISTGETITEMINDEX, 0, 0);
case iIndex of
0:
gCompressionMethodToUse:= smStored;
1:
gCompressionMethodToUse:= smDeflated;
2:
gCompressionMethodToUse:= smBestMethod;
end; // case
iIndex:= SendDlgMsg(pDlg, 'cbDeflationOption', DM_LISTGETITEMINDEX, 0, 0);
case iIndex of
0:
gDeflationOption:= doNormal;
1:
gDeflationOption:= doMaximum;
2:
gDeflationOption:= doFast;
3:
gDeflationOption:= doSuperFast;
end; // case
AFormat:= TArchiveFormat(GetComboBox(pDlg, 'cbArchiveFormat'));
PluginConfig[AFormat].Level:= GetComboBox(pDlg, 'cbCompressionLevel');
PluginConfig[AFormat].Method:= GetComboBox(pDlg, 'cbCompressionMethod');
gTarAutoHandle:= Boolean(SendDlgMsg(pDlg, 'chkTarAutoHandle', DM_GETCHECK, 0, 0));
SaveConfig;
SaveConfiguration;
SendDlgMsg(pDlg, DlgItemName, DM_CLOSE, 1, 0);
end
else if DlgItemName = 'btnCancel' then
@ -137,34 +269,5 @@ begin
end;
end;
procedure LoadConfig;
var
gIni: TIniFileEx;
begin
gIni:= TIniFileEx.Create(gStartupInfo.PluginConfDir + IniFileName);
try
gCompressionMethodToUse:= TAbZipSupportedMethod(gIni.ReadInteger('Configuration', 'CompressionMethodToUse', Integer(smDeflated)));
gDeflationOption:= TAbZipDeflationOption(gIni.ReadInteger('Configuration', 'DeflationOption', Integer(AbDefDeflationOption)));
gTarAutoHandle:= gIni.ReadBool('Configuration', 'TarAutoHandle', True);
finally
gIni.Free;
end;
end;
procedure SaveConfig;
var
gIni: TIniFileEx;
begin
gIni:= TIniFileEx.Create(gStartupInfo.PluginConfDir + IniFileName);
try
gIni.WriteInteger('Configuration', 'CompressionMethodToUse', Integer(gCompressionMethodToUse));
gIni.WriteInteger('Configuration', 'DeflationOption', Integer(gDeflationOption));
gIni.WriteBool('Configuration', 'TarAutoHandle', gTarAutoHandle);
gIni.UpdateFile;
finally
gIni.Free;
end;
end;
end.

View file

@ -82,14 +82,12 @@ const
var
gStartupInfo: TExtensionStartupInfo;
gCompressionMethodToUse : TAbZipSupportedMethod;
gDeflationOption : TAbZipDeflationOption;
gTarAutoHandle : Boolean;
implementation
uses
SysUtils, LazUTF8, ZipConfDlg, AbBrowse, DCConvertEncoding, DCOSUtils;
SysUtils, LazUTF8, ZipConfDlg, AbBrowse, DCConvertEncoding, DCOSUtils, ZipOpt;
threadvar
gProcessDataProcW : TProcessDataProcW;
@ -332,11 +330,13 @@ end;
function PackFilesW(PackedFile: PWideChar; SubPath: PWideChar; SrcPath: PWideChar; AddList: PWideChar; Flags: Integer): Integer;dcpcall;
var
Arc : TAbZipKitEx;
FileExt: String;
FilePath: String;
Arc : TAbZipKitEx;
FileName: UnicodeString;
sPassword: AnsiString;
sPackedFile: String;
ArchiveFormat: TArchiveFormat;
begin
if (Flags and PK_PACK_MOVE_FILES) <> 0 then begin
Exit(E_NOT_SUPPORTED);
@ -346,23 +346,50 @@ begin
try
Arc.AutoSave := False;
Arc.TarAutoHandle:= True;
Arc.CompressionMethodToUse:= gCompressionMethodToUse;
Arc.DeflationOption:= gDeflationOption;
Arc.FProcessDataProcW := gProcessDataProcW;
Arc.OnProcessItemFailure := @Arc.AbProcessItemFailureEvent;
sPackedFile := UTF16ToUTF8(UnicodeString(PackedFile));
try
if ((Flags and PK_PACK_ENCRYPT) <> 0) and
(LowerCase(ExtractFileExt(sPackedFile)) = '.zip') then // only zip supports encryption
FileExt:= LowerCase(ExtractFileExt(sPackedFile));
if ((Flags and PK_PACK_ENCRYPT) <> 0) then
begin
Arc.AbNeedPasswordEvent(Arc, sPassword);
Arc.Password:= sPassword;
// Only zip/zipx supports encryption
if (FileExt = '.zip') or (FileExt = '.zipx') then
begin
sPassword:= EmptyStr;
Arc.AbNeedPasswordEvent(Arc, sPassword);
Arc.Password:= sPassword;
end;
end;
Arc.OpenArchive(sPackedFile);
ArchiveFormat:= ARCHIVE_FORMAT[Arc.ArchiveType];
if (ArchiveFormat = afZip) then
begin
if (FileExt = '.zipx') then
ArchiveFormat:= afZipx
else begin
case PluginConfig[ArchiveFormat].Level of
1: Arc.DeflationOption:= doSuperFast;
3: Arc.DeflationOption:= doFast;
6: Arc.DeflationOption:= doNormal;
9: Arc.DeflationOption:= doMaximum;
end;
case PluginConfig[ArchiveFormat].Method of
PtrInt(cmStored): Arc.CompressionMethodToUse:= smStored;
PtrInt(cmDeflated): Arc.CompressionMethodToUse:= smDeflated;
PtrInt(cmEnhancedDeflated): Arc.CompressionMethodToUse:= smBestMethod;
end;
end;
end;
Arc.ZipArchive.CompressionLevel:= PluginConfig[ArchiveFormat].Level;
Arc.ZipArchive.CompressionMethod:= PluginConfig[ArchiveFormat].Method;
Arc.OnArchiveItemProgress := @Arc.AbArchiveItemProgressEvent;
Arc.OnArchiveProgress := @Arc.AbArchiveProgressEvent;
Arc.StoreOptions := Arc.StoreOptions + [soReplace];
@ -481,7 +508,7 @@ procedure ExtensionInitialize(StartupInfo: PExtensionStartupInfo); dcpcall;
begin
gStartupInfo:= StartupInfo^;
// Load configuration from ini file
LoadConfig;
LoadConfiguration;
end;
{ TAbZipKitEx }

View file

@ -0,0 +1,45 @@
{
Double Commander
-------------------------------------------------------------------------
SevenZip archiver plugin, language support
Copyright (C) 2014-2015 Alexander Koblov (alexx2000@mail.ru)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
}
unit ZipLng;
{$mode delphi}
interface
uses
Classes, SysUtils;
resourcestring
rsCompressionMethodStore = 'Store';
rsCompressionMethodOptimal = 'Optimal (2x slower)';
rsCompressionLevelFastest = 'Fastest';
rsCompressionLevelFast = 'Fast';
rsCompressionLevelNormal = 'Normal';
rsCompressionLevelMaximum = 'Maximum';
rsCompressionLevelUltra = 'Ultra';
implementation
end.

View file

@ -0,0 +1,128 @@
unit ZipOpt;
{$mode ObjFPC}{$H+}
interface
uses
Classes, SysUtils, AbUtils, AbZipTyp;
type
TArchiveFormat = (
afNil,
afZip,
afZipx,
afGzip,
afBzip2,
afXzip,
afLzma,
afZstd
);
TFormatOptions = record
Level: PtrInt;
Method: PtrInt;
end;
const
ARCHIVE_FORMAT: array[TAbArchiveType] of TArchiveFormat =
(
afNil, afZip, afZip, afZip, afNil, afGzip, afGzip, afNil,
afBzip2, afBzip2, afXzip, afXzip, afLzma, afLzma, afZstd, afZstd
);
const
DefaultConfig: array[TArchiveFormat] of TFormatOptions =
(
(Level: 0; Method: 0;),
(Level: 6; Method: PtrInt(cmDeflated);),
(Level: 7; Method: PtrInt(cmXz);),
(Level: 6; Method: PtrInt(cmDeflated);),
(Level: 9; Method: PtrInt(cmBzip2);),
(Level: 7; Method: PtrInt(cmXz);),
(Level: 7; Method: PtrInt(cmLZMA);),
(Level: 11; Method: PtrInt(cmZstd);)
);
var
PluginConfig: array[TArchiveFormat] of TFormatOptions;
procedure LoadConfiguration;
procedure SaveConfiguration;
implementation
uses
TypInfo, DCClassesUtf8, Extension, ZipFunc;
procedure LoadConfiguration;
var
Ini: TIniFileEx;
Section: AnsiString;
ArchiveFormat: TArchiveFormat;
begin
try
Ini:= TIniFileEx.Create(gStartupInfo.PluginConfDir + IniFileName);
try
for ArchiveFormat:= Succ(Low(TArchiveFormat)) to High(TArchiveFormat) do
begin
Section:= Copy(GetEnumName(TypeInfo(TArchiveFormat), PtrInt(ArchiveFormat)), 3, MaxInt);
PluginConfig[ArchiveFormat].Level:= Ini.ReadInteger(Section, 'Level', DefaultConfig[ArchiveFormat].Level);
PluginConfig[ArchiveFormat].Method:= Ini.ReadInteger(Section, 'Method', DefaultConfig[ArchiveFormat].Method);
end;
gTarAutoHandle:= Ini.ReadBool('Configuration', 'TarAutoHandle', True);
// Backward compatibility
case Ini.ReadInteger('Configuration', 'DeflationOption', -1) of
IntPtr(doSuperFast): PluginConfig[afZip].Level:= 1;
IntPtr(doFast): PluginConfig[afZip].Level:= 3;
IntPtr(doNormal): PluginConfig[afZip].Level:= 6;
IntPtr(doMaximum): PluginConfig[afZip].Level:= 9;
end;
case Ini.ReadInteger('Configuration', 'CompressionMethodToUse', -1) of
IntPtr(smStored): PluginConfig[afZip].Method:= IntPtr(cmStored);
IntPtr(smDeflated): PluginConfig[afZip].Method:= IntPtr(cmDeflated);
IntPtr(smBestMethod): PluginConfig[afZip].Method:= IntPtr(cmEnhancedDeflated);
end;
finally
Ini.Free;
end;
except
// Ignore
end;
end;
procedure SaveConfiguration;
var
Ini: TIniFileEx;
Section: AnsiString;
ArchiveFormat: TArchiveFormat;
begin
try
Ini:= TIniFileEx.Create(gStartupInfo.PluginConfDir + IniFileName);
try
for ArchiveFormat:= Succ(Low(TArchiveFormat)) to High(TArchiveFormat) do
begin
Section:= Copy(GetEnumName(TypeInfo(TArchiveFormat), PtrInt(ArchiveFormat)), 3, MaxInt);
Ini.WriteInteger(Section, 'Level', PluginConfig[ArchiveFormat].Level);
Ini.WriteInteger(Section, 'Method', PluginConfig[ArchiveFormat].Method);
end;
Ini.DeleteKey('Configuration', 'DeflationOption');
Ini.DeleteKey('Configuration', 'CompressionMethodToUse');
Ini.WriteBool('Configuration', 'TarAutoHandle', gTarAutoHandle);
Ini.UpdateFile;
finally
Ini.Free;
end;
except
on E: Exception do
begin
gStartupInfo.MessageBox(PAnsiChar(E.Message), nil, MB_OK or MB_ICONERROR);
end;
end;
end;
initialization
Move(DefaultConfig[Low(DefaultConfig)], PluginConfig[Low(PluginConfig)], SizeOf(PluginConfig));
end.

View file

@ -292,6 +292,8 @@ type
FInStream : TStream;
FIsDirty : Boolean;
FSpanningThreshold : Int64;
FCompressionLevel : IntPtr;
FCompressionMethod : IntPtr;
FItemList : TAbArchiveList;
FLogFile : string;
FLogging : Boolean;
@ -495,6 +497,12 @@ type
property TempDirectory : string
read FTempDir
write FTempDir;
property CompressionLevel: IntPtr
read FCompressionLevel
write FCompressionLevel;
property CompressionMethod: IntPtr
read FCompressionMethod
write FCompressionMethod;
public {events}
property OnProcessItemFailure : TAbArchiveItemFailureEvent

View file

@ -114,14 +114,11 @@ type
indicator when you are writing a large chunk of data to the compression
stream in a single call.}
TBlockSize100k = (bs1, bs2, bs3, bs4, bs5, bs6, bs7, bs8, bs9);
TBZCompressionStream = class(TCustomBZip2Stream)
private
function GetCompressionRate: Single;
public
constructor Create(BlockSize100k: TBlockSize100k; Dest: TStream);
constructor Create(Level: IntPtr; Dest: TStream);
destructor Destroy; override;
function Read(var Buffer; Count: Longint): Longint; override;
function Write(const Buffer; Count: Longint): Longint; override;
@ -605,15 +602,13 @@ end; { TCustomBZip2Stream }
// TBZCompressionStream
constructor TBZCompressionStream.Create(BlockSize100k: TBlockSize100k; Dest: TStream);
const
BlockSizes: array[TBlockSize100k] of ShortInt = (1, 2, 3, 4, 5, 6, 7, 8, 9);
constructor TBZCompressionStream.Create(Level: IntPtr; Dest: TStream);
begin
inherited Create(Dest);
LoadBzip2DLL;
FBZRec.next_out := @FBuffer[0];
FBZRec.avail_out := sizeof(FBuffer);
CCheck(BZ2_bzCompressInit(FBZRec, BlockSizes[BlockSize100k], 0, 0));
CCheck(BZ2_bzCompressInit(FBZRec, Level, 0, 0));
end;
destructor TBZCompressionStream.Destroy;

View file

@ -341,7 +341,7 @@ begin
FBzip2Stream := TAbProgressFileStream.Create(TempFileName, fmCreate or fmShareDenyWrite, OnProgress);
end;
FTarStream.Position := 0;
CompStream := TBZCompressionStream.Create(bs9, FBzip2Stream);
CompStream := TBZCompressionStream.Create(CompressionLevel, FBzip2Stream);
try
CompStream.CopyFrom(FTarStream, 0);
finally
@ -372,7 +372,7 @@ begin
aaDelete: ; {doing nothing omits file from new stream}
aaAdd, aaFreshen, aaReplace, aaStreamAdd: begin
FBzip2Stream.Size := 0;
CompStream := TBZCompressionStream.Create(bs9, FBzip2Stream);
CompStream := TBZCompressionStream.Create(CompressionLevel, FBzip2Stream);
try
if CurItem.Action = aaStreamAdd then
CompStream.CopyFrom(InStream, 0){ Copy/compress entire Instream to FBzip2Stream }

View file

@ -197,10 +197,12 @@ type
function GetGzCRC: LongInt;
function GetFileSize: LongInt;
protected {private}
FItem : TAbGzipItem;
FTail : TAbGzTailRec;
FItem : TAbGzipItem;
FTail : TAbGzTailRec;
FArchive : TAbArchive;
public
constructor Create(AStream : TStream);
constructor Create(AStream : TStream); overload;
constructor Create(Archive : TAbArchive; AStream : TStream); overload;
destructor Destroy; override;
procedure ExtractItemData(AStream : TStream); override;
@ -464,12 +466,18 @@ end;
{ TAbGzipStreamHelper }
constructor TAbGzipStreamHelper.Create(AStream : TStream);
constructor TAbGzipStreamHelper.Create(AStream: TStream);
begin
inherited Create(AStream);
FItem := TAbGzipItem.Create;
end;
constructor TAbGzipStreamHelper.Create(Archive : TAbArchive; AStream: TStream);
begin
Create(AStream);
FArchive := Archive;
end;
destructor TAbGzipStreamHelper.Destroy;
begin
FItem.Free;
@ -575,6 +583,12 @@ var
begin
Helper := TAbDeflateHelper.Create;
try
case FArchive.CompressionLevel of
1 : Helper.PKZipOption := 's';
3 : Helper.PKZipOption := 'f';
6 : Helper.PKZipOption := 'n';
9 : Helper.PKZipOption := 'x';
end;
FItem.CRC32 := Deflate(AStream, FStream, Helper);
FItem.UncompressedSize := AStream.Size;
finally
@ -1138,7 +1152,7 @@ begin
NewStream := nil;
try
InGzHelp := TAbGzipStreamHelper.Create(FGzStream);
InGzHelp := TAbGzipStreamHelper.Create(Self, FGzStream);
try
{init new archive stream}
@ -1149,7 +1163,7 @@ begin
ATempName := GetTempName(FArchiveName);
NewStream := TFileStreamEx.Create(ATempName, fmCreate or fmShareDenyWrite);
end;
OutGzHelp := TAbGzipStreamHelper.Create(NewStream);
OutGzHelp := TAbGzipStreamHelper.Create(Self, NewStream);
{ save the Tar data }
if IsGzippedTar and TarAutoHandle then begin

View file

@ -103,7 +103,7 @@ type
protected
function Check(Return: cint): cint; override;
public
constructor Create(ASource, ATarget: TStream); override;
constructor Create(ASource, ATarget: TStream; ALevel: Integer);
function Code(Count: cuint64 = High(cuint64)): Boolean; override;
end;
@ -232,10 +232,10 @@ begin
end;
end;
constructor TLzmaCompression.Create(ASource, ATarget: TStream);
constructor TLzmaCompression.Create(ASource, ATarget: TStream; ALevel: Integer);
begin
inherited Create(ASource, ATarget);
Check(lzma_easy_encoder(FLzmaRec, 6, LZMA_CHECK_CRC64));
Check(lzma_easy_encoder(FLzmaRec, ALevel, LZMA_CHECK_CRC64));
end;
function TLzmaCompression.Code(Count: cuint64): Boolean;

View file

@ -333,7 +333,7 @@ begin
FXzStream := TAbProgressFileStream.Create(TempFileName, fmCreate or fmShareDenyWrite, OnProgress);
end;
FTarStream.Position := 0;
LzmaCompression := TLzmaCompression.Create(FTarStream, FXzStream);
LzmaCompression := TLzmaCompression.Create(FTarStream, FXzStream, FCompressionLevel);
try
LzmaCompression.Code();
finally
@ -366,7 +366,7 @@ begin
FXzStream.Size := 0;
if CurItem.Action = aaStreamAdd then
begin
LzmaCompression := TLzmaCompression.Create(InStream, FXzStream);
LzmaCompression := TLzmaCompression.Create(InStream, FXzStream, FCompressionLevel);
try
LzmaCompression.Code(); { Copy/compress entire Instream to FXzStream }
finally
@ -376,7 +376,7 @@ begin
else begin
InputFileStream := TAbProgressFileStream.Create(CurItem.DiskFileName, fmOpenRead or fmShareDenyWrite, OnProgress);
try
LzmaCompression := TLzmaCompression.Create(InputFileStream, FXzStream);
LzmaCompression := TLzmaCompression.Create(InputFileStream, FXzStream, FCompressionLevel);
try
LzmaCompression.Code(); { Copy/compress entire Instream to FXzStream }
finally

View file

@ -62,7 +62,7 @@ uses
AbVMStrm,
AbDfBase,
AbZlibPrc,
AbXzPrc,
AbZipxPrc,
DCClassesUtf8;
@ -210,7 +210,13 @@ begin
if InStream.Size > 0 then begin
if SameText(ExtractFileExt(Sender.ArchiveName), '.zipx') then
DoCompressXz(ZipArchive, Item, DestStrm, InStream)
begin
case ZipArchive.CompressionMethod of
IntPtr(cmXz): DoCompressXz(ZipArchive, Item, DestStrm, InStream);
IntPtr(cmZstd): DoCompressZstd(ZipArchive, Item, DestStrm, InStream);
else raise Exception.Create(EmptyStr);
end;
end
else
{ determine how to store Item based on specified CompressionMethodToUse }
case ZipArchive.CompressionMethodToUse of

View file

@ -25,12 +25,12 @@
* ***** END LICENSE BLOCK ***** *)
{**********************************************************}
{* ABBREVIA: AbXzPrc.pas *}
{* ABBREVIA: AbZipxPrc.pas *}
{**********************************************************}
{* ABBREVIA: TZipHashStream class *}
{**********************************************************}
unit AbXzPrc;
unit AbZipxPrc;
{$mode delphi}
@ -56,11 +56,12 @@ type
end;
procedure DoCompressXz(Archive : TAbZipArchive; Item : TAbZipItem; OutStream, InStream : TStream);
procedure DoCompressZstd(Archive : TAbZipArchive; Item : TAbZipItem; OutStream, InStream : TStream);
implementation
uses
AbXz, AbExcept, DCcrc32;
AbXz, AbZstd, AbExcept, DCcrc32;
procedure DoCompressXz(Archive : TAbZipArchive; Item : TAbZipItem; OutStream, InStream : TStream);
var
@ -71,7 +72,7 @@ begin
ASource := TZipHashStream.Create(InStream);
try
ASource.OnProgress := Archive.OnProgress;
LzmaCompression := TLzmaCompression.Create(ASource, OutStream);
LzmaCompression := TLzmaCompression.Create(ASource, OutStream, Archive.CompressionLevel);
try
LzmaCompression.Code(Item.UncompressedSize);
finally
@ -83,6 +84,28 @@ begin
end;
end;
procedure DoCompressZstd(Archive: TAbZipArchive; Item: TAbZipItem; OutStream,
InStream: TStream);
var
ASource: TZipHashStream;
CompStream: TZSTDCompressionStream;
begin
Item.CompressionMethod := cmZstd;
ASource := TZipHashStream.Create(InStream);
try
ASource.OnProgress := Archive.OnProgress;
CompStream := TZSTDCompressionStream.Create(OutStream, Archive.CompressionLevel, Item.UncompressedSize);
try
CompStream.CopyFrom(ASource, Item.UncompressedSize);
finally
CompStream.Free;
end;
Item.CRC32 := not ASource.Hash;
finally
ASource.Free;
end;
end;
{ TZipHashStream }
constructor TZipHashStream.Create(ASource: TStream);

View file

@ -41,6 +41,7 @@
#define DM_SETPROGRESSVALUE DM_FIRST+37
#define DM_SETPROGRESSSTYLE DM_FIRST+38
#define DM_SETPASSWORDCHAR DM_FIRST+39
#define DM_LISTCLEAR DM_FIRST+40
/* events messages */
#define DN_FIRST 0x1000

View file

@ -44,6 +44,7 @@ const
DM_SETPROGRESSVALUE = DM_FIRST+37;
DM_SETPROGRESSSTYLE = DM_FIRST+38;
DM_SETPASSWORDCHAR = DM_FIRST+39;
DM_LISTCLEAR = DM_FIRST+40;
// events messages
DN_FIRST = $1000;

View file

@ -388,6 +388,15 @@ begin
else if Control is TMemo then
TMemo(Control).Lines[wParam]:= AText;
end;
DM_LISTCLEAR:
begin
if Control is TComboBox then
TComboBox(Control).Clear
else if Control is TListBox then
TListBox(Control).Clear
else if Control is TMemo then
TMemo(Control).Clear;
end;
DM_GETTEXT:
begin
with DialogBox do