mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-06 11:14:58 -06:00
2004 lines
49 KiB
C++
2004 lines
49 KiB
C++
// CompressDialog.cpp
|
|
|
|
#include "StdAfx.h"
|
|
|
|
#include "../../../../C/CpuArch.h"
|
|
|
|
#include "../../../Common/IntToString.h"
|
|
#include "../../../Common/StringConvert.h"
|
|
|
|
#include "../../../Windows/FileDir.h"
|
|
#include "../../../Windows/FileName.h"
|
|
#include "../../../Windows/System.h"
|
|
|
|
#include "../FileManager/BrowseDialog.h"
|
|
#include "../FileManager/FormatUtils.h"
|
|
#include "../FileManager/HelpUtils.h"
|
|
#include "../FileManager/SplitUtils.h"
|
|
|
|
#include "../Explorer/MyMessages.h"
|
|
|
|
#include "../Common/ZipRegistry.h"
|
|
|
|
#include "CompressDialog.h"
|
|
|
|
#ifndef _UNICODE
|
|
extern bool g_IsNT;
|
|
#endif
|
|
|
|
#ifdef LANG
|
|
#include "../FileManager/LangUtils.h"
|
|
#endif
|
|
|
|
#include "CompressDialogRes.h"
|
|
#include "ExtractRes.h"
|
|
|
|
#ifdef LANG
|
|
static const UInt32 kLangIDs[] =
|
|
{
|
|
IDT_COMPRESS_ARCHIVE,
|
|
IDT_COMPRESS_UPDATE_MODE,
|
|
IDT_COMPRESS_FORMAT,
|
|
IDT_COMPRESS_LEVEL,
|
|
IDT_COMPRESS_METHOD,
|
|
IDT_COMPRESS_DICTIONARY,
|
|
IDT_COMPRESS_ORDER,
|
|
IDT_COMPRESS_SOLID,
|
|
IDT_COMPRESS_THREADS,
|
|
IDT_COMPRESS_PARAMETERS,
|
|
|
|
IDG_COMPRESS_OPTIONS,
|
|
IDX_COMPRESS_SFX,
|
|
IDX_COMPRESS_SHARED,
|
|
IDX_COMPRESS_DEL,
|
|
|
|
IDT_COMPRESS_MEMORY,
|
|
IDT_COMPRESS_MEMORY_DE,
|
|
|
|
IDX_COMPRESS_NT_SYM_LINKS,
|
|
IDX_COMPRESS_NT_HARD_LINKS,
|
|
IDX_COMPRESS_NT_ALT_STREAMS,
|
|
IDX_COMPRESS_NT_SECUR,
|
|
|
|
IDG_COMPRESS_ENCRYPTION,
|
|
IDT_COMPRESS_ENCRYPTION_METHOD,
|
|
IDX_COMPRESS_ENCRYPT_FILE_NAMES,
|
|
|
|
IDT_PASSWORD_ENTER,
|
|
IDT_PASSWORD_REENTER,
|
|
IDX_PASSWORD_SHOW,
|
|
|
|
IDT_SPLIT_TO_VOLUMES,
|
|
IDT_COMPRESS_PATH_MODE
|
|
};
|
|
#endif
|
|
|
|
using namespace NWindows;
|
|
using namespace NFile;
|
|
using namespace NName;
|
|
using namespace NDir;
|
|
|
|
static const unsigned kHistorySize = 20;
|
|
|
|
static const UInt32 kNoSolidBlockSize = 0;
|
|
static const UInt32 kSolidBlockSize = 64;
|
|
|
|
static const UInt32 kLzmaMaxDictSize = (UInt32)15 << 28;
|
|
|
|
static LPCSTR const kExeExt = ".exe";
|
|
|
|
#define k7zFormat "7z"
|
|
|
|
static const UInt32 g_Levels[] =
|
|
{
|
|
IDS_METHOD_STORE,
|
|
IDS_METHOD_FASTEST,
|
|
0,
|
|
IDS_METHOD_FAST,
|
|
0,
|
|
IDS_METHOD_NORMAL,
|
|
0,
|
|
IDS_METHOD_MAXIMUM,
|
|
0,
|
|
IDS_METHOD_ULTRA
|
|
};
|
|
|
|
enum EMethodID
|
|
{
|
|
kCopy,
|
|
kLZMA,
|
|
kLZMA2,
|
|
kPPMd,
|
|
kBZip2,
|
|
kDeflate,
|
|
kDeflate64,
|
|
kPPMdZip
|
|
};
|
|
|
|
static LPCSTR const kMethodsNames[] =
|
|
{
|
|
"Copy"
|
|
, "LZMA"
|
|
, "LZMA2"
|
|
, "PPMd"
|
|
, "BZip2"
|
|
, "Deflate"
|
|
, "Deflate64"
|
|
, "PPMd"
|
|
};
|
|
|
|
static const EMethodID g_7zMethods[] =
|
|
{
|
|
kLZMA2,
|
|
kLZMA,
|
|
kPPMd,
|
|
kBZip2
|
|
};
|
|
|
|
static const EMethodID g_7zSfxMethods[] =
|
|
{
|
|
kCopy,
|
|
kLZMA,
|
|
kLZMA2,
|
|
kPPMd
|
|
};
|
|
|
|
static const EMethodID g_ZipMethods[] =
|
|
{
|
|
kDeflate,
|
|
kDeflate64,
|
|
kBZip2,
|
|
kLZMA,
|
|
kPPMdZip
|
|
};
|
|
|
|
static const EMethodID g_GZipMethods[] =
|
|
{
|
|
kDeflate
|
|
};
|
|
|
|
static const EMethodID g_BZip2Methods[] =
|
|
{
|
|
kBZip2
|
|
};
|
|
|
|
static const EMethodID g_XzMethods[] =
|
|
{
|
|
kLZMA2
|
|
};
|
|
|
|
static const EMethodID g_SwfcMethods[] =
|
|
{
|
|
kDeflate
|
|
// kLZMA
|
|
};
|
|
|
|
struct CFormatInfo
|
|
{
|
|
LPCSTR Name;
|
|
UInt32 LevelsMask;
|
|
unsigned NumMethods;
|
|
const EMethodID *MathodIDs;
|
|
bool Filter;
|
|
bool Solid;
|
|
bool MultiThread;
|
|
bool SFX;
|
|
|
|
bool Encrypt;
|
|
bool EncryptFileNames;
|
|
};
|
|
|
|
#define METHODS_PAIR(x) ARRAY_SIZE(x), x
|
|
|
|
static const CFormatInfo g_Formats[] =
|
|
{
|
|
{
|
|
"",
|
|
(1 << 0) | (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9),
|
|
0, 0,
|
|
false, false, false, false, false, false
|
|
},
|
|
{
|
|
k7zFormat,
|
|
(1 << 0) | (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9),
|
|
METHODS_PAIR(g_7zMethods),
|
|
true, true, true, true, true, true
|
|
},
|
|
{
|
|
"Zip",
|
|
(1 << 0) | (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9),
|
|
METHODS_PAIR(g_ZipMethods),
|
|
false, false, true, false, true, false
|
|
},
|
|
{
|
|
"GZip",
|
|
(1 << 1) | (1 << 5) | (1 << 7) | (1 << 9),
|
|
METHODS_PAIR(g_GZipMethods),
|
|
false, false, false, false, false, false
|
|
},
|
|
{
|
|
"BZip2",
|
|
(1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9),
|
|
METHODS_PAIR(g_BZip2Methods),
|
|
false, false, true, false, false, false
|
|
},
|
|
{
|
|
"xz",
|
|
(1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9),
|
|
METHODS_PAIR(g_XzMethods),
|
|
false, true, true, false, false, false
|
|
},
|
|
{
|
|
"Swfc",
|
|
(1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9),
|
|
METHODS_PAIR(g_SwfcMethods),
|
|
false, false, true, false, false, false
|
|
},
|
|
{
|
|
"Tar",
|
|
(1 << 0),
|
|
0, 0,
|
|
false, false, false, false, false, false
|
|
},
|
|
{
|
|
"wim",
|
|
(1 << 0),
|
|
0, 0,
|
|
false, false, false, false, false, false
|
|
}
|
|
};
|
|
|
|
static bool IsMethodSupportedBySfx(int methodID)
|
|
{
|
|
for (unsigned i = 0; i < ARRAY_SIZE(g_7zSfxMethods); i++)
|
|
if (methodID == g_7zSfxMethods[i])
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
static bool GetMaxRamSizeForProgram(UInt64 &ramSize, UInt64 &size)
|
|
{
|
|
size = (UInt64)(sizeof(size_t)) << 29;
|
|
bool ramSize_Defined = NSystem::GetRamSize(size);
|
|
ramSize = size;
|
|
size = size / 16 * 15;
|
|
const UInt64 kMinSysSize = (1 << 24);
|
|
if (size <= kMinSysSize)
|
|
size = 0;
|
|
else
|
|
size -= kMinSysSize;
|
|
const UInt64 kMinUseSize = (1 << 24);
|
|
if (size < kMinUseSize)
|
|
size = kMinUseSize;
|
|
return ramSize_Defined;
|
|
}
|
|
|
|
|
|
static const
|
|
// NCompressDialog::NUpdateMode::EEnum
|
|
int
|
|
k_UpdateMode_Vals[] =
|
|
{
|
|
NCompressDialog::NUpdateMode::kAdd,
|
|
NCompressDialog::NUpdateMode::kUpdate,
|
|
NCompressDialog::NUpdateMode::kFresh,
|
|
NCompressDialog::NUpdateMode::kSync
|
|
};
|
|
|
|
static const UInt32 k_UpdateMode_IDs[] =
|
|
{
|
|
IDS_COMPRESS_UPDATE_MODE_ADD,
|
|
IDS_COMPRESS_UPDATE_MODE_UPDATE,
|
|
IDS_COMPRESS_UPDATE_MODE_FRESH,
|
|
IDS_COMPRESS_UPDATE_MODE_SYNC
|
|
};
|
|
|
|
static const
|
|
// NWildcard::ECensorPathMode
|
|
int
|
|
k_PathMode_Vals[] =
|
|
{
|
|
NWildcard::k_RelatPath,
|
|
NWildcard::k_FullPath,
|
|
NWildcard::k_AbsPath,
|
|
};
|
|
|
|
static const UInt32 k_PathMode_IDs[] =
|
|
{
|
|
IDS_PATH_MODE_RELAT,
|
|
IDS_EXTRACT_PATHS_FULL,
|
|
IDS_EXTRACT_PATHS_ABS
|
|
};
|
|
|
|
void AddComboItems(NControl::CComboBox &combo, const UInt32 *langIDs, unsigned numItems, const int *values, int curVal);
|
|
bool GetBoolsVal(const CBoolPair &b1, const CBoolPair &b2);
|
|
|
|
void CCompressDialog::CheckButton_TwoBools(UINT id, const CBoolPair &b1, const CBoolPair &b2)
|
|
{
|
|
CheckButton(id, GetBoolsVal(b1, b2));
|
|
}
|
|
|
|
void CCompressDialog::GetButton_Bools(UINT id, CBoolPair &b1, CBoolPair &b2)
|
|
{
|
|
bool val = IsButtonCheckedBool(id);
|
|
bool oldVal = GetBoolsVal(b1, b2);
|
|
if (val != oldVal)
|
|
b1.Def = b2.Def = true;
|
|
b1.Val = b2.Val = val;
|
|
}
|
|
|
|
|
|
bool CCompressDialog::OnInit()
|
|
{
|
|
#ifdef LANG
|
|
LangSetWindowText(*this, IDD_COMPRESS);
|
|
LangSetDlgItems(*this, kLangIDs, ARRAY_SIZE(kLangIDs));
|
|
#endif
|
|
|
|
_password1Control.Attach(GetItem(IDE_COMPRESS_PASSWORD1));
|
|
_password2Control.Attach(GetItem(IDE_COMPRESS_PASSWORD2));
|
|
_password1Control.SetText(Info.Password);
|
|
_password2Control.SetText(Info.Password);
|
|
_encryptionMethod.Attach(GetItem(IDC_COMPRESS_ENCRYPTION_METHOD));
|
|
_default_encryptionMethod_Index = -1;
|
|
|
|
m_ArchivePath.Attach(GetItem(IDC_COMPRESS_ARCHIVE));
|
|
m_Format.Attach(GetItem(IDC_COMPRESS_FORMAT));
|
|
m_Level.Attach(GetItem(IDC_COMPRESS_LEVEL));
|
|
m_Method.Attach(GetItem(IDC_COMPRESS_METHOD));
|
|
m_Dictionary.Attach(GetItem(IDC_COMPRESS_DICTIONARY));
|
|
m_Order.Attach(GetItem(IDC_COMPRESS_ORDER));
|
|
m_Solid.Attach(GetItem(IDC_COMPRESS_SOLID));
|
|
m_NumThreads.Attach(GetItem(IDC_COMPRESS_THREADS));
|
|
|
|
m_UpdateMode.Attach(GetItem(IDC_COMPRESS_UPDATE_MODE));
|
|
m_PathMode.Attach(GetItem(IDC_COMPRESS_PATH_MODE));
|
|
|
|
m_Volume.Attach(GetItem(IDC_COMPRESS_VOLUME));
|
|
m_Params.Attach(GetItem(IDE_COMPRESS_PARAMETERS));
|
|
|
|
AddVolumeItems(m_Volume);
|
|
|
|
m_RegistryInfo.Load();
|
|
CheckButton(IDX_PASSWORD_SHOW, m_RegistryInfo.ShowPassword);
|
|
CheckButton(IDX_COMPRESS_ENCRYPT_FILE_NAMES, m_RegistryInfo.EncryptHeaders);
|
|
|
|
CheckButton_TwoBools(IDX_COMPRESS_NT_SYM_LINKS, Info.SymLinks, m_RegistryInfo.SymLinks);
|
|
CheckButton_TwoBools(IDX_COMPRESS_NT_HARD_LINKS, Info.HardLinks, m_RegistryInfo.HardLinks);
|
|
CheckButton_TwoBools(IDX_COMPRESS_NT_ALT_STREAMS, Info.AltStreams, m_RegistryInfo.AltStreams);
|
|
CheckButton_TwoBools(IDX_COMPRESS_NT_SECUR, Info.NtSecurity, m_RegistryInfo.NtSecurity);
|
|
|
|
UpdatePasswordControl();
|
|
|
|
{
|
|
bool needSetMain = (Info.FormatIndex < 0);
|
|
FOR_VECTOR(i, ArcIndices)
|
|
{
|
|
unsigned arcIndex = ArcIndices[i];
|
|
const CArcInfoEx &ai = (*ArcFormats)[arcIndex];
|
|
int index = (int)m_Format.AddString(ai.Name);
|
|
m_Format.SetItemData(index, arcIndex);
|
|
if (!needSetMain)
|
|
{
|
|
if (Info.FormatIndex == (int)arcIndex)
|
|
m_Format.SetCurSel(index);
|
|
continue;
|
|
}
|
|
if (i == 0 || ai.Name.IsEqualTo_NoCase(m_RegistryInfo.ArcType))
|
|
{
|
|
m_Format.SetCurSel(index);
|
|
Info.FormatIndex = arcIndex;
|
|
}
|
|
}
|
|
}
|
|
|
|
CheckButton(IDX_COMPRESS_SFX, Info.SFXMode);
|
|
|
|
{
|
|
UString fileName;
|
|
SetArcPathFields(Info.ArcPath, fileName, true);
|
|
StartDirPrefix = DirPrefix;
|
|
SetArchiveName(fileName);
|
|
}
|
|
SetLevel();
|
|
SetParams();
|
|
|
|
for (unsigned i = 0; i < m_RegistryInfo.ArcPaths.Size() && i < kHistorySize; i++)
|
|
m_ArchivePath.AddString(m_RegistryInfo.ArcPaths[i]);
|
|
|
|
AddComboItems(m_UpdateMode, k_UpdateMode_IDs, ARRAY_SIZE(k_UpdateMode_IDs),
|
|
k_UpdateMode_Vals, Info.UpdateMode);
|
|
|
|
AddComboItems(m_PathMode, k_PathMode_IDs, ARRAY_SIZE(k_PathMode_IDs),
|
|
k_PathMode_Vals, Info.PathMode);
|
|
|
|
SetSolidBlockSize();
|
|
SetNumThreads();
|
|
|
|
TCHAR s[32] = { TEXT('/'), TEXT(' '), 0 };
|
|
ConvertUInt32ToString(NSystem::GetNumberOfProcessors(), s + 2);
|
|
SetItemText(IDT_COMPRESS_HARDWARE_THREADS, s);
|
|
|
|
CheckButton(IDX_COMPRESS_SHARED, Info.OpenShareForWrite);
|
|
CheckButton(IDX_COMPRESS_DEL, Info.DeleteAfterCompressing);
|
|
|
|
CheckControlsEnable();
|
|
|
|
// OnButtonSFX();
|
|
|
|
SetEncryptionMethod();
|
|
SetMemoryUsage();
|
|
|
|
NormalizePosition();
|
|
|
|
return CModalDialog::OnInit();
|
|
}
|
|
|
|
/*
|
|
namespace NCompressDialog
|
|
{
|
|
bool CInfo::GetFullPathName(UString &result) const
|
|
{
|
|
#ifndef UNDER_CE
|
|
// NDirectory::MySetCurrentDirectory(CurrentDirPrefix);
|
|
#endif
|
|
FString resultF;
|
|
bool res = MyGetFullPathName(us2fs(ArchiveName), resultF);
|
|
result = fs2us(resultF);
|
|
return res;
|
|
}
|
|
}
|
|
*/
|
|
|
|
void CCompressDialog::UpdatePasswordControl()
|
|
{
|
|
bool showPassword = IsShowPasswordChecked();
|
|
TCHAR c = showPassword ? (TCHAR)0: TEXT('*');
|
|
_password1Control.SetPasswordChar(c);
|
|
_password2Control.SetPasswordChar(c);
|
|
UString password;
|
|
_password1Control.GetText(password);
|
|
_password1Control.SetText(password);
|
|
_password2Control.GetText(password);
|
|
_password2Control.SetText(password);
|
|
|
|
ShowItem_Bool(IDT_PASSWORD_REENTER, !showPassword);
|
|
_password2Control.Show_Bool(!showPassword);
|
|
}
|
|
|
|
bool CCompressDialog::OnButtonClicked(int buttonID, HWND buttonHWND)
|
|
{
|
|
switch (buttonID)
|
|
{
|
|
case IDB_COMPRESS_SET_ARCHIVE:
|
|
{
|
|
OnButtonSetArchive();
|
|
return true;
|
|
}
|
|
case IDX_COMPRESS_SFX:
|
|
{
|
|
SetMethod(GetMethodID());
|
|
OnButtonSFX();
|
|
SetMemoryUsage();
|
|
return true;
|
|
}
|
|
case IDX_PASSWORD_SHOW:
|
|
{
|
|
UpdatePasswordControl();
|
|
return true;
|
|
}
|
|
}
|
|
return CModalDialog::OnButtonClicked(buttonID, buttonHWND);
|
|
}
|
|
|
|
void CCompressDialog::CheckSFXControlsEnable()
|
|
{
|
|
const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()];
|
|
bool enable = fi.SFX;
|
|
if (enable)
|
|
{
|
|
int methodID = GetMethodID();
|
|
enable = (methodID == -1 || IsMethodSupportedBySfx(methodID));
|
|
}
|
|
if (!enable)
|
|
CheckButton(IDX_COMPRESS_SFX, false);
|
|
EnableItem(IDX_COMPRESS_SFX, enable);
|
|
}
|
|
|
|
/*
|
|
void CCompressDialog::CheckVolumeEnable()
|
|
{
|
|
bool isSFX = IsSFX();
|
|
m_Volume.Enable(!isSFX);
|
|
if (isSFX)
|
|
m_Volume.SetText(TEXT(""));
|
|
}
|
|
*/
|
|
|
|
void CCompressDialog::CheckControlsEnable()
|
|
{
|
|
const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()];
|
|
Info.SolidIsSpecified = fi.Solid;
|
|
bool multiThreadEnable = fi.MultiThread;
|
|
Info.MultiThreadIsAllowed = multiThreadEnable;
|
|
Info.EncryptHeadersIsAllowed = fi.EncryptFileNames;
|
|
|
|
EnableItem(IDC_COMPRESS_SOLID, fi.Solid);
|
|
EnableItem(IDC_COMPRESS_THREADS, multiThreadEnable);
|
|
|
|
CheckSFXControlsEnable();
|
|
|
|
{
|
|
const CArcInfoEx &ai = (*ArcFormats)[GetFormatIndex()];
|
|
|
|
ShowItem_Bool(IDX_COMPRESS_NT_SYM_LINKS, ai.Flags_SymLinks());
|
|
ShowItem_Bool(IDX_COMPRESS_NT_HARD_LINKS, ai.Flags_HardLinks());
|
|
ShowItem_Bool(IDX_COMPRESS_NT_ALT_STREAMS, ai.Flags_AltStreams());
|
|
ShowItem_Bool(IDX_COMPRESS_NT_SECUR, ai.Flags_NtSecure());
|
|
|
|
ShowItem_Bool(IDG_COMPRESS_NTFS,
|
|
ai.Flags_SymLinks()
|
|
|| ai.Flags_HardLinks()
|
|
|| ai.Flags_AltStreams()
|
|
|| ai.Flags_NtSecure());
|
|
}
|
|
// CheckVolumeEnable();
|
|
|
|
EnableItem(IDG_COMPRESS_ENCRYPTION, fi.Encrypt);
|
|
|
|
EnableItem(IDT_PASSWORD_ENTER, fi.Encrypt);
|
|
EnableItem(IDT_PASSWORD_REENTER, fi.Encrypt);
|
|
EnableItem(IDE_COMPRESS_PASSWORD1, fi.Encrypt);
|
|
EnableItem(IDE_COMPRESS_PASSWORD2, fi.Encrypt);
|
|
EnableItem(IDX_PASSWORD_SHOW, fi.Encrypt);
|
|
|
|
EnableItem(IDT_COMPRESS_ENCRYPTION_METHOD, fi.Encrypt);
|
|
EnableItem(IDC_COMPRESS_ENCRYPTION_METHOD, fi.Encrypt);
|
|
EnableItem(IDX_COMPRESS_ENCRYPT_FILE_NAMES, fi.EncryptFileNames);
|
|
|
|
ShowItem_Bool(IDX_COMPRESS_ENCRYPT_FILE_NAMES, fi.EncryptFileNames);
|
|
}
|
|
|
|
bool CCompressDialog::IsSFX()
|
|
{
|
|
CWindow sfxButton = GetItem(IDX_COMPRESS_SFX);
|
|
return sfxButton.IsEnabled() && IsButtonCheckedBool(IDX_COMPRESS_SFX);
|
|
}
|
|
|
|
static int GetExtDotPos(const UString &s)
|
|
{
|
|
int dotPos = s.ReverseFind_Dot();
|
|
if (dotPos > s.ReverseFind_PathSepar() + 1)
|
|
return dotPos;
|
|
return -1;
|
|
}
|
|
|
|
void CCompressDialog::OnButtonSFX()
|
|
{
|
|
UString fileName;
|
|
m_ArchivePath.GetText(fileName);
|
|
int dotPos = GetExtDotPos(fileName);
|
|
if (IsSFX())
|
|
{
|
|
if (dotPos >= 0)
|
|
fileName.DeleteFrom(dotPos);
|
|
fileName += kExeExt;
|
|
m_ArchivePath.SetText(fileName);
|
|
}
|
|
else
|
|
{
|
|
if (dotPos >= 0)
|
|
{
|
|
UString ext = fileName.Ptr(dotPos);
|
|
if (ext.IsEqualTo_Ascii_NoCase(kExeExt))
|
|
{
|
|
fileName.DeleteFrom(dotPos);
|
|
m_ArchivePath.SetText(fileName);
|
|
}
|
|
}
|
|
SetArchiveName2(false); // it's for OnInit
|
|
}
|
|
|
|
// CheckVolumeEnable();
|
|
}
|
|
|
|
bool CCompressDialog::GetFinalPath_Smart(UString &resPath)
|
|
{
|
|
UString name;
|
|
m_ArchivePath.GetText(name);
|
|
name.Trim();
|
|
UString tempPath = name;
|
|
if (!IsAbsolutePath(name))
|
|
{
|
|
UString newDirPrefix = DirPrefix;
|
|
if (newDirPrefix.IsEmpty())
|
|
newDirPrefix = StartDirPrefix;
|
|
FString resultF;
|
|
if (!MyGetFullPathName(us2fs(newDirPrefix + name), resultF))
|
|
return false;
|
|
tempPath = fs2us(resultF);
|
|
}
|
|
if (!SetArcPathFields(tempPath, name, false))
|
|
return false;
|
|
FString resultF;
|
|
if (!MyGetFullPathName(us2fs(DirPrefix + name), resultF))
|
|
return false;
|
|
resPath = fs2us(resultF);
|
|
return true;
|
|
}
|
|
|
|
bool CCompressDialog::SetArcPathFields(const UString &path, UString &name, bool always)
|
|
{
|
|
FString resDirPrefix;
|
|
FString resFileName;
|
|
bool res = GetFullPathAndSplit(us2fs(path), resDirPrefix, resFileName);
|
|
if (res)
|
|
{
|
|
DirPrefix = fs2us(resDirPrefix);
|
|
name = fs2us(resFileName);
|
|
}
|
|
else
|
|
{
|
|
if (!always)
|
|
return false;
|
|
DirPrefix.Empty();
|
|
name = path;
|
|
}
|
|
SetItemText(IDT_COMPRESS_ARCHIVE_FOLDER, DirPrefix);
|
|
m_ArchivePath.SetText(name);
|
|
return res;
|
|
}
|
|
|
|
static const wchar_t * const k_IncorrectPathMessage = L"Incorrect archive path";
|
|
|
|
void CCompressDialog::OnButtonSetArchive()
|
|
{
|
|
UString path;
|
|
if (!GetFinalPath_Smart(path))
|
|
{
|
|
ShowErrorMessage(*this, k_IncorrectPathMessage);
|
|
return;
|
|
}
|
|
|
|
UString title = LangString(IDS_COMPRESS_SET_ARCHIVE_BROWSE);
|
|
UString filterDescription = LangString(IDS_OPEN_TYPE_ALL_FILES);
|
|
filterDescription += " (*.*)";
|
|
UString resPath;
|
|
CurrentDirWasChanged = true;
|
|
if (!MyBrowseForFile(*this, title,
|
|
// DirPrefix.IsEmpty() ? NULL : (const wchar_t *)DirPrefix,
|
|
// NULL,
|
|
path,
|
|
filterDescription,
|
|
NULL, // L"*.*",
|
|
resPath))
|
|
return;
|
|
UString dummyName;
|
|
SetArcPathFields(resPath, dummyName, true);
|
|
}
|
|
|
|
// in ExtractDialog.cpp
|
|
extern void AddUniqueString(UStringVector &strings, const UString &srcString);
|
|
|
|
static bool IsAsciiString(const UString &s)
|
|
{
|
|
for (unsigned i = 0; i < s.Len(); i++)
|
|
{
|
|
wchar_t c = s[i];
|
|
if (c < 0x20 || c > 0x7F)
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
static void AddSize_MB(UString &s, UInt64 size)
|
|
{
|
|
char temp[32];
|
|
ConvertUInt64ToString((size + (1 << 20) - 1) >> 20, temp);
|
|
s += temp;
|
|
s += " MB";
|
|
}
|
|
|
|
|
|
void SetErrorMessage_MemUsage(UString &s, UInt64 reqSize, UInt64 ramSize, UInt64 ramLimit, const UString &usageString)
|
|
{
|
|
s += "The operation was blocked by 7-Zip";
|
|
s.Add_LF();
|
|
s += "The operation can require big amount of RAM (memory):";
|
|
s.Add_LF();
|
|
s.Add_LF();
|
|
AddSize_MB(s, reqSize);
|
|
|
|
if (!usageString.IsEmpty())
|
|
{
|
|
s += " : ";
|
|
s += usageString;
|
|
}
|
|
|
|
s.Add_LF();
|
|
AddSize_MB(s, ramSize);
|
|
s += " : RAM";
|
|
|
|
if (ramLimit != 0)
|
|
{
|
|
s.Add_LF();
|
|
AddSize_MB(s, ramLimit);
|
|
s += " : 7-Zip limit";
|
|
}
|
|
|
|
s.Add_LF();
|
|
s.Add_LF();
|
|
s += LangString(IDS_MEM_ERROR);
|
|
}
|
|
|
|
|
|
void CCompressDialog::OnOK()
|
|
{
|
|
_password1Control.GetText(Info.Password);
|
|
if (IsZipFormat())
|
|
{
|
|
if (!IsAsciiString(Info.Password))
|
|
{
|
|
ShowErrorMessageHwndRes(*this, IDS_PASSWORD_USE_ASCII);
|
|
return;
|
|
}
|
|
UString method = GetEncryptionMethodSpec();
|
|
if (method.IsPrefixedBy_Ascii_NoCase("aes"))
|
|
{
|
|
if (Info.Password.Len() > 99)
|
|
{
|
|
ShowErrorMessageHwndRes(*this, IDS_PASSWORD_TOO_LONG);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
if (!IsShowPasswordChecked())
|
|
{
|
|
UString password2;
|
|
_password2Control.GetText(password2);
|
|
if (password2 != Info.Password)
|
|
{
|
|
ShowErrorMessageHwndRes(*this, IDS_PASSWORD_NOT_MATCH);
|
|
return;
|
|
}
|
|
}
|
|
|
|
{
|
|
UInt64 ramSize;
|
|
UInt64 maxRamSize;
|
|
const bool maxRamSize_Defined = GetMaxRamSizeForProgram(ramSize, maxRamSize);
|
|
UInt64 decompressMem;
|
|
const UInt64 memUsage = GetMemoryUsage_DecompMem(decompressMem);
|
|
if (maxRamSize_Defined && memUsage > maxRamSize)
|
|
{
|
|
UString s;
|
|
UString s2 = LangString(IDT_COMPRESS_MEMORY);
|
|
if (s2.IsEmpty())
|
|
GetItemText(IDT_COMPRESS_MEMORY, s2);
|
|
SetErrorMessage_MemUsage(s, memUsage, ramSize, maxRamSize, s2);
|
|
MessageBoxError(s);
|
|
return;
|
|
}
|
|
}
|
|
|
|
SaveOptionsInMem();
|
|
{
|
|
UString s;
|
|
if (!GetFinalPath_Smart(s))
|
|
{
|
|
ShowErrorMessage(*this, k_IncorrectPathMessage);
|
|
return;
|
|
}
|
|
|
|
m_RegistryInfo.ArcPaths.Clear();
|
|
AddUniqueString(m_RegistryInfo.ArcPaths, s);
|
|
Info.ArcPath = s;
|
|
}
|
|
|
|
Info.UpdateMode = (NCompressDialog::NUpdateMode::EEnum)k_UpdateMode_Vals[m_UpdateMode.GetCurSel()];;
|
|
Info.PathMode = (NWildcard::ECensorPathMode)k_PathMode_Vals[m_PathMode.GetCurSel()];
|
|
|
|
Info.Level = GetLevelSpec();
|
|
Info.Dict64 = GetDictSpec();
|
|
Info.Order = GetOrderSpec();
|
|
Info.OrderMode = GetOrderMode();
|
|
Info.NumThreads = GetNumThreadsSpec();
|
|
|
|
{
|
|
// Info.SolidIsSpecified = g_Formats[GetStaticFormatIndex()].Solid;
|
|
UInt32 solidLogSize = GetBlockSizeSpec();
|
|
Info.SolidBlockSize = 0;
|
|
if (solidLogSize == (UInt32)(Int32)-1)
|
|
Info.SolidIsSpecified = false;
|
|
else if (solidLogSize > 0)
|
|
Info.SolidBlockSize = (solidLogSize >= 64) ?
|
|
(UInt64)(Int64)-1 :
|
|
((UInt64)1 << solidLogSize);
|
|
}
|
|
|
|
Info.Method = GetMethodSpec();
|
|
Info.EncryptionMethod = GetEncryptionMethodSpec();
|
|
Info.FormatIndex = GetFormatIndex();
|
|
Info.SFXMode = IsSFX();
|
|
Info.OpenShareForWrite = IsButtonCheckedBool(IDX_COMPRESS_SHARED);
|
|
Info.DeleteAfterCompressing = IsButtonCheckedBool(IDX_COMPRESS_DEL);
|
|
|
|
m_RegistryInfo.EncryptHeaders =
|
|
Info.EncryptHeaders = IsButtonCheckedBool(IDX_COMPRESS_ENCRYPT_FILE_NAMES);
|
|
|
|
|
|
GetButton_Bools(IDX_COMPRESS_NT_SYM_LINKS, Info.SymLinks, m_RegistryInfo.SymLinks);
|
|
GetButton_Bools(IDX_COMPRESS_NT_HARD_LINKS, Info.HardLinks, m_RegistryInfo.HardLinks);
|
|
GetButton_Bools(IDX_COMPRESS_NT_ALT_STREAMS, Info.AltStreams, m_RegistryInfo.AltStreams);
|
|
GetButton_Bools(IDX_COMPRESS_NT_SECUR, Info.NtSecurity, m_RegistryInfo.NtSecurity);
|
|
|
|
{
|
|
const CArcInfoEx &ai = (*ArcFormats)[GetFormatIndex()];
|
|
if (!ai.Flags_SymLinks()) Info.SymLinks.Val = false;
|
|
if (!ai.Flags_HardLinks()) Info.HardLinks.Val = false;
|
|
if (!ai.Flags_AltStreams()) Info.AltStreams.Val = false;
|
|
if (!ai.Flags_NtSecure()) Info.NtSecurity.Val = false;
|
|
}
|
|
|
|
m_Params.GetText(Info.Options);
|
|
|
|
UString volumeString;
|
|
m_Volume.GetText(volumeString);
|
|
volumeString.Trim();
|
|
Info.VolumeSizes.Clear();
|
|
|
|
if (!volumeString.IsEmpty())
|
|
{
|
|
if (!ParseVolumeSizes(volumeString, Info.VolumeSizes))
|
|
{
|
|
ShowErrorMessageHwndRes(*this, IDS_INCORRECT_VOLUME_SIZE);
|
|
return;
|
|
}
|
|
if (!Info.VolumeSizes.IsEmpty())
|
|
{
|
|
const UInt64 volumeSize = Info.VolumeSizes.Back();
|
|
if (volumeSize < (100 << 10))
|
|
{
|
|
wchar_t s[32];
|
|
ConvertUInt64ToString(volumeSize, s);
|
|
if (::MessageBoxW(*this, MyFormatNew(IDS_SPLIT_CONFIRM, s),
|
|
L"7-Zip", MB_YESNOCANCEL | MB_ICONQUESTION) != IDYES)
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < m_ArchivePath.GetCount(); i++)
|
|
{
|
|
UString sTemp;
|
|
m_ArchivePath.GetLBText(i, sTemp);
|
|
sTemp.Trim();
|
|
AddUniqueString(m_RegistryInfo.ArcPaths, sTemp);
|
|
}
|
|
|
|
if (m_RegistryInfo.ArcPaths.Size() > kHistorySize)
|
|
m_RegistryInfo.ArcPaths.DeleteBack();
|
|
|
|
if (Info.FormatIndex >= 0)
|
|
m_RegistryInfo.ArcType = (*ArcFormats)[Info.FormatIndex].Name;
|
|
m_RegistryInfo.ShowPassword = IsShowPasswordChecked();
|
|
|
|
m_RegistryInfo.Save();
|
|
|
|
CModalDialog::OnOK();
|
|
}
|
|
|
|
#define kHelpTopic "fm/plugins/7-zip/add.htm"
|
|
|
|
void CCompressDialog::OnHelp()
|
|
{
|
|
ShowHelpWindow(kHelpTopic);
|
|
}
|
|
|
|
bool CCompressDialog::OnCommand(int code, int itemID, LPARAM lParam)
|
|
{
|
|
if (code == CBN_SELCHANGE)
|
|
{
|
|
switch (itemID)
|
|
{
|
|
case IDC_COMPRESS_ARCHIVE:
|
|
{
|
|
// we can 't change m_ArchivePath in that handler !
|
|
DirPrefix.Empty();
|
|
SetItemText(IDT_COMPRESS_ARCHIVE_FOLDER, DirPrefix);
|
|
|
|
/*
|
|
UString path;
|
|
m_ArchivePath.GetText(path);
|
|
m_ArchivePath.SetText(L"");
|
|
if (IsAbsolutePath(path))
|
|
{
|
|
UString fileName;
|
|
SetArcPathFields(path, fileName);
|
|
SetArchiveName(fileName);
|
|
}
|
|
*/
|
|
return true;
|
|
}
|
|
|
|
case IDC_COMPRESS_FORMAT:
|
|
{
|
|
bool isSFX = IsSFX();
|
|
SaveOptionsInMem();
|
|
m_Solid.ResetContent();
|
|
SetLevel();
|
|
SetSolidBlockSize();
|
|
SetNumThreads();
|
|
SetParams();
|
|
CheckControlsEnable();
|
|
SetArchiveName2(isSFX);
|
|
SetEncryptionMethod();
|
|
SetMemoryUsage();
|
|
return true;
|
|
}
|
|
|
|
case IDC_COMPRESS_LEVEL:
|
|
{
|
|
{
|
|
const CArcInfoEx &ai = (*ArcFormats)[GetFormatIndex()];
|
|
int index = FindRegistryFormatAlways(ai.Name);
|
|
NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index];
|
|
fo.ResetForLevelChange();
|
|
}
|
|
|
|
SetMethod();
|
|
SetSolidBlockSize();
|
|
SetNumThreads();
|
|
CheckSFXNameChange();
|
|
SetMemoryUsage();
|
|
return true;
|
|
}
|
|
|
|
case IDC_COMPRESS_METHOD:
|
|
{
|
|
SetDictionary();
|
|
SetOrder();
|
|
SetSolidBlockSize();
|
|
SetNumThreads();
|
|
CheckSFXNameChange();
|
|
SetMemoryUsage();
|
|
return true;
|
|
}
|
|
|
|
case IDC_COMPRESS_DICTIONARY:
|
|
{
|
|
UInt32 blockSizeLog = GetBlockSizeSpec();
|
|
if (blockSizeLog != (UInt32)(Int32)-1
|
|
&& blockSizeLog != kNoSolidBlockSize
|
|
&& blockSizeLog != kSolidBlockSize)
|
|
{
|
|
const CArcInfoEx &ai = (*ArcFormats)[GetFormatIndex()];
|
|
int index = FindRegistryFormatAlways(ai.Name);
|
|
NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index];
|
|
fo.Reset_BlockLogSize();
|
|
SetSolidBlockSize(true);
|
|
}
|
|
|
|
SetMemoryUsage();
|
|
return true;
|
|
}
|
|
|
|
case IDC_COMPRESS_ORDER:
|
|
return true;
|
|
|
|
case IDC_COMPRESS_SOLID:
|
|
{
|
|
SetMemoryUsage();
|
|
return true;
|
|
}
|
|
|
|
case IDC_COMPRESS_THREADS:
|
|
{
|
|
SetMemoryUsage();
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return CModalDialog::OnCommand(code, itemID, lParam);
|
|
}
|
|
|
|
void CCompressDialog::CheckSFXNameChange()
|
|
{
|
|
bool isSFX = IsSFX();
|
|
CheckSFXControlsEnable();
|
|
if (isSFX != IsSFX())
|
|
SetArchiveName2(isSFX);
|
|
}
|
|
|
|
void CCompressDialog::SetArchiveName2(bool prevWasSFX)
|
|
{
|
|
UString fileName;
|
|
m_ArchivePath.GetText(fileName);
|
|
const CArcInfoEx &prevArchiverInfo = (*ArcFormats)[m_PrevFormat];
|
|
if (prevArchiverInfo.Flags_KeepName() || Info.KeepName)
|
|
{
|
|
UString prevExtension;
|
|
if (prevWasSFX)
|
|
prevExtension = kExeExt;
|
|
else
|
|
{
|
|
prevExtension += '.';
|
|
prevExtension += prevArchiverInfo.GetMainExt();
|
|
}
|
|
const unsigned prevExtensionLen = prevExtension.Len();
|
|
if (fileName.Len() >= prevExtensionLen)
|
|
if (StringsAreEqualNoCase(fileName.RightPtr(prevExtensionLen), prevExtension))
|
|
fileName.DeleteFrom(fileName.Len() - prevExtensionLen);
|
|
}
|
|
SetArchiveName(fileName);
|
|
}
|
|
|
|
// if type.KeepName then use OriginalFileName
|
|
// else if !KeepName remove extension
|
|
// add new extension
|
|
|
|
void CCompressDialog::SetArchiveName(const UString &name)
|
|
{
|
|
UString fileName = name;
|
|
Info.FormatIndex = GetFormatIndex();
|
|
const CArcInfoEx &ai = (*ArcFormats)[Info.FormatIndex];
|
|
m_PrevFormat = Info.FormatIndex;
|
|
if (ai.Flags_KeepName())
|
|
{
|
|
fileName = OriginalFileName;
|
|
}
|
|
else
|
|
{
|
|
if (!Info.KeepName)
|
|
{
|
|
int dotPos = GetExtDotPos(fileName);
|
|
if (dotPos >= 0)
|
|
fileName.DeleteFrom(dotPos);
|
|
}
|
|
}
|
|
|
|
if (IsSFX())
|
|
fileName += kExeExt;
|
|
else
|
|
{
|
|
fileName += '.';
|
|
fileName += ai.GetMainExt();
|
|
}
|
|
m_ArchivePath.SetText(fileName);
|
|
}
|
|
|
|
int CCompressDialog::FindRegistryFormat(const UString &name)
|
|
{
|
|
FOR_VECTOR (i, m_RegistryInfo.Formats)
|
|
{
|
|
const NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[i];
|
|
if (name.IsEqualTo_NoCase(GetUnicodeString(fo.FormatID)))
|
|
return i;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
int CCompressDialog::FindRegistryFormatAlways(const UString &name)
|
|
{
|
|
int index = FindRegistryFormat(name);
|
|
if (index < 0)
|
|
{
|
|
NCompression::CFormatOptions fo;
|
|
fo.FormatID = GetSystemString(name);
|
|
index = m_RegistryInfo.Formats.Add(fo);
|
|
}
|
|
return index;
|
|
}
|
|
|
|
int CCompressDialog::GetStaticFormatIndex()
|
|
{
|
|
const CArcInfoEx &ai = (*ArcFormats)[GetFormatIndex()];
|
|
for (unsigned i = 0; i < ARRAY_SIZE(g_Formats); i++)
|
|
if (ai.Name.IsEqualTo_Ascii_NoCase(g_Formats[i].Name))
|
|
return i;
|
|
return 0; // -1;
|
|
}
|
|
|
|
void CCompressDialog::SetNearestSelectComboBox(NControl::CComboBox &comboBox, UInt32 value)
|
|
{
|
|
for (int i = comboBox.GetCount() - 1; i >= 0; i--)
|
|
if ((UInt32)comboBox.GetItemData(i) <= value)
|
|
{
|
|
comboBox.SetCurSel(i);
|
|
return;
|
|
}
|
|
if (comboBox.GetCount() > 0)
|
|
comboBox.SetCurSel(0);
|
|
}
|
|
|
|
void CCompressDialog::SetLevel()
|
|
{
|
|
m_Level.ResetContent();
|
|
const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()];
|
|
const CArcInfoEx &ai = (*ArcFormats)[GetFormatIndex()];
|
|
UInt32 level = 5;
|
|
{
|
|
int index = FindRegistryFormat(ai.Name);
|
|
if (index >= 0)
|
|
{
|
|
const NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index];
|
|
if (fo.Level <= 9)
|
|
level = fo.Level;
|
|
else if (fo.Level == (UInt32)(Int32)-1)
|
|
level = 5;
|
|
else
|
|
level = 9;
|
|
}
|
|
}
|
|
|
|
for (unsigned i = 0; i <= 9; i++)
|
|
{
|
|
if ((fi.LevelsMask & (1 << i)) != 0)
|
|
{
|
|
UInt32 langID = g_Levels[i];
|
|
int index = (int)m_Level.AddString(LangString(langID));
|
|
m_Level.SetItemData(index, i);
|
|
}
|
|
}
|
|
SetNearestSelectComboBox(m_Level, level);
|
|
SetMethod();
|
|
}
|
|
|
|
|
|
static LRESULT ComboBox_AddStringAscii(NControl::CComboBox &cb, const char *s)
|
|
{
|
|
return cb.AddString((CSysString)s);
|
|
}
|
|
|
|
|
|
void CCompressDialog::SetMethod(int keepMethodId)
|
|
{
|
|
m_Method.ResetContent();
|
|
UInt32 level = GetLevel();
|
|
if (level == 0)
|
|
{
|
|
SetDictionary();
|
|
SetOrder();
|
|
return;
|
|
}
|
|
const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()];
|
|
const CArcInfoEx &ai = (*ArcFormats)[GetFormatIndex()];
|
|
int index = FindRegistryFormat(ai.Name);
|
|
UString defaultMethod;
|
|
if (index >= 0)
|
|
{
|
|
const NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index];
|
|
defaultMethod = fo.Method;
|
|
}
|
|
bool isSfx = IsSFX();
|
|
bool weUseSameMethod = false;
|
|
|
|
for (unsigned m = 0; m < fi.NumMethods; m++)
|
|
{
|
|
EMethodID methodID = fi.MathodIDs[m];
|
|
if (isSfx)
|
|
if (!IsMethodSupportedBySfx(methodID))
|
|
continue;
|
|
const char *method = kMethodsNames[methodID];
|
|
int itemIndex = (int)ComboBox_AddStringAscii(m_Method, method);
|
|
m_Method.SetItemData(itemIndex, methodID);
|
|
if (keepMethodId == methodID)
|
|
{
|
|
m_Method.SetCurSel(itemIndex);
|
|
weUseSameMethod = true;
|
|
continue;
|
|
}
|
|
if ((defaultMethod.IsEqualTo_Ascii_NoCase(method) || m == 0) && !weUseSameMethod)
|
|
m_Method.SetCurSel(itemIndex);
|
|
}
|
|
|
|
if (!weUseSameMethod)
|
|
{
|
|
SetDictionary();
|
|
SetOrder();
|
|
}
|
|
}
|
|
|
|
bool CCompressDialog::IsZipFormat()
|
|
{
|
|
const CArcInfoEx &ai = (*ArcFormats)[GetFormatIndex()];
|
|
return ai.Name.IsEqualTo_Ascii_NoCase("zip");
|
|
}
|
|
|
|
bool CCompressDialog::IsXzFormat()
|
|
{
|
|
const CArcInfoEx &ai = (*ArcFormats)[GetFormatIndex()];
|
|
return ai.Name.IsEqualTo_Ascii_NoCase("xz");
|
|
}
|
|
|
|
void CCompressDialog::SetEncryptionMethod()
|
|
{
|
|
_encryptionMethod.ResetContent();
|
|
_default_encryptionMethod_Index = -1;
|
|
const CArcInfoEx &ai = (*ArcFormats)[GetFormatIndex()];
|
|
if (ai.Name.IsEqualTo_Ascii_NoCase("7z"))
|
|
{
|
|
ComboBox_AddStringAscii(_encryptionMethod, "AES-256");
|
|
_encryptionMethod.SetCurSel(0);
|
|
_default_encryptionMethod_Index = 0;
|
|
}
|
|
else if (ai.Name.IsEqualTo_Ascii_NoCase("zip"))
|
|
{
|
|
int index = FindRegistryFormat(ai.Name);
|
|
UString encryptionMethod;
|
|
if (index >= 0)
|
|
{
|
|
const NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index];
|
|
encryptionMethod = fo.EncryptionMethod;
|
|
}
|
|
int sel = 0;
|
|
// if (ZipCryptoIsAllowed)
|
|
{
|
|
ComboBox_AddStringAscii(_encryptionMethod, "ZipCrypto");
|
|
sel = (encryptionMethod.IsPrefixedBy_Ascii_NoCase("aes") ? 1 : 0);
|
|
_default_encryptionMethod_Index = 0;
|
|
}
|
|
ComboBox_AddStringAscii(_encryptionMethod, "AES-256");
|
|
_encryptionMethod.SetCurSel(sel);
|
|
}
|
|
}
|
|
|
|
int CCompressDialog::GetMethodID()
|
|
{
|
|
if (m_Method.GetCount() <= 0)
|
|
return -1;
|
|
return (int)(UInt32)m_Method.GetItemData_of_CurSel();
|
|
}
|
|
|
|
UString CCompressDialog::GetMethodSpec()
|
|
{
|
|
UString s;
|
|
if (m_Method.GetCount() > 1)
|
|
s = kMethodsNames[GetMethodID()];
|
|
return s;
|
|
}
|
|
|
|
UString CCompressDialog::GetEncryptionMethodSpec()
|
|
{
|
|
UString s;
|
|
if (_encryptionMethod.GetCount() > 0
|
|
&& _encryptionMethod.GetCurSel() != _default_encryptionMethod_Index)
|
|
{
|
|
_encryptionMethod.GetText(s);
|
|
s.RemoveChar(L'-');
|
|
}
|
|
return s;
|
|
}
|
|
|
|
|
|
void CCompressDialog::AddDict2(size_t sizeReal, size_t sizeShow)
|
|
{
|
|
Byte c = 0;
|
|
unsigned moveBits = 0;
|
|
if ((sizeShow & 0xFFFFF) == 0) { moveBits = 20; c = 'M'; }
|
|
else if ((sizeShow & 0x3FF) == 0) { moveBits = 10; c = 'K'; }
|
|
TCHAR s[32];
|
|
ConvertUInt64ToString(sizeShow >> moveBits, s);
|
|
unsigned pos = MyStringLen(s);
|
|
s[pos++] = ' ';
|
|
if (moveBits != 0)
|
|
s[pos++] = c;
|
|
s[pos++] = 'B';
|
|
s[pos++] = 0;
|
|
const int index = (int)m_Dictionary.AddString(s);
|
|
m_Dictionary.SetItemData(index, sizeReal);
|
|
}
|
|
|
|
|
|
void CCompressDialog::AddDict(size_t size)
|
|
{
|
|
AddDict2(size, size);
|
|
}
|
|
|
|
|
|
void CCompressDialog::SetDictionary()
|
|
{
|
|
m_Dictionary.ResetContent();
|
|
const CArcInfoEx &ai = (*ArcFormats)[GetFormatIndex()];
|
|
const int index = FindRegistryFormat(ai.Name);
|
|
UInt32 defaultDict = (UInt32)(Int32)-1;
|
|
|
|
if (index >= 0)
|
|
{
|
|
const NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index];
|
|
if (fo.Method.IsEqualTo_NoCase(GetMethodSpec()))
|
|
defaultDict = fo.Dictionary;
|
|
}
|
|
|
|
const int methodID = GetMethodID();
|
|
const UInt32 level = GetLevel2();
|
|
if (methodID < 0)
|
|
return;
|
|
UInt64 ramSize;
|
|
UInt64 maxRamSize;
|
|
const bool maxRamSize_Defined = GetMaxRamSizeForProgram(ramSize, maxRamSize);
|
|
|
|
switch (methodID)
|
|
{
|
|
case kLZMA:
|
|
case kLZMA2:
|
|
{
|
|
if (defaultDict == (UInt32)(Int32)-1)
|
|
{
|
|
defaultDict =
|
|
( level <= 3 ? ((UInt32)1 << (level * 2 + 16)) :
|
|
( level <= 6 ? ((UInt32)1 << (level + 19)) :
|
|
( level <= 7 ? ((UInt32)1 << 25) : ((UInt32)1 << 26)
|
|
)));
|
|
}
|
|
|
|
// we use threshold 3.75 GiB to switch to kLzmaMaxDictSize.
|
|
if (defaultDict >= ((UInt32)15 << 28))
|
|
defaultDict = kLzmaMaxDictSize;
|
|
|
|
const size_t kLzmaMaxDictSize_Up = (size_t)1 << (20 + sizeof(size_t) / 4 * 6);
|
|
|
|
int curSel = 0;
|
|
|
|
for (unsigned i = (16 - 1) * 2; i <= (32 - 1) * 2; i++)
|
|
{
|
|
if (i < (20 - 1) * 2
|
|
&& i != (16 - 1) * 2
|
|
&& i != (18 - 1) * 2)
|
|
continue;
|
|
if (i == (20 - 1) * 2 + 1)
|
|
continue;
|
|
const size_t dict_up = (size_t)(2 + (i & 1)) << (i / 2);
|
|
size_t dict = dict_up;
|
|
if (dict_up >= kLzmaMaxDictSize)
|
|
dict = kLzmaMaxDictSize; // we reduce dictionary
|
|
|
|
AddDict(dict);
|
|
// AddDict2(dict, dict_up); // for debug : we show 4 GB
|
|
|
|
const UInt64 memUsage = GetMemoryUsageComp_Dict(dict);
|
|
if (dict <= defaultDict && (!maxRamSize_Defined || memUsage <= maxRamSize))
|
|
curSel = m_Dictionary.GetCount() - 1;
|
|
if (dict_up >= kLzmaMaxDictSize_Up)
|
|
break;
|
|
}
|
|
|
|
m_Dictionary.SetCurSel(curSel);
|
|
// SetNearestSelectComboBox(m_Dictionary, defaultDict);
|
|
break;
|
|
}
|
|
|
|
case kPPMd:
|
|
{
|
|
if (defaultDict == (UInt32)(Int32)-1)
|
|
defaultDict = (UInt32)1 << (level + 19);
|
|
|
|
const UInt32 kPpmd_Default_4g = (UInt32)0 - ((UInt32)1 << 10);
|
|
const size_t kPpmd_MaxDictSize_Up = (size_t)1 << (29 + sizeof(size_t) / 8);
|
|
|
|
if (defaultDict >= ((UInt32)15 << 28)) // threshold
|
|
defaultDict = kPpmd_Default_4g;
|
|
|
|
int curSel = 0;
|
|
for (unsigned i = (20 - 1) * 2; i <= (32 - 1) * 2; i++)
|
|
{
|
|
if (i == (20 - 1) * 2 + 1)
|
|
continue;
|
|
|
|
const size_t dict_up = (size_t)(2 + (i & 1)) << (i / 2);
|
|
size_t dict = dict_up;
|
|
if (dict_up >= kPpmd_Default_4g)
|
|
dict = kPpmd_Default_4g;
|
|
|
|
AddDict2(dict, dict_up);
|
|
// AddDict2((UInt32)((UInt32)0 - 2), dict_up); // for debug
|
|
// AddDict(dict_up); // for debug
|
|
const UInt64 memUsage = GetMemoryUsageComp_Dict(dict);
|
|
if (dict <= defaultDict && (!maxRamSize_Defined || memUsage <= maxRamSize))
|
|
curSel = m_Dictionary.GetCount() - 1;
|
|
if (dict_up >= kPpmd_MaxDictSize_Up)
|
|
break;
|
|
}
|
|
m_Dictionary.SetCurSel(curSel);
|
|
// SetNearestSelectComboBox(m_Dictionary, defaultDict);
|
|
break;
|
|
}
|
|
|
|
case kPPMdZip:
|
|
{
|
|
if (defaultDict == (UInt32)(Int32)-1)
|
|
defaultDict = (UInt32)1 << (level + 19);
|
|
|
|
int curSel = 0;
|
|
for (unsigned i = 20; i <= 28; i++)
|
|
{
|
|
const UInt32 dict = (UInt32)1 << i;
|
|
AddDict(dict);
|
|
const UInt64 memUsage = GetMemoryUsageComp_Dict(dict);
|
|
if ((dict <= defaultDict && (!maxRamSize_Defined || memUsage <= maxRamSize)))
|
|
curSel = m_Dictionary.GetCount() - 1;
|
|
}
|
|
m_Dictionary.SetCurSel(curSel);
|
|
// SetNearestSelectComboBox(m_Dictionary, defaultDict);
|
|
break;
|
|
}
|
|
|
|
case kDeflate:
|
|
case kDeflate64:
|
|
{
|
|
const UInt32 dict = (methodID == kDeflate ? (UInt32)(1 << 15) : (UInt32)(1 << 16));
|
|
AddDict(dict);
|
|
m_Dictionary.SetCurSel(0);
|
|
break;
|
|
}
|
|
|
|
case kBZip2:
|
|
{
|
|
if (defaultDict == (UInt32)(Int32)-1)
|
|
{
|
|
if (level >= 5) defaultDict = (900 << 10);
|
|
else if (level >= 3) defaultDict = (500 << 10);
|
|
else defaultDict = (100 << 10);
|
|
}
|
|
|
|
int curSel = 0;
|
|
for (unsigned i = 1; i <= 9; i++)
|
|
{
|
|
const UInt32 dict = ((UInt32)i * 100) << 10;
|
|
AddDict(dict);
|
|
// AddDict2(i * 100000, dict);
|
|
if (i <= defaultDict / 100000)
|
|
curSel = m_Dictionary.GetCount() - 1;
|
|
}
|
|
m_Dictionary.SetCurSel(curSel);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
UInt32 CCompressDialog::GetComboValue(NWindows::NControl::CComboBox &c, int defMax)
|
|
{
|
|
if (c.GetCount() <= defMax)
|
|
return (UInt32)(Int32)-1;
|
|
return (UInt32)c.GetItemData_of_CurSel();
|
|
}
|
|
|
|
|
|
UInt64 CCompressDialog::GetComboValue_64(NWindows::NControl::CComboBox &c, int defMax)
|
|
{
|
|
if (c.GetCount() <= defMax)
|
|
return (UInt64)(Int64)-1;
|
|
// LRESULT is signed. so we cast it to unsigned size_t at first:
|
|
return (UInt64)(size_t)c.GetItemData_of_CurSel();
|
|
}
|
|
|
|
UInt32 CCompressDialog::GetLevel2()
|
|
{
|
|
UInt32 level = GetLevel();
|
|
if (level == (UInt32)(Int32)-1)
|
|
level = 5;
|
|
return level;
|
|
}
|
|
|
|
int CCompressDialog::AddOrder(UInt32 size)
|
|
{
|
|
TCHAR s[32];
|
|
ConvertUInt32ToString(size, s);
|
|
int index = (int)m_Order.AddString(s);
|
|
m_Order.SetItemData(index, size);
|
|
return index;
|
|
}
|
|
|
|
void CCompressDialog::SetOrder()
|
|
{
|
|
m_Order.ResetContent();
|
|
const CArcInfoEx &ai = (*ArcFormats)[GetFormatIndex()];
|
|
int index = FindRegistryFormat(ai.Name);
|
|
UInt32 defaultOrder = (UInt32)(Int32)-1;
|
|
|
|
if (index >= 0)
|
|
{
|
|
const NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index];
|
|
if (fo.Method.IsEqualTo_NoCase(GetMethodSpec()))
|
|
defaultOrder = fo.Order;
|
|
}
|
|
|
|
int methodID = GetMethodID();
|
|
UInt32 level = GetLevel2();
|
|
if (methodID < 0)
|
|
return;
|
|
|
|
switch (methodID)
|
|
{
|
|
case kLZMA:
|
|
case kLZMA2:
|
|
{
|
|
if (defaultOrder == (UInt32)(Int32)-1)
|
|
defaultOrder = (level >= 7) ? 64 : 32;
|
|
for (unsigned i = 3; i <= 8; i++)
|
|
for (unsigned j = 0; j < 2; j++)
|
|
{
|
|
UInt32 order = ((UInt32)(2 + j) << (i - 1));
|
|
if (order <= 256)
|
|
AddOrder(order);
|
|
}
|
|
AddOrder(273);
|
|
SetNearestSelectComboBox(m_Order, defaultOrder);
|
|
break;
|
|
}
|
|
|
|
case kPPMd:
|
|
{
|
|
if (defaultOrder == (UInt32)(Int32)-1)
|
|
{
|
|
if (level >= 9) defaultOrder = 32;
|
|
else if (level >= 7) defaultOrder = 16;
|
|
else if (level >= 5) defaultOrder = 6;
|
|
else defaultOrder = 4;
|
|
}
|
|
|
|
AddOrder(2);
|
|
AddOrder(3);
|
|
|
|
for (unsigned i = 2; i < 8; i++)
|
|
for (unsigned j = 0; j < 4; j++)
|
|
{
|
|
UInt32 order = (4 + j) << (i - 2);
|
|
if (order < 32)
|
|
AddOrder(order);
|
|
}
|
|
|
|
AddOrder(32);
|
|
SetNearestSelectComboBox(m_Order, defaultOrder);
|
|
break;
|
|
}
|
|
|
|
case kDeflate:
|
|
case kDeflate64:
|
|
{
|
|
if (defaultOrder == (UInt32)(Int32)-1)
|
|
{
|
|
if (level >= 9) defaultOrder = 128;
|
|
else if (level >= 7) defaultOrder = 64;
|
|
else defaultOrder = 32;
|
|
}
|
|
|
|
for (unsigned i = 3; i <= 8; i++)
|
|
for (unsigned j = 0; j < 2; j++)
|
|
{
|
|
UInt32 order = ((UInt32)(2 + j) << (i - 1));;
|
|
if (order <= 256)
|
|
AddOrder(order);
|
|
}
|
|
|
|
AddOrder(methodID == kDeflate64 ? 257 : 258);
|
|
SetNearestSelectComboBox(m_Order, defaultOrder);
|
|
break;
|
|
}
|
|
|
|
case kBZip2:
|
|
break;
|
|
|
|
case kPPMdZip:
|
|
{
|
|
if (defaultOrder == (UInt32)(Int32)-1)
|
|
defaultOrder = level + 3;
|
|
for (unsigned i = 2; i <= 16; i++)
|
|
AddOrder(i);
|
|
SetNearestSelectComboBox(m_Order, defaultOrder);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool CCompressDialog::GetOrderMode()
|
|
{
|
|
switch (GetMethodID())
|
|
{
|
|
case kPPMd:
|
|
case kPPMdZip:
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
static UInt64 Get_Lzma2_ChunkSize(UInt64 dict)
|
|
{
|
|
// we use same default chunk sizes as defined in 7z encoder and lzma2 encoder
|
|
UInt64 cs = (UInt64)dict << 2;
|
|
const UInt32 kMinSize = (UInt32)1 << 20;
|
|
const UInt32 kMaxSize = (UInt32)1 << 28;
|
|
if (cs < kMinSize) cs = kMinSize;
|
|
if (cs > kMaxSize) cs = kMaxSize;
|
|
if (cs < dict) cs = dict;
|
|
cs += (kMinSize - 1);
|
|
cs &= ~(UInt64)(kMinSize - 1);
|
|
return cs;
|
|
}
|
|
|
|
|
|
void CCompressDialog::SetSolidBlockSize(bool useDictionary)
|
|
{
|
|
m_Solid.ResetContent();
|
|
const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()];
|
|
if (!fi.Solid)
|
|
return;
|
|
|
|
UInt32 level = GetLevel2();
|
|
if (level == 0)
|
|
return;
|
|
|
|
UInt64 dict = GetDictSpec();
|
|
if (dict == (UInt64)(Int64)-1)
|
|
dict = 1;
|
|
|
|
UInt32 defaultBlockSize = (UInt32)(Int32)-1;
|
|
|
|
const CArcInfoEx &ai = (*ArcFormats)[GetFormatIndex()];
|
|
|
|
if (useDictionary)
|
|
defaultBlockSize = GetBlockSizeSpec();
|
|
else
|
|
{
|
|
int index = FindRegistryFormat(ai.Name);
|
|
if (index >= 0)
|
|
{
|
|
const NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index];
|
|
if (fo.Method.IsEqualTo_NoCase(GetMethodSpec()))
|
|
defaultBlockSize = fo.BlockLogSize;
|
|
}
|
|
}
|
|
|
|
bool is7z = ai.Name.IsEqualTo_Ascii_NoCase("7z");
|
|
|
|
{
|
|
UString s ('-');
|
|
if (is7z)
|
|
LangString(IDS_COMPRESS_NON_SOLID, s);
|
|
int index = (int)m_Solid.AddString(s);
|
|
m_Solid.SetItemData(index, (UInt32)kNoSolidBlockSize);
|
|
if (defaultBlockSize == kNoSolidBlockSize)
|
|
m_Solid.SetCurSel(0);
|
|
}
|
|
|
|
const UInt64 cs = Get_Lzma2_ChunkSize(dict);
|
|
|
|
// Solid Block Size
|
|
UInt64 blockSize = cs; // for xz
|
|
|
|
if (is7z)
|
|
{
|
|
// we use same default block sizes as defined in 7z encoder
|
|
UInt64 kMaxSize = (UInt64)1 << 32;
|
|
if (GetMethodID() == kLZMA2)
|
|
{
|
|
blockSize = cs << 6;
|
|
kMaxSize = (UInt64)1 << 34;
|
|
}
|
|
else
|
|
blockSize = (UInt64)dict << 7;
|
|
|
|
const UInt32 kMinSize = (UInt32)1 << 24;
|
|
if (blockSize < kMinSize) blockSize = kMinSize;
|
|
if (blockSize > kMaxSize) blockSize = kMaxSize;
|
|
}
|
|
|
|
for (unsigned i = 20; i <= 36; i++)
|
|
{
|
|
if (defaultBlockSize == (UInt32)(Int32)-1 && ((UInt64)1 << i) >= blockSize)
|
|
defaultBlockSize = i;
|
|
|
|
TCHAR s[32];
|
|
char post;
|
|
ConvertUInt32ToString(1 << (i % 10), s);
|
|
if (i < 20) post = 'K';
|
|
else if (i < 30) post = 'M';
|
|
else post = 'G';
|
|
unsigned pos = (unsigned)lstrlen(s);
|
|
s[pos++] = ' ';
|
|
s[pos++] = post;
|
|
s[pos++] = 'B';
|
|
s[pos] = 0;
|
|
int index = (int)m_Solid.AddString(s);
|
|
m_Solid.SetItemData(index, (UInt32)i);
|
|
}
|
|
|
|
{
|
|
int index = (int)m_Solid.AddString(LangString(IDS_COMPRESS_SOLID));
|
|
m_Solid.SetItemData(index, kSolidBlockSize);
|
|
}
|
|
|
|
if (defaultBlockSize == (UInt32)(Int32)-1)
|
|
defaultBlockSize = kSolidBlockSize;
|
|
if (defaultBlockSize != kNoSolidBlockSize)
|
|
SetNearestSelectComboBox(m_Solid, defaultBlockSize);
|
|
}
|
|
|
|
void CCompressDialog::SetNumThreads()
|
|
{
|
|
m_NumThreads.ResetContent();
|
|
|
|
const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()];
|
|
if (!fi.MultiThread)
|
|
return;
|
|
|
|
UInt32 numHardwareThreads = NSystem::GetNumberOfProcessors();
|
|
// numHardwareThreads = 64;
|
|
|
|
UInt32 defaultValue = numHardwareThreads;
|
|
|
|
{
|
|
const CArcInfoEx &ai = (*ArcFormats)[GetFormatIndex()];
|
|
int index = FindRegistryFormat(ai.Name);
|
|
if (index >= 0)
|
|
{
|
|
const NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index];
|
|
if (fo.Method.IsEqualTo_NoCase(GetMethodSpec()) && fo.NumThreads != (UInt32)(Int32)-1)
|
|
defaultValue = fo.NumThreads;
|
|
}
|
|
}
|
|
|
|
UInt32 numAlgoThreadsMax = 1;
|
|
int methodID = GetMethodID();
|
|
switch (methodID)
|
|
{
|
|
case kLZMA: numAlgoThreadsMax = 2; break;
|
|
case kLZMA2: numAlgoThreadsMax = 256; break;
|
|
case kBZip2: numAlgoThreadsMax = 32; break;
|
|
}
|
|
if (IsZipFormat())
|
|
numAlgoThreadsMax = 128;
|
|
for (UInt32 i = 1; i <= numHardwareThreads * 2 && i <= numAlgoThreadsMax; i++)
|
|
{
|
|
TCHAR s[32];
|
|
ConvertUInt32ToString(i, s);
|
|
int index = (int)m_NumThreads.AddString(s);
|
|
m_NumThreads.SetItemData(index, (UInt32)i);
|
|
}
|
|
SetNearestSelectComboBox(m_NumThreads, defaultValue);
|
|
}
|
|
|
|
|
|
UInt64 CCompressDialog::GetMemoryUsage_Dict_DecompMem(UInt64 dict64, UInt64 &decompressMemory)
|
|
{
|
|
decompressMemory = UInt64(Int64(-1));
|
|
UInt32 level = GetLevel2();
|
|
if (level == 0)
|
|
{
|
|
decompressMemory = (1 << 20);
|
|
return decompressMemory;
|
|
}
|
|
UInt64 size = 0;
|
|
|
|
const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()];
|
|
if (fi.Filter && level >= 9)
|
|
size += (12 << 20) * 2 + (5 << 20);
|
|
UInt32 numThreads = GetNumThreads2();
|
|
|
|
if (IsZipFormat())
|
|
{
|
|
UInt32 numSubThreads = 1;
|
|
if (GetMethodID() == kLZMA && numThreads > 1 && level >= 5)
|
|
numSubThreads = 2;
|
|
UInt32 numMainThreads = numThreads / numSubThreads;
|
|
if (numMainThreads > 1)
|
|
size += (UInt64)numMainThreads << 25;
|
|
}
|
|
|
|
int methidId = GetMethodID();
|
|
|
|
switch (methidId)
|
|
{
|
|
case kLZMA:
|
|
case kLZMA2:
|
|
{
|
|
const UInt32 dict = (dict64 >= kLzmaMaxDictSize ? kLzmaMaxDictSize : (UInt32)dict64);
|
|
UInt32 hs = dict - 1;
|
|
hs |= (hs >> 1);
|
|
hs |= (hs >> 2);
|
|
hs |= (hs >> 4);
|
|
hs |= (hs >> 8);
|
|
hs >>= 1;
|
|
if (hs >= (1 << 24))
|
|
hs >>= 1;
|
|
hs |= (1 << 16) - 1;
|
|
// if (numHashBytes >= 5)
|
|
if (level < 5)
|
|
hs |= (256 << 10) - 1;
|
|
hs++;
|
|
UInt64 size1 = (UInt64)hs * 4;
|
|
size1 += (UInt64)dict * 4;
|
|
if (level >= 5)
|
|
size1 += (UInt64)dict * 4;
|
|
size1 += (2 << 20);
|
|
|
|
UInt32 numThreads1 = 1;
|
|
if (numThreads > 1 && level >= 5)
|
|
{
|
|
size1 += (2 << 20) + (4 << 20);
|
|
numThreads1 = 2;
|
|
}
|
|
|
|
UInt32 numBlockThreads = numThreads / numThreads1;
|
|
|
|
UInt64 chunkSize = 0;
|
|
|
|
if (methidId != kLZMA && numBlockThreads != 1)
|
|
{
|
|
chunkSize = Get_Lzma2_ChunkSize(dict);
|
|
|
|
if (IsXzFormat())
|
|
{
|
|
UInt32 blockSizeLog = GetBlockSizeSpec();
|
|
if (blockSizeLog != (UInt32)(Int32)-1)
|
|
{
|
|
if (blockSizeLog == kSolidBlockSize)
|
|
{
|
|
numBlockThreads = 1;
|
|
chunkSize = 0;
|
|
}
|
|
else if (blockSizeLog != kNoSolidBlockSize)
|
|
chunkSize = (UInt64)1 << blockSizeLog;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (chunkSize == 0)
|
|
{
|
|
const UInt32 kBlockSizeMax = (UInt32)0 - (UInt32)(1 << 16);
|
|
UInt64 blockSize = (UInt64)dict + (1 << 16)
|
|
+ (numThreads1 > 1 ? (1 << 20) : 0);
|
|
blockSize += (blockSize >> (blockSize < ((UInt32)1 << 30) ? 1 : 2));
|
|
if (blockSize >= kBlockSizeMax)
|
|
blockSize = kBlockSizeMax;
|
|
size += numBlockThreads * (size1 + blockSize);
|
|
}
|
|
else
|
|
{
|
|
size += numBlockThreads * (size1 + chunkSize);
|
|
UInt64 numPackChunks = numBlockThreads + (numBlockThreads / 4) + 2;
|
|
size += numPackChunks * chunkSize;
|
|
}
|
|
|
|
decompressMemory = dict + (2 << 20);
|
|
return size;
|
|
}
|
|
|
|
case kPPMd:
|
|
{
|
|
decompressMemory = dict64 + (2 << 20);
|
|
return size + decompressMemory;
|
|
}
|
|
|
|
case kDeflate:
|
|
case kDeflate64:
|
|
{
|
|
/*
|
|
UInt32 order = GetOrder();
|
|
if (order == (UInt32)(Int32)-1)
|
|
order = 32;
|
|
*/
|
|
if (level >= 7)
|
|
size += (1 << 20);
|
|
size += 3 << 20;
|
|
decompressMemory = (2 << 20);
|
|
return size;
|
|
}
|
|
|
|
case kBZip2:
|
|
{
|
|
decompressMemory = (7 << 20);
|
|
UInt64 memForOneThread = (10 << 20);
|
|
return size + memForOneThread * numThreads;
|
|
}
|
|
|
|
case kPPMdZip:
|
|
{
|
|
decompressMemory = dict64 + (2 << 20);
|
|
return size + (UInt64)decompressMemory * numThreads;
|
|
}
|
|
}
|
|
|
|
return (UInt64)(Int64)-1;
|
|
}
|
|
|
|
UInt64 CCompressDialog::GetMemoryUsage_DecompMem(UInt64 &decompressMemory)
|
|
{
|
|
return GetMemoryUsage_Dict_DecompMem(GetDict(), decompressMemory);
|
|
}
|
|
|
|
UInt64 CCompressDialog::GetMemoryUsageComp_Dict(UInt64 dict64)
|
|
{
|
|
UInt64 decompressMemory;
|
|
return GetMemoryUsage_Dict_DecompMem(dict64, decompressMemory);
|
|
}
|
|
|
|
void CCompressDialog::PrintMemUsage(UINT res, UInt64 value)
|
|
{
|
|
if (value == (UInt64)(Int64)-1)
|
|
{
|
|
SetItemText(res, TEXT("?"));
|
|
return;
|
|
}
|
|
TCHAR s[32];
|
|
if (value <= ((UInt64)16 << 30))
|
|
{
|
|
value = (value + (1 << 20) - 1) >> 20;
|
|
ConvertUInt64ToString(value, s);
|
|
lstrcat(s, TEXT(" MB"));
|
|
}
|
|
else
|
|
{
|
|
value = (value + (1 << 30) - 1) >> 30;
|
|
ConvertUInt64ToString(value, s);
|
|
lstrcat(s, TEXT(" GB"));
|
|
}
|
|
SetItemText(res, s);
|
|
}
|
|
|
|
void CCompressDialog::SetMemoryUsage()
|
|
{
|
|
UInt64 decompressMem;
|
|
const UInt64 memUsage = GetMemoryUsage_DecompMem(decompressMem);
|
|
PrintMemUsage(IDT_COMPRESS_MEMORY_VALUE, memUsage);
|
|
PrintMemUsage(IDT_COMPRESS_MEMORY_DE_VALUE, decompressMem);
|
|
}
|
|
|
|
void CCompressDialog::SetParams()
|
|
{
|
|
const CArcInfoEx &ai = (*ArcFormats)[GetFormatIndex()];
|
|
m_Params.SetText(TEXT(""));
|
|
const int index = FindRegistryFormat(ai.Name);
|
|
if (index >= 0)
|
|
{
|
|
const NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index];
|
|
m_Params.SetText(fo.Options);
|
|
}
|
|
}
|
|
|
|
void CCompressDialog::SaveOptionsInMem()
|
|
{
|
|
const CArcInfoEx &ai = (*ArcFormats)[Info.FormatIndex];
|
|
const int index = FindRegistryFormatAlways(ai.Name);
|
|
m_Params.GetText(Info.Options);
|
|
Info.Options.Trim();
|
|
NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index];
|
|
fo.Options = Info.Options;
|
|
fo.Level = GetLevelSpec();
|
|
{
|
|
const UInt64 dict64 = GetDictSpec();
|
|
UInt32 dict32;
|
|
if (dict64 == (UInt64)(Int64)-1)
|
|
dict32 = (UInt32)(Int32)-1;
|
|
else
|
|
{
|
|
dict32 = (UInt32)dict64;
|
|
if (dict64 != dict32)
|
|
{
|
|
/* here we must write 32-bit value for registry that indicates big_value
|
|
(UInt32)(Int32)-1 : is used as marker for default size
|
|
(UInt32)(Int32)-2 : it can be used to indicate big value (4 GiB)
|
|
the value must be larger than threshold
|
|
*/
|
|
dict32 = (UInt32)(Int32)-2;
|
|
// dict32 = kLzmaMaxDictSize; // it must be larger than threshold
|
|
}
|
|
}
|
|
fo.Dictionary = dict32;
|
|
}
|
|
|
|
fo.Order = GetOrderSpec();
|
|
fo.Method = GetMethodSpec();
|
|
fo.EncryptionMethod = GetEncryptionMethodSpec();
|
|
fo.NumThreads = GetNumThreadsSpec();
|
|
fo.BlockLogSize = GetBlockSizeSpec();
|
|
}
|
|
|
|
unsigned CCompressDialog::GetFormatIndex()
|
|
{
|
|
return (unsigned)m_Format.GetItemData_of_CurSel();
|
|
}
|