diff options
Diffstat (limited to 'CPP/7zip/UI/GUI/CompressDialog.cpp')
-rw-r--r-- | CPP/7zip/UI/GUI/CompressDialog.cpp | 2593 |
1 files changed, 2593 insertions, 0 deletions
diff --git a/CPP/7zip/UI/GUI/CompressDialog.cpp b/CPP/7zip/UI/GUI/CompressDialog.cpp new file mode 100644 index 0000000..16a3585 --- /dev/null +++ b/CPP/7zip/UI/GUI/CompressDialog.cpp | |||
@@ -0,0 +1,2593 @@ | |||
1 | // CompressDialog.cpp | ||
2 | |||
3 | #include "StdAfx.h" | ||
4 | |||
5 | #include "../../../../C/CpuArch.h" | ||
6 | |||
7 | #include "../../../Common/IntToString.h" | ||
8 | #include "../../../Common/StringConvert.h" | ||
9 | |||
10 | #include "../../../Windows/FileDir.h" | ||
11 | #include "../../../Windows/FileName.h" | ||
12 | #include "../../../Windows/System.h" | ||
13 | |||
14 | #include "../../Common/MethodProps.h" | ||
15 | |||
16 | #include "../FileManager/BrowseDialog.h" | ||
17 | #include "../FileManager/FormatUtils.h" | ||
18 | #include "../FileManager/HelpUtils.h" | ||
19 | #include "../FileManager/SplitUtils.h" | ||
20 | |||
21 | #include "../Explorer/MyMessages.h" | ||
22 | |||
23 | #include "../Common/ZipRegistry.h" | ||
24 | |||
25 | #include "CompressDialog.h" | ||
26 | |||
27 | #ifndef _UNICODE | ||
28 | extern bool g_IsNT; | ||
29 | #endif | ||
30 | |||
31 | #ifdef LANG | ||
32 | #include "../FileManager/LangUtils.h" | ||
33 | #endif | ||
34 | |||
35 | #include "CompressDialogRes.h" | ||
36 | #include "ExtractRes.h" | ||
37 | |||
38 | #ifdef LANG | ||
39 | static const UInt32 kLangIDs[] = | ||
40 | { | ||
41 | IDT_COMPRESS_ARCHIVE, | ||
42 | IDT_COMPRESS_UPDATE_MODE, | ||
43 | IDT_COMPRESS_FORMAT, | ||
44 | IDT_COMPRESS_LEVEL, | ||
45 | IDT_COMPRESS_METHOD, | ||
46 | IDT_COMPRESS_DICTIONARY, | ||
47 | IDT_COMPRESS_ORDER, | ||
48 | IDT_COMPRESS_SOLID, | ||
49 | IDT_COMPRESS_THREADS, | ||
50 | IDT_COMPRESS_PARAMETERS, | ||
51 | |||
52 | IDG_COMPRESS_OPTIONS, | ||
53 | IDX_COMPRESS_SFX, | ||
54 | IDX_COMPRESS_SHARED, | ||
55 | IDX_COMPRESS_DEL, | ||
56 | |||
57 | IDT_COMPRESS_MEMORY, | ||
58 | IDT_COMPRESS_MEMORY_DE, | ||
59 | |||
60 | IDX_COMPRESS_NT_SYM_LINKS, | ||
61 | IDX_COMPRESS_NT_HARD_LINKS, | ||
62 | IDX_COMPRESS_NT_ALT_STREAMS, | ||
63 | IDX_COMPRESS_NT_SECUR, | ||
64 | |||
65 | IDG_COMPRESS_ENCRYPTION, | ||
66 | IDT_COMPRESS_ENCRYPTION_METHOD, | ||
67 | IDX_COMPRESS_ENCRYPT_FILE_NAMES, | ||
68 | |||
69 | IDT_PASSWORD_ENTER, | ||
70 | IDT_PASSWORD_REENTER, | ||
71 | IDX_PASSWORD_SHOW, | ||
72 | |||
73 | IDT_SPLIT_TO_VOLUMES, | ||
74 | IDT_COMPRESS_PATH_MODE | ||
75 | }; | ||
76 | #endif | ||
77 | |||
78 | using namespace NWindows; | ||
79 | using namespace NFile; | ||
80 | using namespace NName; | ||
81 | using namespace NDir; | ||
82 | |||
83 | static const unsigned kHistorySize = 20; | ||
84 | |||
85 | static const UInt32 kSolidLog_NoSolid = 0; | ||
86 | static const UInt32 kSolidLog_FullSolid = 64; | ||
87 | |||
88 | static const UInt32 kLzmaMaxDictSize = (UInt32)15 << 28; | ||
89 | |||
90 | static LPCSTR const kExeExt = ".exe"; | ||
91 | |||
92 | #define k7zFormat "7z" | ||
93 | |||
94 | static const UInt32 g_Levels[] = | ||
95 | { | ||
96 | IDS_METHOD_STORE, | ||
97 | IDS_METHOD_FASTEST, | ||
98 | 0, | ||
99 | IDS_METHOD_FAST, | ||
100 | 0, | ||
101 | IDS_METHOD_NORMAL, | ||
102 | 0, | ||
103 | IDS_METHOD_MAXIMUM, | ||
104 | 0, | ||
105 | IDS_METHOD_ULTRA | ||
106 | }; | ||
107 | |||
108 | enum EMethodID | ||
109 | { | ||
110 | kCopy, | ||
111 | kLZMA, | ||
112 | kLZMA2, | ||
113 | kPPMd, | ||
114 | kBZip2, | ||
115 | kDeflate, | ||
116 | kDeflate64, | ||
117 | kPPMdZip, | ||
118 | kSha256, | ||
119 | kSha1, | ||
120 | kCrc32, | ||
121 | kCrc64, | ||
122 | }; | ||
123 | |||
124 | static LPCSTR const kMethodsNames[] = | ||
125 | { | ||
126 | "Copy" | ||
127 | , "LZMA" | ||
128 | , "LZMA2" | ||
129 | , "PPMd" | ||
130 | , "BZip2" | ||
131 | , "Deflate" | ||
132 | , "Deflate64" | ||
133 | , "PPMd" | ||
134 | , "SHA256" | ||
135 | , "SHA1" | ||
136 | , "CRC32" | ||
137 | , "CRC64" | ||
138 | }; | ||
139 | |||
140 | static const EMethodID g_7zMethods[] = | ||
141 | { | ||
142 | kLZMA2, | ||
143 | kLZMA, | ||
144 | kPPMd, | ||
145 | kBZip2 | ||
146 | , kDeflate | ||
147 | , kDeflate64 | ||
148 | , kCopy | ||
149 | }; | ||
150 | |||
151 | static const EMethodID g_7zSfxMethods[] = | ||
152 | { | ||
153 | kCopy, | ||
154 | kLZMA, | ||
155 | kLZMA2, | ||
156 | kPPMd | ||
157 | }; | ||
158 | |||
159 | static const EMethodID g_ZipMethods[] = | ||
160 | { | ||
161 | kDeflate, | ||
162 | kDeflate64, | ||
163 | kBZip2, | ||
164 | kLZMA, | ||
165 | kPPMdZip | ||
166 | }; | ||
167 | |||
168 | static const EMethodID g_GZipMethods[] = | ||
169 | { | ||
170 | kDeflate | ||
171 | }; | ||
172 | |||
173 | static const EMethodID g_BZip2Methods[] = | ||
174 | { | ||
175 | kBZip2 | ||
176 | }; | ||
177 | |||
178 | static const EMethodID g_XzMethods[] = | ||
179 | { | ||
180 | kLZMA2 | ||
181 | }; | ||
182 | |||
183 | static const EMethodID g_SwfcMethods[] = | ||
184 | { | ||
185 | kDeflate | ||
186 | // kLZMA | ||
187 | }; | ||
188 | |||
189 | static const EMethodID g_HashMethods[] = | ||
190 | { | ||
191 | kSha256 | ||
192 | , kSha1 | ||
193 | // , kCrc32 | ||
194 | // , kCrc64 | ||
195 | }; | ||
196 | |||
197 | static const UInt32 kFF_Filter = 1 << 0; | ||
198 | static const UInt32 kFF_Solid = 1 << 1; | ||
199 | static const UInt32 kFF_MultiThread = 1 << 2; | ||
200 | static const UInt32 kFF_Encrypt = 1 << 3; | ||
201 | static const UInt32 kFF_EncryptFileNames = 1 << 4; | ||
202 | static const UInt32 kFF_MemUse = 1 << 5; | ||
203 | static const UInt32 kFF_SFX = 1 << 6; | ||
204 | |||
205 | struct CFormatInfo | ||
206 | { | ||
207 | LPCSTR Name; | ||
208 | UInt32 LevelsMask; | ||
209 | unsigned NumMethods; | ||
210 | const EMethodID *MethodIDs; | ||
211 | |||
212 | UInt32 Flags; | ||
213 | |||
214 | bool Filter_() const { return (Flags & kFF_Filter) != 0; } | ||
215 | bool Solid_() const { return (Flags & kFF_Solid) != 0; } | ||
216 | bool MultiThread_() const { return (Flags & kFF_MultiThread) != 0; } | ||
217 | bool Encrypt_() const { return (Flags & kFF_Encrypt) != 0; } | ||
218 | bool EncryptFileNames_() const { return (Flags & kFF_EncryptFileNames) != 0; } | ||
219 | bool MemUse_() const { return (Flags & kFF_MemUse) != 0; } | ||
220 | bool SFX_() const { return (Flags & kFF_SFX) != 0; } | ||
221 | }; | ||
222 | |||
223 | #define METHODS_PAIR(x) ARRAY_SIZE(x), x | ||
224 | |||
225 | static const CFormatInfo g_Formats[] = | ||
226 | { | ||
227 | { | ||
228 | "", | ||
229 | // (1 << 0) | (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9), | ||
230 | ((UInt32)1 << 10) - 1, | ||
231 | // (UInt32)(Int32)-1, | ||
232 | 0, NULL, | ||
233 | kFF_MultiThread | kFF_MemUse | ||
234 | }, | ||
235 | { | ||
236 | k7zFormat, | ||
237 | (1 << 0) | (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9), | ||
238 | METHODS_PAIR(g_7zMethods), | ||
239 | kFF_Filter | kFF_Solid | kFF_MultiThread | kFF_Encrypt | | ||
240 | kFF_EncryptFileNames | kFF_MemUse | kFF_SFX | ||
241 | }, | ||
242 | { | ||
243 | "Zip", | ||
244 | (1 << 0) | (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9), | ||
245 | METHODS_PAIR(g_ZipMethods), | ||
246 | kFF_MultiThread | kFF_Encrypt | kFF_MemUse | ||
247 | }, | ||
248 | { | ||
249 | "GZip", | ||
250 | (1 << 1) | (1 << 5) | (1 << 7) | (1 << 9), | ||
251 | METHODS_PAIR(g_GZipMethods), | ||
252 | kFF_MemUse | ||
253 | }, | ||
254 | { | ||
255 | "BZip2", | ||
256 | (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9), | ||
257 | METHODS_PAIR(g_BZip2Methods), | ||
258 | kFF_MultiThread | kFF_MemUse | ||
259 | }, | ||
260 | { | ||
261 | "xz", | ||
262 | (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9), | ||
263 | METHODS_PAIR(g_XzMethods), | ||
264 | kFF_Solid | kFF_MultiThread | kFF_MemUse | ||
265 | }, | ||
266 | { | ||
267 | "Swfc", | ||
268 | (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9), | ||
269 | METHODS_PAIR(g_SwfcMethods), | ||
270 | 0 | ||
271 | }, | ||
272 | { | ||
273 | "Tar", | ||
274 | (1 << 0), | ||
275 | 0, NULL, | ||
276 | 0 | ||
277 | }, | ||
278 | { | ||
279 | "wim", | ||
280 | (1 << 0), | ||
281 | 0, NULL, | ||
282 | 0 | ||
283 | }, | ||
284 | { | ||
285 | "Hash", | ||
286 | (0 << 0), | ||
287 | METHODS_PAIR(g_HashMethods), | ||
288 | 0 | ||
289 | } | ||
290 | }; | ||
291 | |||
292 | static bool IsMethodSupportedBySfx(int methodID) | ||
293 | { | ||
294 | for (unsigned i = 0; i < ARRAY_SIZE(g_7zSfxMethods); i++) | ||
295 | if (methodID == g_7zSfxMethods[i]) | ||
296 | return true; | ||
297 | return false; | ||
298 | } | ||
299 | |||
300 | |||
301 | static const | ||
302 | // NCompressDialog::NUpdateMode::EEnum | ||
303 | int | ||
304 | k_UpdateMode_Vals[] = | ||
305 | { | ||
306 | NCompressDialog::NUpdateMode::kAdd, | ||
307 | NCompressDialog::NUpdateMode::kUpdate, | ||
308 | NCompressDialog::NUpdateMode::kFresh, | ||
309 | NCompressDialog::NUpdateMode::kSync | ||
310 | }; | ||
311 | |||
312 | static const UInt32 k_UpdateMode_IDs[] = | ||
313 | { | ||
314 | IDS_COMPRESS_UPDATE_MODE_ADD, | ||
315 | IDS_COMPRESS_UPDATE_MODE_UPDATE, | ||
316 | IDS_COMPRESS_UPDATE_MODE_FRESH, | ||
317 | IDS_COMPRESS_UPDATE_MODE_SYNC | ||
318 | }; | ||
319 | |||
320 | static const | ||
321 | // NWildcard::ECensorPathMode | ||
322 | int | ||
323 | k_PathMode_Vals[] = | ||
324 | { | ||
325 | NWildcard::k_RelatPath, | ||
326 | NWildcard::k_FullPath, | ||
327 | NWildcard::k_AbsPath, | ||
328 | }; | ||
329 | |||
330 | static const UInt32 k_PathMode_IDs[] = | ||
331 | { | ||
332 | IDS_PATH_MODE_RELAT, | ||
333 | IDS_EXTRACT_PATHS_FULL, | ||
334 | IDS_EXTRACT_PATHS_ABS | ||
335 | }; | ||
336 | |||
337 | void AddComboItems(NControl::CComboBox &combo, const UInt32 *langIDs, unsigned numItems, const int *values, int curVal); | ||
338 | bool GetBoolsVal(const CBoolPair &b1, const CBoolPair &b2); | ||
339 | |||
340 | void CCompressDialog::CheckButton_TwoBools(UINT id, const CBoolPair &b1, const CBoolPair &b2) | ||
341 | { | ||
342 | CheckButton(id, GetBoolsVal(b1, b2)); | ||
343 | } | ||
344 | |||
345 | void CCompressDialog::GetButton_Bools(UINT id, CBoolPair &b1, CBoolPair &b2) | ||
346 | { | ||
347 | bool val = IsButtonCheckedBool(id); | ||
348 | bool oldVal = GetBoolsVal(b1, b2); | ||
349 | if (val != oldVal) | ||
350 | b1.Def = b2.Def = true; | ||
351 | b1.Val = b2.Val = val; | ||
352 | } | ||
353 | |||
354 | |||
355 | void CCompressDialog::SetMethods(const CObjectVector<CCodecInfoUser> &userCodecs) | ||
356 | { | ||
357 | ExternalMethods.Clear(); | ||
358 | { | ||
359 | FOR_VECTOR (i, userCodecs) | ||
360 | { | ||
361 | const CCodecInfoUser &c = userCodecs[i]; | ||
362 | if (!c.EncoderIsAssigned | ||
363 | || !c.IsFilter_Assigned | ||
364 | || c.IsFilter | ||
365 | || c.NumStreams != 1) | ||
366 | continue; | ||
367 | unsigned k; | ||
368 | for (k = 0; k < ARRAY_SIZE(g_7zMethods); k++) | ||
369 | if (c.Name.IsEqualTo_Ascii_NoCase(kMethodsNames[g_7zMethods[k]])) | ||
370 | break; | ||
371 | if (k != ARRAY_SIZE(g_7zMethods)) | ||
372 | continue; | ||
373 | ExternalMethods.Add(c.Name); | ||
374 | } | ||
375 | } | ||
376 | } | ||
377 | |||
378 | |||
379 | bool CCompressDialog::OnInit() | ||
380 | { | ||
381 | #ifdef LANG | ||
382 | LangSetWindowText(*this, IDD_COMPRESS); | ||
383 | LangSetDlgItems(*this, kLangIDs, ARRAY_SIZE(kLangIDs)); | ||
384 | #endif | ||
385 | |||
386 | { | ||
387 | UInt64 size = (UInt64)(sizeof(size_t)) << 29; | ||
388 | _ramSize_Defined = NSystem::GetRamSize(size); | ||
389 | // size = (UInt64)3 << 62; // for debug only; | ||
390 | _ramSize = size; | ||
391 | const UInt64 kMinUseSize = (1 << 26); | ||
392 | if (size < kMinUseSize) | ||
393 | size = kMinUseSize; | ||
394 | |||
395 | unsigned bits = sizeof(size_t) * 8; | ||
396 | if (bits == 32) | ||
397 | { | ||
398 | const UInt32 limit2 = (UInt32)7 << 28; | ||
399 | if (size > limit2) | ||
400 | size = limit2; | ||
401 | } | ||
402 | |||
403 | _ramSize_Reduced = size; | ||
404 | |||
405 | // 80% - is auto usage limit in handlers | ||
406 | _ramUsage_Auto = Calc_From_Val_Percents(size, 80); | ||
407 | } | ||
408 | |||
409 | _password1Control.Attach(GetItem(IDE_COMPRESS_PASSWORD1)); | ||
410 | _password2Control.Attach(GetItem(IDE_COMPRESS_PASSWORD2)); | ||
411 | _password1Control.SetText(Info.Password); | ||
412 | _password2Control.SetText(Info.Password); | ||
413 | _encryptionMethod.Attach(GetItem(IDC_COMPRESS_ENCRYPTION_METHOD)); | ||
414 | _default_encryptionMethod_Index = -1; | ||
415 | |||
416 | m_ArchivePath.Attach(GetItem(IDC_COMPRESS_ARCHIVE)); | ||
417 | m_Format.Attach(GetItem(IDC_COMPRESS_FORMAT)); | ||
418 | m_Level.Attach(GetItem(IDC_COMPRESS_LEVEL)); | ||
419 | m_Method.Attach(GetItem(IDC_COMPRESS_METHOD)); | ||
420 | m_Dictionary.Attach(GetItem(IDC_COMPRESS_DICTIONARY)); | ||
421 | m_Order.Attach(GetItem(IDC_COMPRESS_ORDER)); | ||
422 | m_Solid.Attach(GetItem(IDC_COMPRESS_SOLID)); | ||
423 | m_NumThreads.Attach(GetItem(IDC_COMPRESS_THREADS)); | ||
424 | m_MemUse.Attach(GetItem(IDC_COMPRESS_MEM_USE)); | ||
425 | |||
426 | m_UpdateMode.Attach(GetItem(IDC_COMPRESS_UPDATE_MODE)); | ||
427 | m_PathMode.Attach(GetItem(IDC_COMPRESS_PATH_MODE)); | ||
428 | |||
429 | m_Volume.Attach(GetItem(IDC_COMPRESS_VOLUME)); | ||
430 | m_Params.Attach(GetItem(IDE_COMPRESS_PARAMETERS)); | ||
431 | |||
432 | AddVolumeItems(m_Volume); | ||
433 | |||
434 | m_RegistryInfo.Load(); | ||
435 | CheckButton(IDX_PASSWORD_SHOW, m_RegistryInfo.ShowPassword); | ||
436 | CheckButton(IDX_COMPRESS_ENCRYPT_FILE_NAMES, m_RegistryInfo.EncryptHeaders); | ||
437 | |||
438 | CheckButton_TwoBools(IDX_COMPRESS_NT_SYM_LINKS, Info.SymLinks, m_RegistryInfo.SymLinks); | ||
439 | CheckButton_TwoBools(IDX_COMPRESS_NT_HARD_LINKS, Info.HardLinks, m_RegistryInfo.HardLinks); | ||
440 | CheckButton_TwoBools(IDX_COMPRESS_NT_ALT_STREAMS, Info.AltStreams, m_RegistryInfo.AltStreams); | ||
441 | CheckButton_TwoBools(IDX_COMPRESS_NT_SECUR, Info.NtSecurity, m_RegistryInfo.NtSecurity); | ||
442 | |||
443 | UpdatePasswordControl(); | ||
444 | |||
445 | { | ||
446 | bool needSetMain = (Info.FormatIndex < 0); | ||
447 | FOR_VECTOR(i, ArcIndices) | ||
448 | { | ||
449 | unsigned arcIndex = ArcIndices[i]; | ||
450 | const CArcInfoEx &ai = (*ArcFormats)[arcIndex]; | ||
451 | int index = (int)m_Format.AddString(ai.Name); | ||
452 | m_Format.SetItemData(index, arcIndex); | ||
453 | if (!needSetMain) | ||
454 | { | ||
455 | if (Info.FormatIndex == (int)arcIndex) | ||
456 | m_Format.SetCurSel(index); | ||
457 | continue; | ||
458 | } | ||
459 | if (i == 0 || ai.Name.IsEqualTo_NoCase(m_RegistryInfo.ArcType)) | ||
460 | { | ||
461 | m_Format.SetCurSel(index); | ||
462 | Info.FormatIndex = arcIndex; | ||
463 | } | ||
464 | } | ||
465 | } | ||
466 | |||
467 | CheckButton(IDX_COMPRESS_SFX, Info.SFXMode); | ||
468 | |||
469 | { | ||
470 | UString fileName; | ||
471 | SetArcPathFields(Info.ArcPath, fileName, true); | ||
472 | StartDirPrefix = DirPrefix; | ||
473 | SetArchiveName(fileName); | ||
474 | } | ||
475 | |||
476 | for (unsigned i = 0; i < m_RegistryInfo.ArcPaths.Size() && i < kHistorySize; i++) | ||
477 | m_ArchivePath.AddString(m_RegistryInfo.ArcPaths[i]); | ||
478 | |||
479 | AddComboItems(m_UpdateMode, k_UpdateMode_IDs, ARRAY_SIZE(k_UpdateMode_IDs), | ||
480 | k_UpdateMode_Vals, Info.UpdateMode); | ||
481 | |||
482 | AddComboItems(m_PathMode, k_PathMode_IDs, ARRAY_SIZE(k_PathMode_IDs), | ||
483 | k_PathMode_Vals, Info.PathMode); | ||
484 | |||
485 | |||
486 | TCHAR s[32] = { TEXT('/'), TEXT(' '), 0 }; | ||
487 | ConvertUInt32ToString(NSystem::GetNumberOfProcessors(), s + 2); | ||
488 | SetItemText(IDT_COMPRESS_HARDWARE_THREADS, s); | ||
489 | |||
490 | CheckButton(IDX_COMPRESS_SHARED, Info.OpenShareForWrite); | ||
491 | CheckButton(IDX_COMPRESS_DEL, Info.DeleteAfterCompressing); | ||
492 | |||
493 | FormatChanged(); | ||
494 | |||
495 | // OnButtonSFX(); | ||
496 | |||
497 | NormalizePosition(); | ||
498 | |||
499 | return CModalDialog::OnInit(); | ||
500 | } | ||
501 | |||
502 | /* | ||
503 | namespace NCompressDialog | ||
504 | { | ||
505 | bool CInfo::GetFullPathName(UString &result) const | ||
506 | { | ||
507 | #ifndef UNDER_CE | ||
508 | // NDirectory::MySetCurrentDirectory(CurrentDirPrefix); | ||
509 | #endif | ||
510 | FString resultF; | ||
511 | bool res = MyGetFullPathName(us2fs(ArchiveName), resultF); | ||
512 | result = fs2us(resultF); | ||
513 | return res; | ||
514 | } | ||
515 | } | ||
516 | */ | ||
517 | |||
518 | void CCompressDialog::UpdatePasswordControl() | ||
519 | { | ||
520 | bool showPassword = IsShowPasswordChecked(); | ||
521 | TCHAR c = showPassword ? (TCHAR)0: TEXT('*'); | ||
522 | _password1Control.SetPasswordChar(c); | ||
523 | _password2Control.SetPasswordChar(c); | ||
524 | UString password; | ||
525 | _password1Control.GetText(password); | ||
526 | _password1Control.SetText(password); | ||
527 | _password2Control.GetText(password); | ||
528 | _password2Control.SetText(password); | ||
529 | |||
530 | ShowItem_Bool(IDT_PASSWORD_REENTER, !showPassword); | ||
531 | _password2Control.Show_Bool(!showPassword); | ||
532 | } | ||
533 | |||
534 | bool CCompressDialog::OnButtonClicked(int buttonID, HWND buttonHWND) | ||
535 | { | ||
536 | switch (buttonID) | ||
537 | { | ||
538 | case IDB_COMPRESS_SET_ARCHIVE: | ||
539 | { | ||
540 | OnButtonSetArchive(); | ||
541 | return true; | ||
542 | } | ||
543 | case IDX_COMPRESS_SFX: | ||
544 | { | ||
545 | SetMethod(GetMethodID()); | ||
546 | OnButtonSFX(); | ||
547 | SetMemoryUsage(); | ||
548 | return true; | ||
549 | } | ||
550 | case IDX_PASSWORD_SHOW: | ||
551 | { | ||
552 | UpdatePasswordControl(); | ||
553 | return true; | ||
554 | } | ||
555 | } | ||
556 | return CModalDialog::OnButtonClicked(buttonID, buttonHWND); | ||
557 | } | ||
558 | |||
559 | void CCompressDialog::CheckSFXControlsEnable() | ||
560 | { | ||
561 | const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()]; | ||
562 | bool enable = fi.SFX_(); | ||
563 | if (enable) | ||
564 | { | ||
565 | const int methodID = GetMethodID(); | ||
566 | enable = (methodID == -1 || IsMethodSupportedBySfx(methodID)); | ||
567 | } | ||
568 | if (!enable) | ||
569 | CheckButton(IDX_COMPRESS_SFX, false); | ||
570 | EnableItem(IDX_COMPRESS_SFX, enable); | ||
571 | } | ||
572 | |||
573 | /* | ||
574 | void CCompressDialog::CheckVolumeEnable() | ||
575 | { | ||
576 | bool isSFX = IsSFX(); | ||
577 | m_Volume.Enable(!isSFX); | ||
578 | if (isSFX) | ||
579 | m_Volume.SetText(TEXT("")); | ||
580 | } | ||
581 | */ | ||
582 | |||
583 | void CCompressDialog::EnableMultiCombo(unsigned id) | ||
584 | { | ||
585 | NWindows::NControl::CComboBox combo; | ||
586 | combo.Attach(GetItem(id)); | ||
587 | const bool enable = (combo.GetCount() > 1); | ||
588 | EnableItem(id, enable); | ||
589 | } | ||
590 | |||
591 | |||
592 | void CCompressDialog::FormatChanged() | ||
593 | { | ||
594 | SetLevel(); | ||
595 | SetSolidBlockSize(); | ||
596 | SetParams(); | ||
597 | SetMemUseCombo(); | ||
598 | SetNumThreads(); | ||
599 | |||
600 | const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()]; | ||
601 | Info.SolidIsSpecified = fi.Solid_(); | ||
602 | Info.EncryptHeadersIsAllowed = fi.EncryptFileNames_(); | ||
603 | |||
604 | /* | ||
605 | const bool multiThreadEnable = fi.MultiThread; | ||
606 | Info.MultiThreadIsAllowed = multiThreadEnable; | ||
607 | EnableItem(IDC_COMPRESS_SOLID, fi.Solid); | ||
608 | EnableItem(IDC_COMPRESS_THREADS, multiThreadEnable); | ||
609 | const bool methodEnable = (fi.MethodIDs != NULL); | ||
610 | EnableItem(IDC_COMPRESS_METHOD, methodEnable); | ||
611 | EnableMultiCombo(IDC_COMPRESS_DICTIONARY, methodEnable); | ||
612 | EnableItem(IDC_COMPRESS_ORDER, methodEnable); | ||
613 | */ | ||
614 | |||
615 | CheckSFXControlsEnable(); | ||
616 | |||
617 | { | ||
618 | const CArcInfoEx &ai = Get_ArcInfoEx(); | ||
619 | |||
620 | ShowItem_Bool(IDX_COMPRESS_NT_SYM_LINKS, ai.Flags_SymLinks()); | ||
621 | ShowItem_Bool(IDX_COMPRESS_NT_HARD_LINKS, ai.Flags_HardLinks()); | ||
622 | ShowItem_Bool(IDX_COMPRESS_NT_ALT_STREAMS, ai.Flags_AltStreams()); | ||
623 | ShowItem_Bool(IDX_COMPRESS_NT_SECUR, ai.Flags_NtSecure()); | ||
624 | |||
625 | ShowItem_Bool(IDG_COMPRESS_NTFS, | ||
626 | ai.Flags_SymLinks() | ||
627 | || ai.Flags_HardLinks() | ||
628 | || ai.Flags_AltStreams() | ||
629 | || ai.Flags_NtSecure()); | ||
630 | } | ||
631 | // CheckVolumeEnable(); | ||
632 | |||
633 | const bool encrypt = fi.Encrypt_(); | ||
634 | EnableItem(IDG_COMPRESS_ENCRYPTION, encrypt); | ||
635 | |||
636 | EnableItem(IDT_PASSWORD_ENTER, encrypt); | ||
637 | EnableItem(IDT_PASSWORD_REENTER, encrypt); | ||
638 | EnableItem(IDE_COMPRESS_PASSWORD1, encrypt); | ||
639 | EnableItem(IDE_COMPRESS_PASSWORD2, encrypt); | ||
640 | EnableItem(IDX_PASSWORD_SHOW, encrypt); | ||
641 | |||
642 | EnableItem(IDT_COMPRESS_ENCRYPTION_METHOD, encrypt); | ||
643 | EnableItem(IDC_COMPRESS_ENCRYPTION_METHOD, encrypt); | ||
644 | EnableItem(IDX_COMPRESS_ENCRYPT_FILE_NAMES, fi.EncryptFileNames_()); | ||
645 | |||
646 | ShowItem_Bool(IDX_COMPRESS_ENCRYPT_FILE_NAMES, fi.EncryptFileNames_()); | ||
647 | |||
648 | SetEncryptionMethod(); | ||
649 | SetMemoryUsage(); | ||
650 | } | ||
651 | |||
652 | |||
653 | bool CCompressDialog::IsSFX() | ||
654 | { | ||
655 | CWindow sfxButton = GetItem(IDX_COMPRESS_SFX); | ||
656 | return sfxButton.IsEnabled() && IsButtonCheckedBool(IDX_COMPRESS_SFX); | ||
657 | } | ||
658 | |||
659 | static int GetExtDotPos(const UString &s) | ||
660 | { | ||
661 | int dotPos = s.ReverseFind_Dot(); | ||
662 | if (dotPos > s.ReverseFind_PathSepar() + 1) | ||
663 | return dotPos; | ||
664 | return -1; | ||
665 | } | ||
666 | |||
667 | void CCompressDialog::OnButtonSFX() | ||
668 | { | ||
669 | UString fileName; | ||
670 | m_ArchivePath.GetText(fileName); | ||
671 | int dotPos = GetExtDotPos(fileName); | ||
672 | if (IsSFX()) | ||
673 | { | ||
674 | if (dotPos >= 0) | ||
675 | fileName.DeleteFrom(dotPos); | ||
676 | fileName += kExeExt; | ||
677 | m_ArchivePath.SetText(fileName); | ||
678 | } | ||
679 | else | ||
680 | { | ||
681 | if (dotPos >= 0) | ||
682 | { | ||
683 | UString ext = fileName.Ptr(dotPos); | ||
684 | if (ext.IsEqualTo_Ascii_NoCase(kExeExt)) | ||
685 | { | ||
686 | fileName.DeleteFrom(dotPos); | ||
687 | m_ArchivePath.SetText(fileName); | ||
688 | } | ||
689 | } | ||
690 | SetArchiveName2(false); // it's for OnInit | ||
691 | } | ||
692 | |||
693 | // CheckVolumeEnable(); | ||
694 | } | ||
695 | |||
696 | bool CCompressDialog::GetFinalPath_Smart(UString &resPath) | ||
697 | { | ||
698 | UString name; | ||
699 | m_ArchivePath.GetText(name); | ||
700 | name.Trim(); | ||
701 | UString tempPath = name; | ||
702 | if (!IsAbsolutePath(name)) | ||
703 | { | ||
704 | UString newDirPrefix = DirPrefix; | ||
705 | if (newDirPrefix.IsEmpty()) | ||
706 | newDirPrefix = StartDirPrefix; | ||
707 | FString resultF; | ||
708 | if (!MyGetFullPathName(us2fs(newDirPrefix + name), resultF)) | ||
709 | return false; | ||
710 | tempPath = fs2us(resultF); | ||
711 | } | ||
712 | if (!SetArcPathFields(tempPath, name, false)) | ||
713 | return false; | ||
714 | FString resultF; | ||
715 | if (!MyGetFullPathName(us2fs(DirPrefix + name), resultF)) | ||
716 | return false; | ||
717 | resPath = fs2us(resultF); | ||
718 | return true; | ||
719 | } | ||
720 | |||
721 | bool CCompressDialog::SetArcPathFields(const UString &path, UString &name, bool always) | ||
722 | { | ||
723 | FString resDirPrefix; | ||
724 | FString resFileName; | ||
725 | bool res = GetFullPathAndSplit(us2fs(path), resDirPrefix, resFileName); | ||
726 | if (res) | ||
727 | { | ||
728 | DirPrefix = fs2us(resDirPrefix); | ||
729 | name = fs2us(resFileName); | ||
730 | } | ||
731 | else | ||
732 | { | ||
733 | if (!always) | ||
734 | return false; | ||
735 | DirPrefix.Empty(); | ||
736 | name = path; | ||
737 | } | ||
738 | SetItemText(IDT_COMPRESS_ARCHIVE_FOLDER, DirPrefix); | ||
739 | m_ArchivePath.SetText(name); | ||
740 | return res; | ||
741 | } | ||
742 | |||
743 | static const wchar_t * const k_IncorrectPathMessage = L"Incorrect archive path"; | ||
744 | |||
745 | void CCompressDialog::OnButtonSetArchive() | ||
746 | { | ||
747 | UString path; | ||
748 | if (!GetFinalPath_Smart(path)) | ||
749 | { | ||
750 | ShowErrorMessage(*this, k_IncorrectPathMessage); | ||
751 | return; | ||
752 | } | ||
753 | |||
754 | UString title = LangString(IDS_COMPRESS_SET_ARCHIVE_BROWSE); | ||
755 | UString filterDescription = LangString(IDS_OPEN_TYPE_ALL_FILES); | ||
756 | filterDescription += " (*.*)"; | ||
757 | UString resPath; | ||
758 | CurrentDirWasChanged = true; | ||
759 | if (!MyBrowseForFile(*this, title, | ||
760 | // DirPrefix.IsEmpty() ? NULL : (const wchar_t *)DirPrefix, | ||
761 | // NULL, | ||
762 | path, | ||
763 | filterDescription, | ||
764 | NULL, // L"*.*", | ||
765 | resPath)) | ||
766 | return; | ||
767 | UString dummyName; | ||
768 | SetArcPathFields(resPath, dummyName, true); | ||
769 | } | ||
770 | |||
771 | // in ExtractDialog.cpp | ||
772 | extern void AddUniqueString(UStringVector &strings, const UString &srcString); | ||
773 | |||
774 | static bool IsAsciiString(const UString &s) | ||
775 | { | ||
776 | for (unsigned i = 0; i < s.Len(); i++) | ||
777 | { | ||
778 | wchar_t c = s[i]; | ||
779 | if (c < 0x20 || c > 0x7F) | ||
780 | return false; | ||
781 | } | ||
782 | return true; | ||
783 | } | ||
784 | |||
785 | |||
786 | static void AddSize_MB(UString &s, UInt64 size) | ||
787 | { | ||
788 | const UInt64 v2 = size + ((UInt32)1 << 20) - 1; | ||
789 | if (size <= v2) | ||
790 | size = v2; | ||
791 | s.Add_UInt64(size >> 20); | ||
792 | s += " MB"; | ||
793 | } | ||
794 | |||
795 | |||
796 | void SetErrorMessage_MemUsage(UString &s, UInt64 reqSize, UInt64 ramSize, UInt64 ramLimit, const UString &usageString) | ||
797 | { | ||
798 | s += "The operation was blocked by 7-Zip"; | ||
799 | s.Add_LF(); | ||
800 | s += "The operation can require big amount of RAM (memory):"; | ||
801 | s.Add_LF(); | ||
802 | s.Add_LF(); | ||
803 | AddSize_MB(s, reqSize); | ||
804 | |||
805 | if (!usageString.IsEmpty()) | ||
806 | { | ||
807 | s += " : "; | ||
808 | s += usageString; | ||
809 | } | ||
810 | |||
811 | s.Add_LF(); | ||
812 | AddSize_MB(s, ramSize); | ||
813 | s += " : RAM"; | ||
814 | |||
815 | // if (ramLimit != 0) | ||
816 | { | ||
817 | s.Add_LF(); | ||
818 | AddSize_MB(s, ramLimit); | ||
819 | s += " : 7-Zip limit"; | ||
820 | } | ||
821 | |||
822 | s.Add_LF(); | ||
823 | s.Add_LF(); | ||
824 | s += LangString(IDS_MEM_ERROR); | ||
825 | } | ||
826 | |||
827 | |||
828 | void CCompressDialog::OnOK() | ||
829 | { | ||
830 | _password1Control.GetText(Info.Password); | ||
831 | if (IsZipFormat()) | ||
832 | { | ||
833 | if (!IsAsciiString(Info.Password)) | ||
834 | { | ||
835 | ShowErrorMessageHwndRes(*this, IDS_PASSWORD_USE_ASCII); | ||
836 | return; | ||
837 | } | ||
838 | UString method = GetEncryptionMethodSpec(); | ||
839 | if (method.IsPrefixedBy_Ascii_NoCase("aes")) | ||
840 | { | ||
841 | if (Info.Password.Len() > 99) | ||
842 | { | ||
843 | ShowErrorMessageHwndRes(*this, IDS_PASSWORD_TOO_LONG); | ||
844 | return; | ||
845 | } | ||
846 | } | ||
847 | } | ||
848 | if (!IsShowPasswordChecked()) | ||
849 | { | ||
850 | UString password2; | ||
851 | _password2Control.GetText(password2); | ||
852 | if (password2 != Info.Password) | ||
853 | { | ||
854 | ShowErrorMessageHwndRes(*this, IDS_PASSWORD_NOT_MATCH); | ||
855 | return; | ||
856 | } | ||
857 | } | ||
858 | |||
859 | { | ||
860 | UInt64 decompressMem; | ||
861 | const UInt64 memUsage = GetMemoryUsage_DecompMem(decompressMem); | ||
862 | if (memUsage != (UInt64)(Int64)-1) | ||
863 | { | ||
864 | const UInt64 limit = Get_MemUse_Bytes(); | ||
865 | if (memUsage > limit) | ||
866 | { | ||
867 | UString s; | ||
868 | UString s2 = LangString(IDT_COMPRESS_MEMORY); | ||
869 | if (s2.IsEmpty()) | ||
870 | GetItemText(IDT_COMPRESS_MEMORY, s2); | ||
871 | SetErrorMessage_MemUsage(s, memUsage, _ramSize, limit, s2); | ||
872 | MessageBoxError(s); | ||
873 | return; | ||
874 | } | ||
875 | } | ||
876 | } | ||
877 | |||
878 | SaveOptionsInMem(); | ||
879 | { | ||
880 | UString s; | ||
881 | if (!GetFinalPath_Smart(s)) | ||
882 | { | ||
883 | ShowErrorMessage(*this, k_IncorrectPathMessage); | ||
884 | return; | ||
885 | } | ||
886 | |||
887 | m_RegistryInfo.ArcPaths.Clear(); | ||
888 | AddUniqueString(m_RegistryInfo.ArcPaths, s); | ||
889 | Info.ArcPath = s; | ||
890 | } | ||
891 | |||
892 | Info.UpdateMode = (NCompressDialog::NUpdateMode::EEnum)k_UpdateMode_Vals[m_UpdateMode.GetCurSel()];; | ||
893 | Info.PathMode = (NWildcard::ECensorPathMode)k_PathMode_Vals[m_PathMode.GetCurSel()]; | ||
894 | |||
895 | Info.Level = GetLevelSpec(); | ||
896 | Info.Dict64 = GetDictSpec(); | ||
897 | Info.Order = GetOrderSpec(); | ||
898 | Info.OrderMode = GetOrderMode(); | ||
899 | Info.NumThreads = GetNumThreadsSpec(); | ||
900 | |||
901 | Info.MemUsage.Clear(); | ||
902 | { | ||
903 | const UString mus = Get_MemUse_Spec(); | ||
904 | if (!mus.IsEmpty()) | ||
905 | { | ||
906 | NCompression::CMemUse mu; | ||
907 | mu.Parse(mus); | ||
908 | if (mu.IsDefined) | ||
909 | Info.MemUsage = mu; | ||
910 | } | ||
911 | } | ||
912 | |||
913 | { | ||
914 | // Info.SolidIsSpecified = g_Formats[GetStaticFormatIndex()].Solid; | ||
915 | const UInt32 solidLogSize = GetBlockSizeSpec(); | ||
916 | Info.SolidBlockSize = 0; | ||
917 | if (solidLogSize == (UInt32)(Int32)-1) | ||
918 | Info.SolidIsSpecified = false; | ||
919 | else if (solidLogSize > 0) | ||
920 | Info.SolidBlockSize = (solidLogSize >= 64) ? | ||
921 | (UInt64)(Int64)-1 : | ||
922 | ((UInt64)1 << solidLogSize); | ||
923 | } | ||
924 | |||
925 | Info.Method = GetMethodSpec(); | ||
926 | Info.EncryptionMethod = GetEncryptionMethodSpec(); | ||
927 | Info.FormatIndex = GetFormatIndex(); | ||
928 | Info.SFXMode = IsSFX(); | ||
929 | Info.OpenShareForWrite = IsButtonCheckedBool(IDX_COMPRESS_SHARED); | ||
930 | Info.DeleteAfterCompressing = IsButtonCheckedBool(IDX_COMPRESS_DEL); | ||
931 | |||
932 | m_RegistryInfo.EncryptHeaders = | ||
933 | Info.EncryptHeaders = IsButtonCheckedBool(IDX_COMPRESS_ENCRYPT_FILE_NAMES); | ||
934 | |||
935 | |||
936 | GetButton_Bools(IDX_COMPRESS_NT_SYM_LINKS, Info.SymLinks, m_RegistryInfo.SymLinks); | ||
937 | GetButton_Bools(IDX_COMPRESS_NT_HARD_LINKS, Info.HardLinks, m_RegistryInfo.HardLinks); | ||
938 | GetButton_Bools(IDX_COMPRESS_NT_ALT_STREAMS, Info.AltStreams, m_RegistryInfo.AltStreams); | ||
939 | GetButton_Bools(IDX_COMPRESS_NT_SECUR, Info.NtSecurity, m_RegistryInfo.NtSecurity); | ||
940 | |||
941 | { | ||
942 | const CArcInfoEx &ai = Get_ArcInfoEx(); | ||
943 | if (!ai.Flags_SymLinks()) Info.SymLinks.Val = false; | ||
944 | if (!ai.Flags_HardLinks()) Info.HardLinks.Val = false; | ||
945 | if (!ai.Flags_AltStreams()) Info.AltStreams.Val = false; | ||
946 | if (!ai.Flags_NtSecure()) Info.NtSecurity.Val = false; | ||
947 | } | ||
948 | |||
949 | m_Params.GetText(Info.Options); | ||
950 | |||
951 | UString volumeString; | ||
952 | m_Volume.GetText(volumeString); | ||
953 | volumeString.Trim(); | ||
954 | Info.VolumeSizes.Clear(); | ||
955 | |||
956 | if (!volumeString.IsEmpty()) | ||
957 | { | ||
958 | if (!ParseVolumeSizes(volumeString, Info.VolumeSizes)) | ||
959 | { | ||
960 | ShowErrorMessageHwndRes(*this, IDS_INCORRECT_VOLUME_SIZE); | ||
961 | return; | ||
962 | } | ||
963 | if (!Info.VolumeSizes.IsEmpty()) | ||
964 | { | ||
965 | const UInt64 volumeSize = Info.VolumeSizes.Back(); | ||
966 | if (volumeSize < (100 << 10)) | ||
967 | { | ||
968 | wchar_t s[32]; | ||
969 | ConvertUInt64ToString(volumeSize, s); | ||
970 | if (::MessageBoxW(*this, MyFormatNew(IDS_SPLIT_CONFIRM, s), | ||
971 | L"7-Zip", MB_YESNOCANCEL | MB_ICONQUESTION) != IDYES) | ||
972 | return; | ||
973 | } | ||
974 | } | ||
975 | } | ||
976 | |||
977 | for (int i = 0; i < m_ArchivePath.GetCount(); i++) | ||
978 | { | ||
979 | UString sTemp; | ||
980 | m_ArchivePath.GetLBText(i, sTemp); | ||
981 | sTemp.Trim(); | ||
982 | AddUniqueString(m_RegistryInfo.ArcPaths, sTemp); | ||
983 | } | ||
984 | |||
985 | if (m_RegistryInfo.ArcPaths.Size() > kHistorySize) | ||
986 | m_RegistryInfo.ArcPaths.DeleteBack(); | ||
987 | |||
988 | if (Info.FormatIndex >= 0) | ||
989 | m_RegistryInfo.ArcType = (*ArcFormats)[Info.FormatIndex].Name; | ||
990 | m_RegistryInfo.ShowPassword = IsShowPasswordChecked(); | ||
991 | |||
992 | m_RegistryInfo.Save(); | ||
993 | |||
994 | CModalDialog::OnOK(); | ||
995 | } | ||
996 | |||
997 | #define kHelpTopic "fm/plugins/7-zip/add.htm" | ||
998 | |||
999 | void CCompressDialog::OnHelp() | ||
1000 | { | ||
1001 | ShowHelpWindow(kHelpTopic); | ||
1002 | } | ||
1003 | |||
1004 | bool CCompressDialog::OnCommand(int code, int itemID, LPARAM lParam) | ||
1005 | { | ||
1006 | if (code == CBN_SELCHANGE) | ||
1007 | { | ||
1008 | switch (itemID) | ||
1009 | { | ||
1010 | case IDC_COMPRESS_ARCHIVE: | ||
1011 | { | ||
1012 | // we can 't change m_ArchivePath in that handler ! | ||
1013 | DirPrefix.Empty(); | ||
1014 | SetItemText(IDT_COMPRESS_ARCHIVE_FOLDER, DirPrefix); | ||
1015 | |||
1016 | /* | ||
1017 | UString path; | ||
1018 | m_ArchivePath.GetText(path); | ||
1019 | m_ArchivePath.SetText(L""); | ||
1020 | if (IsAbsolutePath(path)) | ||
1021 | { | ||
1022 | UString fileName; | ||
1023 | SetArcPathFields(path, fileName); | ||
1024 | SetArchiveName(fileName); | ||
1025 | } | ||
1026 | */ | ||
1027 | return true; | ||
1028 | } | ||
1029 | |||
1030 | case IDC_COMPRESS_FORMAT: | ||
1031 | { | ||
1032 | const bool isSFX = IsSFX(); | ||
1033 | SaveOptionsInMem(); | ||
1034 | FormatChanged(); | ||
1035 | SetArchiveName2(isSFX); | ||
1036 | return true; | ||
1037 | } | ||
1038 | |||
1039 | case IDC_COMPRESS_LEVEL: | ||
1040 | { | ||
1041 | Get_FormatOptions().ResetForLevelChange(); | ||
1042 | |||
1043 | SetMethod(); | ||
1044 | SetSolidBlockSize(); | ||
1045 | SetNumThreads(); | ||
1046 | CheckSFXNameChange(); | ||
1047 | SetMemoryUsage(); | ||
1048 | return true; | ||
1049 | } | ||
1050 | |||
1051 | case IDC_COMPRESS_METHOD: | ||
1052 | { | ||
1053 | MethodChanged(); | ||
1054 | SetSolidBlockSize(); | ||
1055 | SetNumThreads(); | ||
1056 | CheckSFXNameChange(); | ||
1057 | SetMemoryUsage(); | ||
1058 | if (Get_ArcInfoEx().Flags_HashHandler()) | ||
1059 | SetArchiveName2(false); | ||
1060 | return true; | ||
1061 | } | ||
1062 | |||
1063 | case IDC_COMPRESS_DICTIONARY: | ||
1064 | { | ||
1065 | /* we want to change the reported threads for Auto line | ||
1066 | and keep selected NumThreads option | ||
1067 | So we save selected NumThreads option in memory */ | ||
1068 | SaveOptionsInMem(); | ||
1069 | const UInt32 blockSizeLog = GetBlockSizeSpec(); | ||
1070 | if (// blockSizeLog != (UInt32)(Int32)-1 && | ||
1071 | blockSizeLog != kSolidLog_NoSolid | ||
1072 | && blockSizeLog != kSolidLog_FullSolid) | ||
1073 | { | ||
1074 | Get_FormatOptions().Reset_BlockLogSize(); | ||
1075 | // SetSolidBlockSize(true); | ||
1076 | } | ||
1077 | |||
1078 | SetSolidBlockSize(); | ||
1079 | SetNumThreads(); // we want to change the reported threads for Auto line only | ||
1080 | SetMemoryUsage(); | ||
1081 | return true; | ||
1082 | } | ||
1083 | |||
1084 | case IDC_COMPRESS_ORDER: | ||
1085 | return true; | ||
1086 | |||
1087 | case IDC_COMPRESS_SOLID: | ||
1088 | { | ||
1089 | SetMemoryUsage(); | ||
1090 | return true; | ||
1091 | } | ||
1092 | |||
1093 | case IDC_COMPRESS_THREADS: | ||
1094 | { | ||
1095 | SetMemoryUsage(); | ||
1096 | return true; | ||
1097 | } | ||
1098 | |||
1099 | case IDC_COMPRESS_MEM_USE: | ||
1100 | { | ||
1101 | /* we want to change the reported threads for Auto line | ||
1102 | and keep selected NumThreads option | ||
1103 | So we save selected NumThreads option in memory */ | ||
1104 | SaveOptionsInMem(); | ||
1105 | |||
1106 | SetNumThreads(); // we want to change the reported threads for Auto line only | ||
1107 | SetMemoryUsage(); | ||
1108 | return true; | ||
1109 | } | ||
1110 | } | ||
1111 | } | ||
1112 | return CModalDialog::OnCommand(code, itemID, lParam); | ||
1113 | } | ||
1114 | |||
1115 | void CCompressDialog::CheckSFXNameChange() | ||
1116 | { | ||
1117 | const bool isSFX = IsSFX(); | ||
1118 | CheckSFXControlsEnable(); | ||
1119 | if (isSFX != IsSFX()) | ||
1120 | SetArchiveName2(isSFX); | ||
1121 | } | ||
1122 | |||
1123 | void CCompressDialog::SetArchiveName2(bool prevWasSFX) | ||
1124 | { | ||
1125 | UString fileName; | ||
1126 | m_ArchivePath.GetText(fileName); | ||
1127 | const CArcInfoEx &prevArchiverInfo = (*ArcFormats)[m_PrevFormat]; | ||
1128 | if (prevArchiverInfo.Flags_KeepName() || Info.KeepName) | ||
1129 | { | ||
1130 | UString prevExtension; | ||
1131 | if (prevWasSFX) | ||
1132 | prevExtension = kExeExt; | ||
1133 | else | ||
1134 | { | ||
1135 | prevExtension += '.'; | ||
1136 | prevExtension += prevArchiverInfo.GetMainExt(); | ||
1137 | } | ||
1138 | const unsigned prevExtensionLen = prevExtension.Len(); | ||
1139 | if (fileName.Len() >= prevExtensionLen) | ||
1140 | if (StringsAreEqualNoCase(fileName.RightPtr(prevExtensionLen), prevExtension)) | ||
1141 | fileName.DeleteFrom(fileName.Len() - prevExtensionLen); | ||
1142 | } | ||
1143 | SetArchiveName(fileName); | ||
1144 | } | ||
1145 | |||
1146 | // if type.KeepName then use OriginalFileName | ||
1147 | // else if !KeepName remove extension | ||
1148 | // add new extension | ||
1149 | |||
1150 | void CCompressDialog::SetArchiveName(const UString &name) | ||
1151 | { | ||
1152 | UString fileName = name; | ||
1153 | Info.FormatIndex = GetFormatIndex(); | ||
1154 | const CArcInfoEx &ai = (*ArcFormats)[Info.FormatIndex]; | ||
1155 | m_PrevFormat = Info.FormatIndex; | ||
1156 | if (ai.Flags_KeepName()) | ||
1157 | { | ||
1158 | fileName = OriginalFileName; | ||
1159 | } | ||
1160 | else | ||
1161 | { | ||
1162 | if (!Info.KeepName) | ||
1163 | { | ||
1164 | int dotPos = GetExtDotPos(fileName); | ||
1165 | if (dotPos >= 0) | ||
1166 | fileName.DeleteFrom(dotPos); | ||
1167 | } | ||
1168 | } | ||
1169 | |||
1170 | if (IsSFX()) | ||
1171 | fileName += kExeExt; | ||
1172 | else | ||
1173 | { | ||
1174 | fileName += '.'; | ||
1175 | UString ext = ai.GetMainExt(); | ||
1176 | if (ai.Flags_HashHandler()) | ||
1177 | { | ||
1178 | UString estimatedName; | ||
1179 | GetMethodSpec(estimatedName); | ||
1180 | if (!estimatedName.IsEmpty()) | ||
1181 | { | ||
1182 | ext = estimatedName; | ||
1183 | ext.MakeLower_Ascii(); | ||
1184 | } | ||
1185 | } | ||
1186 | fileName += ext; | ||
1187 | } | ||
1188 | m_ArchivePath.SetText(fileName); | ||
1189 | } | ||
1190 | |||
1191 | int CCompressDialog::FindRegistryFormat(const UString &name) | ||
1192 | { | ||
1193 | FOR_VECTOR (i, m_RegistryInfo.Formats) | ||
1194 | { | ||
1195 | const NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[i]; | ||
1196 | if (name.IsEqualTo_NoCase(GetUnicodeString(fo.FormatID))) | ||
1197 | return i; | ||
1198 | } | ||
1199 | return -1; | ||
1200 | } | ||
1201 | |||
1202 | int CCompressDialog::FindRegistryFormatAlways(const UString &name) | ||
1203 | { | ||
1204 | int index = FindRegistryFormat(name); | ||
1205 | if (index < 0) | ||
1206 | { | ||
1207 | NCompression::CFormatOptions fo; | ||
1208 | fo.FormatID = GetSystemString(name); | ||
1209 | index = m_RegistryInfo.Formats.Add(fo); | ||
1210 | } | ||
1211 | return index; | ||
1212 | } | ||
1213 | |||
1214 | int CCompressDialog::GetStaticFormatIndex() | ||
1215 | { | ||
1216 | const CArcInfoEx &ai = Get_ArcInfoEx(); | ||
1217 | for (unsigned i = 0; i < ARRAY_SIZE(g_Formats); i++) | ||
1218 | if (ai.Name.IsEqualTo_Ascii_NoCase(g_Formats[i].Name)) | ||
1219 | return i; | ||
1220 | return 0; // -1; | ||
1221 | } | ||
1222 | |||
1223 | void CCompressDialog::SetNearestSelectComboBox(NControl::CComboBox &comboBox, UInt32 value) | ||
1224 | { | ||
1225 | for (int i = comboBox.GetCount() - 1; i >= 0; i--) | ||
1226 | if ((UInt32)comboBox.GetItemData(i) <= value) | ||
1227 | { | ||
1228 | comboBox.SetCurSel(i); | ||
1229 | return; | ||
1230 | } | ||
1231 | if (comboBox.GetCount() > 0) | ||
1232 | comboBox.SetCurSel(0); | ||
1233 | } | ||
1234 | |||
1235 | void CCompressDialog::SetLevel2() | ||
1236 | { | ||
1237 | m_Level.ResetContent(); | ||
1238 | const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()]; | ||
1239 | const CArcInfoEx &ai = Get_ArcInfoEx(); | ||
1240 | UInt32 level = 5; | ||
1241 | { | ||
1242 | int index = FindRegistryFormat(ai.Name); | ||
1243 | if (index >= 0) | ||
1244 | { | ||
1245 | const NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index]; | ||
1246 | if (fo.Level <= 9) | ||
1247 | level = fo.Level; | ||
1248 | else if (fo.Level == (UInt32)(Int32)-1) | ||
1249 | level = 5; | ||
1250 | else | ||
1251 | level = 9; | ||
1252 | } | ||
1253 | } | ||
1254 | |||
1255 | for (unsigned i = 0; i < sizeof(UInt32) * 8; i++) | ||
1256 | { | ||
1257 | const UInt32 mask = (UInt32)1 << i; | ||
1258 | if ((fi.LevelsMask & mask) != 0) | ||
1259 | { | ||
1260 | UInt32 langID = g_Levels[i]; | ||
1261 | UString s; | ||
1262 | s.Add_UInt32(i); | ||
1263 | s += " - "; | ||
1264 | s += LangString(langID); | ||
1265 | int index = (int)m_Level.AddString(s); | ||
1266 | m_Level.SetItemData(index, i); | ||
1267 | } | ||
1268 | if (fi.LevelsMask <= mask) | ||
1269 | break; | ||
1270 | } | ||
1271 | SetNearestSelectComboBox(m_Level, level); | ||
1272 | } | ||
1273 | |||
1274 | |||
1275 | static LRESULT ComboBox_AddStringAscii(NControl::CComboBox &cb, const char *s) | ||
1276 | { | ||
1277 | return cb.AddString((CSysString)s); | ||
1278 | } | ||
1279 | |||
1280 | // static const char *k_Auto = "- "; // "auto : "; | ||
1281 | |||
1282 | static void Modify_Auto(AString &s) | ||
1283 | { | ||
1284 | s.Insert(0, "* "); | ||
1285 | // s += " -"; | ||
1286 | } | ||
1287 | |||
1288 | void CCompressDialog::SetMethod2(int keepMethodId) | ||
1289 | { | ||
1290 | m_Method.ResetContent(); | ||
1291 | _auto_MethodId = -1; | ||
1292 | const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()]; | ||
1293 | const CArcInfoEx &ai = Get_ArcInfoEx(); | ||
1294 | if (GetLevel() == 0 && !ai.Flags_HashHandler()) | ||
1295 | { | ||
1296 | MethodChanged(); | ||
1297 | return; | ||
1298 | } | ||
1299 | UString defaultMethod; | ||
1300 | { | ||
1301 | const int index = FindRegistryFormat(ai.Name); | ||
1302 | if (index >= 0) | ||
1303 | { | ||
1304 | const NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index]; | ||
1305 | defaultMethod = fo.Method; | ||
1306 | } | ||
1307 | } | ||
1308 | const bool isSfx = IsSFX(); | ||
1309 | bool weUseSameMethod = false; | ||
1310 | |||
1311 | const bool is7z = ai.Name.IsEqualTo_Ascii_NoCase("7z"); | ||
1312 | |||
1313 | for (unsigned m = 0;; m++) | ||
1314 | { | ||
1315 | int methodID; | ||
1316 | const char *method; | ||
1317 | if (m < fi.NumMethods) | ||
1318 | { | ||
1319 | methodID = fi.MethodIDs[m]; | ||
1320 | method = kMethodsNames[methodID]; | ||
1321 | if (is7z) | ||
1322 | if (methodID == kCopy | ||
1323 | || methodID == kDeflate | ||
1324 | || methodID == kDeflate64 | ||
1325 | ) | ||
1326 | continue; | ||
1327 | } | ||
1328 | else | ||
1329 | { | ||
1330 | if (!is7z) | ||
1331 | break; | ||
1332 | unsigned extIndex = m - fi.NumMethods; | ||
1333 | if (extIndex >= ExternalMethods.Size()) | ||
1334 | break; | ||
1335 | methodID = ARRAY_SIZE(kMethodsNames) + extIndex; | ||
1336 | method = ExternalMethods[extIndex].Ptr(); | ||
1337 | } | ||
1338 | if (isSfx) | ||
1339 | if (!IsMethodSupportedBySfx(methodID)) | ||
1340 | continue; | ||
1341 | |||
1342 | AString s (method); | ||
1343 | int writtenMethodId = methodID; | ||
1344 | if (m == 0) | ||
1345 | { | ||
1346 | _auto_MethodId = methodID; | ||
1347 | writtenMethodId = -1; | ||
1348 | Modify_Auto(s); | ||
1349 | } | ||
1350 | const int itemIndex = (int)ComboBox_AddStringAscii(m_Method, s); | ||
1351 | m_Method.SetItemData(itemIndex, writtenMethodId); | ||
1352 | if (keepMethodId == methodID) | ||
1353 | { | ||
1354 | m_Method.SetCurSel(itemIndex); | ||
1355 | weUseSameMethod = true; | ||
1356 | continue; | ||
1357 | } | ||
1358 | if ((defaultMethod.IsEqualTo_Ascii_NoCase(method) || m == 0) && !weUseSameMethod) | ||
1359 | m_Method.SetCurSel(itemIndex); | ||
1360 | } | ||
1361 | |||
1362 | if (!weUseSameMethod) | ||
1363 | MethodChanged(); | ||
1364 | } | ||
1365 | |||
1366 | |||
1367 | |||
1368 | bool CCompressDialog::IsZipFormat() | ||
1369 | { | ||
1370 | return Get_ArcInfoEx().Name.IsEqualTo_Ascii_NoCase("zip"); | ||
1371 | } | ||
1372 | |||
1373 | bool CCompressDialog::IsXzFormat() | ||
1374 | { | ||
1375 | return Get_ArcInfoEx().Name.IsEqualTo_Ascii_NoCase("xz"); | ||
1376 | } | ||
1377 | |||
1378 | void CCompressDialog::SetEncryptionMethod() | ||
1379 | { | ||
1380 | _encryptionMethod.ResetContent(); | ||
1381 | _default_encryptionMethod_Index = -1; | ||
1382 | const CArcInfoEx &ai = Get_ArcInfoEx(); | ||
1383 | if (ai.Name.IsEqualTo_Ascii_NoCase("7z")) | ||
1384 | { | ||
1385 | ComboBox_AddStringAscii(_encryptionMethod, "AES-256"); | ||
1386 | _encryptionMethod.SetCurSel(0); | ||
1387 | _default_encryptionMethod_Index = 0; | ||
1388 | } | ||
1389 | else if (ai.Name.IsEqualTo_Ascii_NoCase("zip")) | ||
1390 | { | ||
1391 | int index = FindRegistryFormat(ai.Name); | ||
1392 | UString encryptionMethod; | ||
1393 | if (index >= 0) | ||
1394 | { | ||
1395 | const NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index]; | ||
1396 | encryptionMethod = fo.EncryptionMethod; | ||
1397 | } | ||
1398 | int sel = 0; | ||
1399 | // if (ZipCryptoIsAllowed) | ||
1400 | { | ||
1401 | ComboBox_AddStringAscii(_encryptionMethod, "ZipCrypto"); | ||
1402 | sel = (encryptionMethod.IsPrefixedBy_Ascii_NoCase("aes") ? 1 : 0); | ||
1403 | _default_encryptionMethod_Index = 0; | ||
1404 | } | ||
1405 | ComboBox_AddStringAscii(_encryptionMethod, "AES-256"); | ||
1406 | _encryptionMethod.SetCurSel(sel); | ||
1407 | } | ||
1408 | } | ||
1409 | |||
1410 | |||
1411 | int CCompressDialog::GetMethodID_RAW() | ||
1412 | { | ||
1413 | if (m_Method.GetCount() <= 0) | ||
1414 | return -1; | ||
1415 | return (int)(Int32)(UInt32)m_Method.GetItemData_of_CurSel(); | ||
1416 | } | ||
1417 | |||
1418 | int CCompressDialog::GetMethodID() | ||
1419 | { | ||
1420 | int raw = GetMethodID_RAW(); | ||
1421 | if (raw < 0) | ||
1422 | return _auto_MethodId; | ||
1423 | return raw; | ||
1424 | } | ||
1425 | |||
1426 | |||
1427 | UString CCompressDialog::GetMethodSpec(UString &estimatedName) | ||
1428 | { | ||
1429 | estimatedName.Empty(); | ||
1430 | if (m_Method.GetCount() < 1) | ||
1431 | return estimatedName; | ||
1432 | const int methodIdRaw = GetMethodID_RAW(); | ||
1433 | int methodId = methodIdRaw; | ||
1434 | if (methodIdRaw < 0) | ||
1435 | methodId = _auto_MethodId; | ||
1436 | UString s; | ||
1437 | if (methodId >= 0) | ||
1438 | { | ||
1439 | if ((unsigned)methodId < ARRAY_SIZE(kMethodsNames)) | ||
1440 | estimatedName = kMethodsNames[methodId]; | ||
1441 | else | ||
1442 | estimatedName = ExternalMethods[methodId - ARRAY_SIZE(kMethodsNames)]; | ||
1443 | if (methodIdRaw >= 0) | ||
1444 | s = estimatedName; | ||
1445 | } | ||
1446 | return s; | ||
1447 | } | ||
1448 | |||
1449 | |||
1450 | UString CCompressDialog::GetMethodSpec() | ||
1451 | { | ||
1452 | UString estimatedName; | ||
1453 | UString s = GetMethodSpec(estimatedName); | ||
1454 | return s; | ||
1455 | } | ||
1456 | |||
1457 | bool CCompressDialog::IsMethodEqualTo(const UString &s) | ||
1458 | { | ||
1459 | UString estimatedName; | ||
1460 | const UString shortName = GetMethodSpec(estimatedName); | ||
1461 | if (s.IsEmpty()) | ||
1462 | return shortName.IsEmpty(); | ||
1463 | return s.IsEqualTo_NoCase(estimatedName); | ||
1464 | } | ||
1465 | |||
1466 | |||
1467 | UString CCompressDialog::GetEncryptionMethodSpec() | ||
1468 | { | ||
1469 | UString s; | ||
1470 | if (_encryptionMethod.GetCount() > 0 | ||
1471 | && _encryptionMethod.GetCurSel() != _default_encryptionMethod_Index) | ||
1472 | { | ||
1473 | _encryptionMethod.GetText(s); | ||
1474 | s.RemoveChar(L'-'); | ||
1475 | } | ||
1476 | return s; | ||
1477 | } | ||
1478 | |||
1479 | static const size_t k_Auto_Dict = (size_t)0 - 1; | ||
1480 | |||
1481 | |||
1482 | int CCompressDialog::AddDict2(size_t sizeReal, size_t sizeShow) | ||
1483 | { | ||
1484 | char c = 0; | ||
1485 | unsigned moveBits = 0; | ||
1486 | if ((sizeShow & 0xFFFFF) == 0) { moveBits = 20; c = 'M'; } | ||
1487 | else if ((sizeShow & 0x3FF) == 0) { moveBits = 10; c = 'K'; } | ||
1488 | AString s; | ||
1489 | s.Add_UInt64(sizeShow >> moveBits); | ||
1490 | s.Add_Space(); | ||
1491 | if (moveBits != 0) | ||
1492 | s += c; | ||
1493 | s += 'B'; | ||
1494 | if (sizeReal == k_Auto_Dict) | ||
1495 | Modify_Auto(s); | ||
1496 | const int index = (int)ComboBox_AddStringAscii(m_Dictionary, s); | ||
1497 | m_Dictionary.SetItemData(index, sizeReal); | ||
1498 | return index; | ||
1499 | } | ||
1500 | |||
1501 | |||
1502 | int CCompressDialog::AddDict(size_t size) | ||
1503 | { | ||
1504 | return AddDict2(size, size); | ||
1505 | } | ||
1506 | |||
1507 | |||
1508 | void CCompressDialog::SetDictionary2() | ||
1509 | { | ||
1510 | m_Dictionary.ResetContent(); | ||
1511 | // _auto_Dict = (UInt32)1 << 24; // we can use this dictSize to calculate _auto_Solid for unknown method for 7z | ||
1512 | _auto_Dict = (UInt32)(Int32)-1; // for debug: | ||
1513 | |||
1514 | const CArcInfoEx &ai = Get_ArcInfoEx(); | ||
1515 | UInt32 defaultDict = (UInt32)(Int32)-1; | ||
1516 | { | ||
1517 | const int index = FindRegistryFormat(ai.Name); | ||
1518 | if (index >= 0) | ||
1519 | { | ||
1520 | const NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index]; | ||
1521 | if (IsMethodEqualTo(fo.Method)) | ||
1522 | defaultDict = fo.Dictionary; | ||
1523 | } | ||
1524 | } | ||
1525 | |||
1526 | const int methodID = GetMethodID(); | ||
1527 | const UInt32 level = GetLevel2(); | ||
1528 | if (methodID < 0) | ||
1529 | return; | ||
1530 | |||
1531 | switch (methodID) | ||
1532 | { | ||
1533 | case kLZMA: | ||
1534 | case kLZMA2: | ||
1535 | { | ||
1536 | { | ||
1537 | _auto_Dict = | ||
1538 | ( level <= 3 ? ((UInt32)1 << (level * 2 + 16)) : | ||
1539 | ( level <= 6 ? ((UInt32)1 << (level + 19)) : | ||
1540 | ( level <= 7 ? ((UInt32)1 << 25) : ((UInt32)1 << 26) | ||
1541 | ))); | ||
1542 | } | ||
1543 | |||
1544 | // we use threshold 3.75 GiB to switch to kLzmaMaxDictSize. | ||
1545 | if (defaultDict != (UInt32)(Int32)-1 | ||
1546 | && defaultDict >= ((UInt32)15 << 28)) | ||
1547 | defaultDict = kLzmaMaxDictSize; | ||
1548 | |||
1549 | const size_t kLzmaMaxDictSize_Up = (size_t)1 << (20 + sizeof(size_t) / 4 * 6); | ||
1550 | |||
1551 | int curSel = AddDict2(k_Auto_Dict, _auto_Dict); | ||
1552 | |||
1553 | for (unsigned i = (16 - 1) * 2; i <= (32 - 1) * 2; i++) | ||
1554 | { | ||
1555 | if (i < (20 - 1) * 2 | ||
1556 | && i != (16 - 1) * 2 | ||
1557 | && i != (18 - 1) * 2) | ||
1558 | continue; | ||
1559 | if (i == (20 - 1) * 2 + 1) | ||
1560 | continue; | ||
1561 | const size_t dict_up = (size_t)(2 + (i & 1)) << (i / 2); | ||
1562 | size_t dict = dict_up; | ||
1563 | if (dict_up >= kLzmaMaxDictSize) | ||
1564 | dict = kLzmaMaxDictSize; // we reduce dictionary | ||
1565 | |||
1566 | const int index = AddDict(dict); | ||
1567 | // AddDict2(dict, dict_up); // for debug : we show 4 GB | ||
1568 | |||
1569 | // const UInt32 numThreads = 2; | ||
1570 | // const UInt64 memUsage = GetMemoryUsageComp_Threads_Dict(numThreads, dict); | ||
1571 | if (defaultDict != (UInt32)(Int32)-1) | ||
1572 | if (dict <= defaultDict || curSel <= 0) | ||
1573 | // if (!maxRamSize_Defined || memUsage <= maxRamSize) | ||
1574 | curSel = index; | ||
1575 | if (dict_up >= kLzmaMaxDictSize_Up) | ||
1576 | break; | ||
1577 | } | ||
1578 | |||
1579 | m_Dictionary.SetCurSel(curSel); | ||
1580 | break; | ||
1581 | } | ||
1582 | |||
1583 | case kPPMd: | ||
1584 | { | ||
1585 | _auto_Dict = (UInt32)1 << (level + 19); | ||
1586 | |||
1587 | const UInt32 kPpmd_Default_4g = (UInt32)0 - ((UInt32)1 << 10); | ||
1588 | const size_t kPpmd_MaxDictSize_Up = (size_t)1 << (29 + sizeof(size_t) / 8); | ||
1589 | |||
1590 | if (defaultDict != (UInt32)(Int32)-1 | ||
1591 | && defaultDict >= ((UInt32)15 << 28)) // threshold | ||
1592 | defaultDict = kPpmd_Default_4g; | ||
1593 | |||
1594 | int curSel = AddDict2(k_Auto_Dict, _auto_Dict); | ||
1595 | |||
1596 | for (unsigned i = (20 - 1) * 2; i <= (32 - 1) * 2; i++) | ||
1597 | { | ||
1598 | if (i == (20 - 1) * 2 + 1) | ||
1599 | continue; | ||
1600 | |||
1601 | const size_t dict_up = (size_t)(2 + (i & 1)) << (i / 2); | ||
1602 | size_t dict = dict_up; | ||
1603 | if (dict_up >= kPpmd_Default_4g) | ||
1604 | dict = kPpmd_Default_4g; | ||
1605 | |||
1606 | const int index = AddDict2(dict, dict_up); | ||
1607 | // AddDict2((UInt32)((UInt32)0 - 2), dict_up); // for debug | ||
1608 | // AddDict(dict_up); // for debug | ||
1609 | // const UInt64 memUsage = GetMemoryUsageComp_Threads_Dict(1, dict); | ||
1610 | if (defaultDict != (UInt32)(Int32)-1) | ||
1611 | if (dict <= defaultDict || curSel <= 0) | ||
1612 | // if (!maxRamSize_Defined || memUsage <= maxRamSize) | ||
1613 | curSel = index; | ||
1614 | if (dict_up >= kPpmd_MaxDictSize_Up) | ||
1615 | break; | ||
1616 | } | ||
1617 | m_Dictionary.SetCurSel(curSel); | ||
1618 | break; | ||
1619 | } | ||
1620 | |||
1621 | case kPPMdZip: | ||
1622 | { | ||
1623 | _auto_Dict = (UInt32)1 << (level + 19); | ||
1624 | |||
1625 | int curSel = AddDict2(k_Auto_Dict, _auto_Dict); | ||
1626 | |||
1627 | for (unsigned i = 20; i <= 28; i++) | ||
1628 | { | ||
1629 | const UInt32 dict = (UInt32)1 << i; | ||
1630 | const int index = AddDict(dict); | ||
1631 | // const UInt64 memUsage = GetMemoryUsageComp_Threads_Dict(1, dict); | ||
1632 | if (defaultDict != (UInt32)(Int32)-1) | ||
1633 | if (dict <= defaultDict || curSel <= 0) | ||
1634 | // if (!maxRamSize_Defined || memUsage <= maxRamSize) | ||
1635 | curSel = index; | ||
1636 | } | ||
1637 | m_Dictionary.SetCurSel(curSel); | ||
1638 | break; | ||
1639 | } | ||
1640 | |||
1641 | case kDeflate: | ||
1642 | case kDeflate64: | ||
1643 | { | ||
1644 | const UInt32 dict = (methodID == kDeflate ? (UInt32)(1 << 15) : (UInt32)(1 << 16)); | ||
1645 | _auto_Dict = dict; | ||
1646 | AddDict2(k_Auto_Dict, _auto_Dict); | ||
1647 | m_Dictionary.SetCurSel(0); | ||
1648 | // EnableItem(IDC_COMPRESS_DICTIONARY, false); | ||
1649 | break; | ||
1650 | } | ||
1651 | |||
1652 | case kBZip2: | ||
1653 | { | ||
1654 | { | ||
1655 | if (level >= 5) _auto_Dict = (900 << 10); | ||
1656 | else if (level >= 3) _auto_Dict = (500 << 10); | ||
1657 | else _auto_Dict = (100 << 10); | ||
1658 | } | ||
1659 | |||
1660 | int curSel = AddDict2(k_Auto_Dict, _auto_Dict); | ||
1661 | |||
1662 | for (unsigned i = 1; i <= 9; i++) | ||
1663 | { | ||
1664 | const UInt32 dict = ((UInt32)i * 100) << 10; | ||
1665 | AddDict(dict); | ||
1666 | // AddDict2(i * 100000, dict); | ||
1667 | if (defaultDict != (UInt32)(Int32)-1) | ||
1668 | if (i <= defaultDict / 100000 || curSel <= 0) | ||
1669 | curSel = m_Dictionary.GetCount() - 1; | ||
1670 | } | ||
1671 | m_Dictionary.SetCurSel(curSel); | ||
1672 | break; | ||
1673 | } | ||
1674 | |||
1675 | case kCopy: | ||
1676 | { | ||
1677 | _auto_Dict = 0; | ||
1678 | AddDict(0); | ||
1679 | m_Dictionary.SetCurSel(0); | ||
1680 | break; | ||
1681 | } | ||
1682 | } | ||
1683 | } | ||
1684 | |||
1685 | |||
1686 | UInt32 CCompressDialog::GetComboValue(NWindows::NControl::CComboBox &c, int defMax) | ||
1687 | { | ||
1688 | if (c.GetCount() <= defMax) | ||
1689 | return (UInt32)(Int32)-1; | ||
1690 | return (UInt32)c.GetItemData_of_CurSel(); | ||
1691 | } | ||
1692 | |||
1693 | |||
1694 | UInt64 CCompressDialog::GetComboValue_64(NWindows::NControl::CComboBox &c, int defMax) | ||
1695 | { | ||
1696 | if (c.GetCount() <= defMax) | ||
1697 | return (UInt64)(Int64)-1; | ||
1698 | // LRESULT is signed. so we cast it to unsigned size_t at first: | ||
1699 | LRESULT val = c.GetItemData_of_CurSel(); | ||
1700 | if (val == (LPARAM)(INT_PTR)(-1)) | ||
1701 | return (UInt64)(Int64)-1; | ||
1702 | return (UInt64)(size_t)c.GetItemData_of_CurSel(); | ||
1703 | } | ||
1704 | |||
1705 | UInt32 CCompressDialog::GetLevel2() | ||
1706 | { | ||
1707 | UInt32 level = GetLevel(); | ||
1708 | if (level == (UInt32)(Int32)-1) | ||
1709 | level = 5; | ||
1710 | return level; | ||
1711 | } | ||
1712 | |||
1713 | |||
1714 | int CCompressDialog::AddOrder(UInt32 size) | ||
1715 | { | ||
1716 | char s[32]; | ||
1717 | ConvertUInt32ToString(size, s); | ||
1718 | int index = (int)ComboBox_AddStringAscii(m_Order, s); | ||
1719 | m_Order.SetItemData(index, size); | ||
1720 | return index; | ||
1721 | } | ||
1722 | |||
1723 | int CCompressDialog::AddOrder_Auto() | ||
1724 | { | ||
1725 | AString s; | ||
1726 | s.Add_UInt32(_auto_Order); | ||
1727 | Modify_Auto(s); | ||
1728 | int index = (int)ComboBox_AddStringAscii(m_Order, s); | ||
1729 | m_Order.SetItemData(index, (LPARAM)(INT_PTR)(-1)); | ||
1730 | return index; | ||
1731 | } | ||
1732 | |||
1733 | void CCompressDialog::SetOrder2() | ||
1734 | { | ||
1735 | m_Order.ResetContent(); | ||
1736 | |||
1737 | _auto_Order = 1; | ||
1738 | |||
1739 | const CArcInfoEx &ai = Get_ArcInfoEx(); | ||
1740 | UInt32 defaultOrder = (UInt32)(Int32)-1; | ||
1741 | |||
1742 | { | ||
1743 | const int index = FindRegistryFormat(ai.Name); | ||
1744 | if (index >= 0) | ||
1745 | { | ||
1746 | const NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index]; | ||
1747 | if (IsMethodEqualTo(fo.Method)) | ||
1748 | defaultOrder = fo.Order; | ||
1749 | } | ||
1750 | } | ||
1751 | |||
1752 | const int methodID = GetMethodID(); | ||
1753 | const UInt32 level = GetLevel2(); | ||
1754 | if (methodID < 0) | ||
1755 | return; | ||
1756 | |||
1757 | switch (methodID) | ||
1758 | { | ||
1759 | case kLZMA: | ||
1760 | case kLZMA2: | ||
1761 | { | ||
1762 | _auto_Order = (level < 7 ? 32 : 64); | ||
1763 | int curSel = AddOrder_Auto(); | ||
1764 | for (unsigned i = 2 * 2; i < 8 * 2; i++) | ||
1765 | { | ||
1766 | UInt32 order = ((UInt32)(2 + (i & 1)) << (i / 2)); | ||
1767 | if (order > 256) | ||
1768 | order = 273; | ||
1769 | const int index = AddOrder(order); | ||
1770 | if (defaultOrder != (UInt32)(Int32)-1) | ||
1771 | if (order <= defaultOrder || curSel <= 0) | ||
1772 | curSel = index; | ||
1773 | } | ||
1774 | m_Order.SetCurSel(curSel); | ||
1775 | break; | ||
1776 | } | ||
1777 | |||
1778 | case kDeflate: | ||
1779 | case kDeflate64: | ||
1780 | { | ||
1781 | { | ||
1782 | if (level >= 9) _auto_Order = 128; | ||
1783 | else if (level >= 7) _auto_Order = 64; | ||
1784 | else _auto_Order = 32; | ||
1785 | } | ||
1786 | int curSel = AddOrder_Auto(); | ||
1787 | for (unsigned i = 2 * 2; i < 8 * 2; i++) | ||
1788 | { | ||
1789 | UInt32 order = ((UInt32)(2 + (i & 1)) << (i / 2)); | ||
1790 | if (order > 256) | ||
1791 | order = (methodID == kDeflate64 ? 257 : 258); | ||
1792 | const int index = AddOrder(order); | ||
1793 | if (defaultOrder != (UInt32)(Int32)-1) | ||
1794 | if (order <= defaultOrder || curSel <= 0) | ||
1795 | curSel = index; | ||
1796 | } | ||
1797 | |||
1798 | m_Order.SetCurSel(curSel); | ||
1799 | break; | ||
1800 | } | ||
1801 | |||
1802 | case kPPMd: | ||
1803 | { | ||
1804 | { | ||
1805 | if (level >= 9) _auto_Order = 32; | ||
1806 | else if (level >= 7) _auto_Order = 16; | ||
1807 | else if (level >= 5) _auto_Order = 6; | ||
1808 | else _auto_Order = 4; | ||
1809 | } | ||
1810 | |||
1811 | int curSel = AddOrder_Auto(); | ||
1812 | |||
1813 | for (unsigned i = 0;; i++) | ||
1814 | { | ||
1815 | UInt32 order = i + 2; | ||
1816 | if (i >= 2) | ||
1817 | order = (4 + ((i - 2) & 3)) << ((i - 2) / 4); | ||
1818 | const int index = AddOrder(order); | ||
1819 | if (defaultOrder != (UInt32)(Int32)-1) | ||
1820 | if (order <= defaultOrder || curSel <= 0) | ||
1821 | curSel = index; | ||
1822 | if (order >= 32) | ||
1823 | break; | ||
1824 | } | ||
1825 | m_Order.SetCurSel(curSel); | ||
1826 | break; | ||
1827 | } | ||
1828 | |||
1829 | case kPPMdZip: | ||
1830 | { | ||
1831 | _auto_Order = level + 3; | ||
1832 | int curSel = AddOrder_Auto(); | ||
1833 | for (unsigned i = 2; i <= 16; i++) | ||
1834 | { | ||
1835 | const int index = AddOrder(i); | ||
1836 | if (defaultOrder != (UInt32)(Int32)-1) | ||
1837 | if (i <= defaultOrder || curSel <= 0) | ||
1838 | curSel = index; | ||
1839 | } | ||
1840 | m_Order.SetCurSel(curSel); | ||
1841 | break; | ||
1842 | } | ||
1843 | |||
1844 | // case kBZip2: | ||
1845 | default: | ||
1846 | break; | ||
1847 | } | ||
1848 | } | ||
1849 | |||
1850 | bool CCompressDialog::GetOrderMode() | ||
1851 | { | ||
1852 | switch (GetMethodID()) | ||
1853 | { | ||
1854 | case kPPMd: | ||
1855 | case kPPMdZip: | ||
1856 | return true; | ||
1857 | } | ||
1858 | return false; | ||
1859 | } | ||
1860 | |||
1861 | |||
1862 | static UInt64 Get_Lzma2_ChunkSize(UInt64 dict) | ||
1863 | { | ||
1864 | // we use same default chunk sizes as defined in 7z encoder and lzma2 encoder | ||
1865 | UInt64 cs = (UInt64)dict << 2; | ||
1866 | const UInt32 kMinSize = (UInt32)1 << 20; | ||
1867 | const UInt32 kMaxSize = (UInt32)1 << 28; | ||
1868 | if (cs < kMinSize) cs = kMinSize; | ||
1869 | if (cs > kMaxSize) cs = kMaxSize; | ||
1870 | if (cs < dict) cs = dict; | ||
1871 | cs += (kMinSize - 1); | ||
1872 | cs &= ~(UInt64)(kMinSize - 1); | ||
1873 | return cs; | ||
1874 | } | ||
1875 | |||
1876 | |||
1877 | static void Add_Size(AString &s, UInt64 val) | ||
1878 | { | ||
1879 | unsigned moveBits = 0; | ||
1880 | char c = 0; | ||
1881 | if ((val & 0x3FFFFFFF) == 0) { moveBits = 30; c = 'G'; } | ||
1882 | else if ((val & 0xFFFFF) == 0) { moveBits = 20; c = 'M'; } | ||
1883 | else if ((val & 0x3FF) == 0) { moveBits = 10; c = 'K'; } | ||
1884 | s.Add_UInt64(val >> moveBits); | ||
1885 | s.Add_Space(); | ||
1886 | if (moveBits != 0) | ||
1887 | s += c; | ||
1888 | s += 'B'; | ||
1889 | } | ||
1890 | |||
1891 | |||
1892 | void CCompressDialog::SetSolidBlockSize2() | ||
1893 | { | ||
1894 | m_Solid.ResetContent(); | ||
1895 | _auto_Solid = 1 << 20; | ||
1896 | |||
1897 | const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()]; | ||
1898 | if (!fi.Solid_()) | ||
1899 | return; | ||
1900 | |||
1901 | const UInt32 level = GetLevel2(); | ||
1902 | if (level == 0) | ||
1903 | return; | ||
1904 | |||
1905 | UInt64 dict = GetDict2(); | ||
1906 | if (dict == (UInt64)(Int64)-1) | ||
1907 | { | ||
1908 | dict = 1 << 25; // default dict for unknown methods | ||
1909 | // return; | ||
1910 | } | ||
1911 | |||
1912 | |||
1913 | UInt32 defaultBlockSize = (UInt32)(Int32)-1; | ||
1914 | |||
1915 | const CArcInfoEx &ai = Get_ArcInfoEx(); | ||
1916 | |||
1917 | /* | ||
1918 | if (usePrevDictionary) | ||
1919 | defaultBlockSize = GetBlockSizeSpec(); | ||
1920 | else | ||
1921 | */ | ||
1922 | { | ||
1923 | const int index = FindRegistryFormat(ai.Name); | ||
1924 | if (index >= 0) | ||
1925 | { | ||
1926 | const NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index]; | ||
1927 | if (IsMethodEqualTo(fo.Method)) | ||
1928 | defaultBlockSize = fo.BlockLogSize; | ||
1929 | } | ||
1930 | } | ||
1931 | |||
1932 | const bool is7z = ai.Name.IsEqualTo_Ascii_NoCase("7z"); | ||
1933 | |||
1934 | const UInt64 cs = Get_Lzma2_ChunkSize(dict); | ||
1935 | |||
1936 | // Solid Block Size | ||
1937 | UInt64 blockSize = cs; // for xz | ||
1938 | |||
1939 | if (is7z) | ||
1940 | { | ||
1941 | // we use same default block sizes as defined in 7z encoder | ||
1942 | UInt64 kMaxSize = (UInt64)1 << 32; | ||
1943 | const int methodId = GetMethodID(); | ||
1944 | if (methodId == kLZMA2) | ||
1945 | { | ||
1946 | blockSize = cs << 6; | ||
1947 | kMaxSize = (UInt64)1 << 34; | ||
1948 | } | ||
1949 | else | ||
1950 | { | ||
1951 | UInt64 dict2 = dict; | ||
1952 | if (methodId == kBZip2) | ||
1953 | { | ||
1954 | dict2 /= 100000; | ||
1955 | if (dict2 < 1) | ||
1956 | dict2 = 1; | ||
1957 | dict2 *= 100000; | ||
1958 | } | ||
1959 | blockSize = dict2 << 7; | ||
1960 | } | ||
1961 | |||
1962 | const UInt32 kMinSize = (UInt32)1 << 24; | ||
1963 | if (blockSize < kMinSize) blockSize = kMinSize; | ||
1964 | if (blockSize > kMaxSize) blockSize = kMaxSize; | ||
1965 | } | ||
1966 | |||
1967 | _auto_Solid = blockSize; | ||
1968 | |||
1969 | int curSel; | ||
1970 | { | ||
1971 | AString s; | ||
1972 | Add_Size(s, _auto_Solid); | ||
1973 | Modify_Auto(s); | ||
1974 | int index = (int)ComboBox_AddStringAscii(m_Solid, s); | ||
1975 | m_Solid.SetItemData(index, (UInt32)(Int32)-1); | ||
1976 | curSel = index; | ||
1977 | } | ||
1978 | |||
1979 | if (is7z) | ||
1980 | { | ||
1981 | UString s ('-'); | ||
1982 | // kSolidLog_NoSolid = 0 for xz means default blockSize | ||
1983 | if (is7z) | ||
1984 | LangString(IDS_COMPRESS_NON_SOLID, s); | ||
1985 | const int index = (int)m_Solid.AddString(s); | ||
1986 | m_Solid.SetItemData(index, (UInt32)kSolidLog_NoSolid); | ||
1987 | if (defaultBlockSize == kSolidLog_NoSolid) | ||
1988 | curSel = index; | ||
1989 | } | ||
1990 | |||
1991 | for (unsigned i = 20; i <= 36; i++) | ||
1992 | { | ||
1993 | AString s; | ||
1994 | Add_Size(s, (UInt64)1 << i); | ||
1995 | const int index = (int)ComboBox_AddStringAscii(m_Solid, s); | ||
1996 | m_Solid.SetItemData(index, (UInt32)i); | ||
1997 | if (defaultBlockSize != (UInt32)(Int32)-1) | ||
1998 | if (i <= defaultBlockSize || index <= 1) | ||
1999 | curSel = index; | ||
2000 | } | ||
2001 | |||
2002 | { | ||
2003 | const int index = (int)m_Solid.AddString(LangString(IDS_COMPRESS_SOLID)); | ||
2004 | m_Solid.SetItemData(index, kSolidLog_FullSolid); | ||
2005 | if (defaultBlockSize == kSolidLog_FullSolid) | ||
2006 | curSel = index; | ||
2007 | } | ||
2008 | |||
2009 | m_Solid.SetCurSel(curSel); | ||
2010 | } | ||
2011 | |||
2012 | |||
2013 | void CCompressDialog::SetNumThreads2() | ||
2014 | { | ||
2015 | _auto_NumThreads = 1; | ||
2016 | |||
2017 | m_NumThreads.ResetContent(); | ||
2018 | const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()]; | ||
2019 | if (!fi.MultiThread_()) | ||
2020 | return; | ||
2021 | |||
2022 | const UInt32 numHardwareThreads = NSystem::GetNumberOfProcessors(); | ||
2023 | // 64; // for debug: | ||
2024 | |||
2025 | UInt32 defaultValue = numHardwareThreads; | ||
2026 | bool useAutoThreads = true; | ||
2027 | |||
2028 | { | ||
2029 | const CArcInfoEx &ai = Get_ArcInfoEx(); | ||
2030 | int index = FindRegistryFormat(ai.Name); | ||
2031 | if (index >= 0) | ||
2032 | { | ||
2033 | const NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index]; | ||
2034 | if (IsMethodEqualTo(fo.Method) && fo.NumThreads != (UInt32)(Int32)-1) | ||
2035 | { | ||
2036 | defaultValue = fo.NumThreads; | ||
2037 | useAutoThreads = false; | ||
2038 | } | ||
2039 | } | ||
2040 | } | ||
2041 | |||
2042 | UInt32 numAlgoThreadsMax = numHardwareThreads * 2; | ||
2043 | const int methodID = GetMethodID(); | ||
2044 | switch (methodID) | ||
2045 | { | ||
2046 | case kLZMA: numAlgoThreadsMax = 2; break; | ||
2047 | case kLZMA2: numAlgoThreadsMax = 256; break; | ||
2048 | case kBZip2: numAlgoThreadsMax = 32; break; | ||
2049 | case kCopy: | ||
2050 | case kPPMd: | ||
2051 | case kDeflate: | ||
2052 | case kDeflate64: | ||
2053 | case kPPMdZip: | ||
2054 | numAlgoThreadsMax = 1; | ||
2055 | } | ||
2056 | const bool isZip = IsZipFormat(); | ||
2057 | if (isZip) | ||
2058 | { | ||
2059 | numAlgoThreadsMax = | ||
2060 | #ifdef _WIN32 | ||
2061 | 64; // _WIN32 supports only 64 threads in one group. So no need for more threads here | ||
2062 | #else | ||
2063 | 128; | ||
2064 | #endif | ||
2065 | } | ||
2066 | |||
2067 | UInt32 autoThreads = numHardwareThreads; | ||
2068 | if (autoThreads > numAlgoThreadsMax) | ||
2069 | autoThreads = numAlgoThreadsMax; | ||
2070 | |||
2071 | const UInt64 memUse_Limit = Get_MemUse_Bytes(); | ||
2072 | |||
2073 | if (autoThreads > 1 && _ramSize_Defined) | ||
2074 | { | ||
2075 | if (isZip) | ||
2076 | { | ||
2077 | for (; autoThreads > 1; autoThreads--) | ||
2078 | { | ||
2079 | const UInt64 dict64 = GetDict2(); | ||
2080 | UInt64 decompressMemory; | ||
2081 | const UInt64 usage = GetMemoryUsage_Threads_Dict_DecompMem(autoThreads, dict64, decompressMemory); | ||
2082 | if (usage <= memUse_Limit) | ||
2083 | break; | ||
2084 | } | ||
2085 | } | ||
2086 | else if (methodID == kLZMA2) | ||
2087 | { | ||
2088 | const UInt64 dict64 = GetDict2(); | ||
2089 | const UInt32 numThreads1 = (GetLevel2() >= 5 ? 2 : 1); | ||
2090 | UInt32 numBlockThreads = autoThreads / numThreads1; | ||
2091 | for (; numBlockThreads > 1; numBlockThreads--) | ||
2092 | { | ||
2093 | autoThreads = numBlockThreads * numThreads1; | ||
2094 | UInt64 decompressMemory; | ||
2095 | const UInt64 usage = GetMemoryUsage_Threads_Dict_DecompMem(autoThreads, dict64, decompressMemory); | ||
2096 | if (usage <= memUse_Limit) | ||
2097 | break; | ||
2098 | } | ||
2099 | autoThreads = numBlockThreads * numThreads1; | ||
2100 | } | ||
2101 | } | ||
2102 | |||
2103 | _auto_NumThreads = autoThreads; | ||
2104 | |||
2105 | int curSel = -1; | ||
2106 | { | ||
2107 | AString s; | ||
2108 | s.Add_UInt32(autoThreads); | ||
2109 | Modify_Auto(s); | ||
2110 | int index = (int)ComboBox_AddStringAscii(m_NumThreads, s); | ||
2111 | m_NumThreads.SetItemData(index, (LPARAM)(INT_PTR)(-1)); | ||
2112 | // m_NumThreads.SetItemData(index, autoThreads); | ||
2113 | if (useAutoThreads) | ||
2114 | curSel = index; | ||
2115 | } | ||
2116 | |||
2117 | if (numAlgoThreadsMax != autoThreads || autoThreads != 1) | ||
2118 | for (UInt32 i = 1; i <= numHardwareThreads * 2 && i <= numAlgoThreadsMax; i++) | ||
2119 | { | ||
2120 | char s[32]; | ||
2121 | ConvertUInt32ToString(i, s); | ||
2122 | int index = (int)ComboBox_AddStringAscii(m_NumThreads, s); | ||
2123 | m_NumThreads.SetItemData(index, (UInt32)i); | ||
2124 | if (!useAutoThreads && i == defaultValue) | ||
2125 | curSel = index; | ||
2126 | } | ||
2127 | |||
2128 | m_NumThreads.SetCurSel(curSel); | ||
2129 | } | ||
2130 | |||
2131 | |||
2132 | static void AddMemSize(UString &res, UInt64 size) | ||
2133 | { | ||
2134 | char c; | ||
2135 | unsigned moveBits = 0; | ||
2136 | if (size >= ((UInt64)1 << 31) && (size & 0x3FFFFFFF) == 0) | ||
2137 | { moveBits = 30; c = 'G'; } | ||
2138 | else // if (size >= ((UInt32)1 << 21) && (size & 0xFFFFF) == 0) | ||
2139 | { moveBits = 20; c = 'M'; } | ||
2140 | // else { moveBits = 10; c = 'K'; } | ||
2141 | res.Add_UInt64(size >> moveBits); | ||
2142 | res.Add_Space(); | ||
2143 | if (moveBits != 0) | ||
2144 | res += c; | ||
2145 | res += 'B'; | ||
2146 | } | ||
2147 | |||
2148 | |||
2149 | int CCompressDialog::AddMemComboItem(UInt64 val, bool isPercent, bool isDefault) | ||
2150 | { | ||
2151 | UString sUser; | ||
2152 | UString sRegistry; | ||
2153 | if (isPercent) | ||
2154 | { | ||
2155 | UString s; | ||
2156 | s.Add_UInt64(val); | ||
2157 | s += '%'; | ||
2158 | if (isDefault) | ||
2159 | sUser = "* "; | ||
2160 | else | ||
2161 | sRegistry = s; | ||
2162 | sUser += s; | ||
2163 | } | ||
2164 | else | ||
2165 | { | ||
2166 | AddMemSize(sUser, val); | ||
2167 | sRegistry = sUser; | ||
2168 | for (;;) | ||
2169 | { | ||
2170 | int pos = sRegistry.Find(L' '); | ||
2171 | if (pos < 0) | ||
2172 | break; | ||
2173 | sRegistry.Delete(pos); | ||
2174 | } | ||
2175 | if (!sRegistry.IsEmpty()) | ||
2176 | if (sRegistry.Back() == 'B') | ||
2177 | sRegistry.DeleteBack(); | ||
2178 | } | ||
2179 | const unsigned dataIndex = _memUse_Strings.Add(sRegistry); | ||
2180 | const int index = (int)m_MemUse.AddString(sUser); | ||
2181 | m_MemUse.SetItemData(index, dataIndex); | ||
2182 | return index; | ||
2183 | } | ||
2184 | |||
2185 | |||
2186 | |||
2187 | void CCompressDialog::SetMemUseCombo() | ||
2188 | { | ||
2189 | _memUse_Strings.Clear(); | ||
2190 | m_MemUse.ResetContent(); | ||
2191 | const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()]; | ||
2192 | |||
2193 | { | ||
2194 | const bool enable = fi.MemUse_(); | ||
2195 | ShowItem_Bool(IDT_COMPRESS_MEMORY, enable); | ||
2196 | ShowItem_Bool(IDT_COMPRESS_MEMORY_VALUE, enable); | ||
2197 | ShowItem_Bool(IDT_COMPRESS_MEMORY_DE, enable); | ||
2198 | ShowItem_Bool(IDT_COMPRESS_MEMORY_DE_VALUE, enable); | ||
2199 | ShowItem_Bool(IDC_COMPRESS_MEM_USE, enable); | ||
2200 | EnableItem(IDC_COMPRESS_MEM_USE, enable); | ||
2201 | if (!enable) | ||
2202 | return; | ||
2203 | } | ||
2204 | |||
2205 | UInt64 curMem_Bytes = 0; | ||
2206 | UInt64 curMem_Percents = 0; | ||
2207 | bool needSetCur_Bytes = false; | ||
2208 | bool needSetCur_Percents = false; | ||
2209 | { | ||
2210 | const NCompression::CFormatOptions &fo = Get_FormatOptions(); | ||
2211 | if (!fo.MemUse.IsEmpty()) | ||
2212 | { | ||
2213 | NCompression::CMemUse mu; | ||
2214 | mu.Parse(fo.MemUse); | ||
2215 | if (mu.IsDefined) | ||
2216 | { | ||
2217 | if (mu.IsPercent) | ||
2218 | { | ||
2219 | curMem_Percents = mu.Val; | ||
2220 | needSetCur_Percents = true; | ||
2221 | } | ||
2222 | else | ||
2223 | { | ||
2224 | curMem_Bytes = mu.GetBytes(_ramSize_Reduced); | ||
2225 | needSetCur_Bytes = true; | ||
2226 | } | ||
2227 | } | ||
2228 | } | ||
2229 | } | ||
2230 | |||
2231 | |||
2232 | // 80% - is auto usage limit in handlers | ||
2233 | AddMemComboItem(80, true, true); | ||
2234 | m_MemUse.SetCurSel(0); | ||
2235 | |||
2236 | { | ||
2237 | for (unsigned i = 10;; i += 10) | ||
2238 | { | ||
2239 | UInt64 size = i; | ||
2240 | if (i > 100) | ||
2241 | size = (UInt64)(Int64)-1; | ||
2242 | if (needSetCur_Percents && size >= curMem_Percents) | ||
2243 | { | ||
2244 | const int index = AddMemComboItem(curMem_Percents, true); | ||
2245 | m_MemUse.SetCurSel(index); | ||
2246 | needSetCur_Percents = false; | ||
2247 | if (size == curMem_Percents) | ||
2248 | continue; | ||
2249 | } | ||
2250 | if (size == (UInt64)(Int64)-1) | ||
2251 | break; | ||
2252 | AddMemComboItem(size, true); | ||
2253 | } | ||
2254 | } | ||
2255 | { | ||
2256 | for (unsigned i = (27) * 2;; i++) | ||
2257 | { | ||
2258 | UInt64 size = (UInt64)(2 + (i & 1)) << (i / 2); | ||
2259 | if (i > (20 + sizeof(size_t) * 3 - 1) * 2) | ||
2260 | size = (UInt64)(Int64)-1; | ||
2261 | if (needSetCur_Bytes && size >= curMem_Bytes) | ||
2262 | { | ||
2263 | const int index = AddMemComboItem(curMem_Bytes); | ||
2264 | m_MemUse.SetCurSel(index); | ||
2265 | needSetCur_Bytes = false; | ||
2266 | if (size == curMem_Bytes) | ||
2267 | continue; | ||
2268 | } | ||
2269 | if (size == (UInt64)(Int64)-1) | ||
2270 | break; | ||
2271 | AddMemComboItem(size); | ||
2272 | } | ||
2273 | } | ||
2274 | } | ||
2275 | |||
2276 | |||
2277 | UString CCompressDialog::Get_MemUse_Spec() | ||
2278 | { | ||
2279 | if (m_MemUse.GetCount() < 1) | ||
2280 | return UString(); | ||
2281 | return _memUse_Strings[(unsigned)m_MemUse.GetItemData_of_CurSel()]; | ||
2282 | } | ||
2283 | |||
2284 | |||
2285 | UInt64 CCompressDialog::Get_MemUse_Bytes() | ||
2286 | { | ||
2287 | const UString mus = Get_MemUse_Spec(); | ||
2288 | NCompression::CMemUse mu; | ||
2289 | if (!mus.IsEmpty()) | ||
2290 | { | ||
2291 | mu.Parse(mus); | ||
2292 | if (mu.IsDefined) | ||
2293 | return mu.GetBytes(_ramSize_Reduced); | ||
2294 | } | ||
2295 | return _ramUsage_Auto; // _ramSize_Reduced; // _ramSize;; | ||
2296 | } | ||
2297 | |||
2298 | |||
2299 | |||
2300 | UInt64 CCompressDialog::GetMemoryUsage_DecompMem(UInt64 &decompressMemory) | ||
2301 | { | ||
2302 | return GetMemoryUsage_Dict_DecompMem(GetDict2(), decompressMemory); | ||
2303 | } | ||
2304 | |||
2305 | UInt64 CCompressDialog::GetMemoryUsageComp_Threads_Dict(UInt32 numThreads, UInt64 dict64) | ||
2306 | { | ||
2307 | UInt64 decompressMemory; | ||
2308 | return GetMemoryUsage_Threads_Dict_DecompMem(numThreads, dict64, decompressMemory); | ||
2309 | } | ||
2310 | |||
2311 | UInt64 CCompressDialog::GetMemoryUsage_Dict_DecompMem(UInt64 dict64, UInt64 &decompressMemory) | ||
2312 | { | ||
2313 | return GetMemoryUsage_Threads_Dict_DecompMem(GetNumThreads2(), dict64, decompressMemory); | ||
2314 | } | ||
2315 | |||
2316 | UInt64 CCompressDialog::GetMemoryUsage_Threads_Dict_DecompMem(UInt32 numThreads, UInt64 dict64, UInt64 &decompressMemory) | ||
2317 | { | ||
2318 | decompressMemory = (UInt64)(Int64)-1; | ||
2319 | if (dict64 == (UInt64)(Int64)-1) | ||
2320 | return (UInt64)(Int64)-1; | ||
2321 | |||
2322 | UInt32 level = GetLevel2(); | ||
2323 | if (level == 0) | ||
2324 | { | ||
2325 | decompressMemory = (1 << 20); | ||
2326 | return decompressMemory; | ||
2327 | } | ||
2328 | UInt64 size = 0; | ||
2329 | |||
2330 | const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()]; | ||
2331 | if (fi.Filter_() && level >= 9) | ||
2332 | size += (12 << 20) * 2 + (5 << 20); | ||
2333 | // UInt32 numThreads = GetNumThreads2(); | ||
2334 | |||
2335 | UInt32 numMainZipThreads = 1; | ||
2336 | |||
2337 | if (IsZipFormat()) | ||
2338 | { | ||
2339 | UInt32 numSubThreads = 1; | ||
2340 | if (GetMethodID() == kLZMA && numThreads > 1 && level >= 5) | ||
2341 | numSubThreads = 2; | ||
2342 | numMainZipThreads = numThreads / numSubThreads; | ||
2343 | if (numMainZipThreads > 1) | ||
2344 | size += (UInt64)numMainZipThreads * ((size_t)sizeof(size_t) << 23); | ||
2345 | else | ||
2346 | numMainZipThreads = 1; | ||
2347 | } | ||
2348 | |||
2349 | const int methodId = GetMethodID(); | ||
2350 | |||
2351 | switch (methodId) | ||
2352 | { | ||
2353 | case kLZMA: | ||
2354 | case kLZMA2: | ||
2355 | { | ||
2356 | const UInt32 dict = (dict64 >= kLzmaMaxDictSize ? kLzmaMaxDictSize : (UInt32)dict64); | ||
2357 | UInt32 hs = dict - 1; | ||
2358 | hs |= (hs >> 1); | ||
2359 | hs |= (hs >> 2); | ||
2360 | hs |= (hs >> 4); | ||
2361 | hs |= (hs >> 8); | ||
2362 | hs >>= 1; | ||
2363 | if (hs >= (1 << 24)) | ||
2364 | hs >>= 1; | ||
2365 | hs |= (1 << 16) - 1; | ||
2366 | // if (numHashBytes >= 5) | ||
2367 | if (level < 5) | ||
2368 | hs |= (256 << 10) - 1; | ||
2369 | hs++; | ||
2370 | UInt64 size1 = (UInt64)hs * 4; | ||
2371 | size1 += (UInt64)dict * 4; | ||
2372 | if (level >= 5) | ||
2373 | size1 += (UInt64)dict * 4; | ||
2374 | size1 += (2 << 20); | ||
2375 | |||
2376 | UInt32 numThreads1 = 1; | ||
2377 | if (numThreads > 1 && level >= 5) | ||
2378 | { | ||
2379 | size1 += (2 << 20) + (4 << 20); | ||
2380 | numThreads1 = 2; | ||
2381 | } | ||
2382 | |||
2383 | UInt32 numBlockThreads = numThreads / numThreads1; | ||
2384 | |||
2385 | UInt64 chunkSize = 0; // it's solid chunk | ||
2386 | |||
2387 | if (methodId != kLZMA && numBlockThreads != 1) | ||
2388 | { | ||
2389 | chunkSize = Get_Lzma2_ChunkSize(dict); | ||
2390 | |||
2391 | if (IsXzFormat()) | ||
2392 | { | ||
2393 | UInt32 blockSizeLog = GetBlockSizeSpec(); | ||
2394 | if (blockSizeLog != (UInt32)(Int32)-1) | ||
2395 | { | ||
2396 | if (blockSizeLog == kSolidLog_FullSolid) | ||
2397 | { | ||
2398 | numBlockThreads = 1; | ||
2399 | chunkSize = 0; | ||
2400 | } | ||
2401 | else if (blockSizeLog != kSolidLog_NoSolid) | ||
2402 | chunkSize = (UInt64)1 << blockSizeLog; | ||
2403 | } | ||
2404 | } | ||
2405 | } | ||
2406 | |||
2407 | if (chunkSize == 0) | ||
2408 | { | ||
2409 | const UInt32 kBlockSizeMax = (UInt32)0 - (UInt32)(1 << 16); | ||
2410 | UInt64 blockSize = (UInt64)dict + (1 << 16) | ||
2411 | + (numThreads1 > 1 ? (1 << 20) : 0); | ||
2412 | blockSize += (blockSize >> (blockSize < ((UInt32)1 << 30) ? 1 : 2)); | ||
2413 | if (blockSize >= kBlockSizeMax) | ||
2414 | blockSize = kBlockSizeMax; | ||
2415 | size += numBlockThreads * (size1 + blockSize); | ||
2416 | } | ||
2417 | else | ||
2418 | { | ||
2419 | size += numBlockThreads * (size1 + chunkSize); | ||
2420 | UInt32 numPackChunks = numBlockThreads + (numBlockThreads / 8) + 1; | ||
2421 | if (chunkSize < ((UInt32)1 << 26)) numBlockThreads++; | ||
2422 | if (chunkSize < ((UInt32)1 << 24)) numBlockThreads++; | ||
2423 | if (chunkSize < ((UInt32)1 << 22)) numBlockThreads++; | ||
2424 | size += numPackChunks * chunkSize; | ||
2425 | } | ||
2426 | |||
2427 | decompressMemory = dict + (2 << 20); | ||
2428 | return size; | ||
2429 | } | ||
2430 | |||
2431 | case kPPMd: | ||
2432 | { | ||
2433 | decompressMemory = dict64 + (2 << 20); | ||
2434 | return size + decompressMemory; | ||
2435 | } | ||
2436 | |||
2437 | case kDeflate: | ||
2438 | case kDeflate64: | ||
2439 | { | ||
2440 | UInt64 size1 = 3 << 20; | ||
2441 | // if (level >= 7) | ||
2442 | size1 += (1 << 20); | ||
2443 | size += size1 * numMainZipThreads; | ||
2444 | decompressMemory = (2 << 20); | ||
2445 | return size; | ||
2446 | } | ||
2447 | |||
2448 | case kBZip2: | ||
2449 | { | ||
2450 | decompressMemory = (7 << 20); | ||
2451 | UInt64 memForOneThread = (10 << 20); | ||
2452 | return size + memForOneThread * numThreads; | ||
2453 | } | ||
2454 | |||
2455 | case kPPMdZip: | ||
2456 | { | ||
2457 | decompressMemory = dict64 + (2 << 20); | ||
2458 | return size + (UInt64)decompressMemory * numThreads; | ||
2459 | } | ||
2460 | } | ||
2461 | |||
2462 | return (UInt64)(Int64)-1; | ||
2463 | } | ||
2464 | |||
2465 | |||
2466 | |||
2467 | static void AddMemUsage(UString &s, UInt64 v) | ||
2468 | { | ||
2469 | const char *post; | ||
2470 | if (v <= ((UInt64)16 << 30)) | ||
2471 | { | ||
2472 | v = (v + (1 << 20) - 1) >> 20; | ||
2473 | post = "MB"; | ||
2474 | } | ||
2475 | else if (v <= ((UInt64)64 << 40)) | ||
2476 | { | ||
2477 | v = (v + (1 << 30) - 1) >> 30; | ||
2478 | post = "GB"; | ||
2479 | } | ||
2480 | else | ||
2481 | { | ||
2482 | const UInt64 v2 = v + ((UInt64)1 << 40) - 1; | ||
2483 | if (v <= v2) | ||
2484 | v = v2; | ||
2485 | v >>= 40; | ||
2486 | post = "TB"; | ||
2487 | } | ||
2488 | s.Add_UInt64(v); | ||
2489 | s.Add_Space(); | ||
2490 | s += post; | ||
2491 | } | ||
2492 | |||
2493 | |||
2494 | void CCompressDialog::PrintMemUsage(UINT res, UInt64 value) | ||
2495 | { | ||
2496 | if (value == (UInt64)(Int64)-1) | ||
2497 | { | ||
2498 | SetItemText(res, TEXT("?")); | ||
2499 | return; | ||
2500 | } | ||
2501 | UString s; | ||
2502 | AddMemUsage(s, value); | ||
2503 | if (res == IDT_COMPRESS_MEMORY_VALUE) | ||
2504 | { | ||
2505 | const UString mus = Get_MemUse_Spec(); | ||
2506 | NCompression::CMemUse mu; | ||
2507 | if (!mus.IsEmpty()) | ||
2508 | mu.Parse(mus); | ||
2509 | if (mu.IsDefined) | ||
2510 | { | ||
2511 | s += " / "; | ||
2512 | AddMemUsage(s, mu.GetBytes(_ramSize_Reduced)); | ||
2513 | } | ||
2514 | else if (_ramSize_Defined) | ||
2515 | { | ||
2516 | s += " / "; | ||
2517 | AddMemUsage(s, _ramUsage_Auto); | ||
2518 | } | ||
2519 | |||
2520 | if (_ramSize_Defined) | ||
2521 | { | ||
2522 | s += " / "; | ||
2523 | AddMemUsage(s, _ramSize); | ||
2524 | } | ||
2525 | } | ||
2526 | SetItemText(res, s); | ||
2527 | } | ||
2528 | |||
2529 | |||
2530 | void CCompressDialog::SetMemoryUsage() | ||
2531 | { | ||
2532 | UInt64 decompressMem; | ||
2533 | const UInt64 memUsage = GetMemoryUsage_DecompMem(decompressMem); | ||
2534 | PrintMemUsage(IDT_COMPRESS_MEMORY_VALUE, memUsage); | ||
2535 | PrintMemUsage(IDT_COMPRESS_MEMORY_DE_VALUE, decompressMem); | ||
2536 | } | ||
2537 | |||
2538 | void CCompressDialog::SetParams() | ||
2539 | { | ||
2540 | const CArcInfoEx &ai = Get_ArcInfoEx(); | ||
2541 | m_Params.SetText(TEXT("")); | ||
2542 | const int index = FindRegistryFormat(ai.Name); | ||
2543 | if (index >= 0) | ||
2544 | { | ||
2545 | const NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index]; | ||
2546 | m_Params.SetText(fo.Options); | ||
2547 | } | ||
2548 | } | ||
2549 | |||
2550 | void CCompressDialog::SaveOptionsInMem() | ||
2551 | { | ||
2552 | m_Params.GetText(Info.Options); | ||
2553 | Info.Options.Trim(); | ||
2554 | |||
2555 | const CArcInfoEx &ai = (*ArcFormats)[Info.FormatIndex]; | ||
2556 | const int index = FindRegistryFormatAlways(ai.Name); | ||
2557 | NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index]; | ||
2558 | fo.Options = Info.Options; | ||
2559 | fo.Level = GetLevelSpec(); | ||
2560 | { | ||
2561 | const UInt64 dict64 = GetDictSpec(); | ||
2562 | UInt32 dict32; | ||
2563 | if (dict64 == (UInt64)(Int64)-1) | ||
2564 | dict32 = (UInt32)(Int32)-1; | ||
2565 | else | ||
2566 | { | ||
2567 | dict32 = (UInt32)dict64; | ||
2568 | if (dict64 != dict32) | ||
2569 | { | ||
2570 | /* here we must write 32-bit value for registry that indicates big_value | ||
2571 | (UInt32)(Int32)-1 : is used as marker for default size | ||
2572 | (UInt32)(Int32)-2 : it can be used to indicate big value (4 GiB) | ||
2573 | the value must be larger than threshold | ||
2574 | */ | ||
2575 | dict32 = (UInt32)(Int32)-2; | ||
2576 | // dict32 = kLzmaMaxDictSize; // it must be larger than threshold | ||
2577 | } | ||
2578 | } | ||
2579 | fo.Dictionary = dict32; | ||
2580 | } | ||
2581 | |||
2582 | fo.Order = GetOrderSpec(); | ||
2583 | fo.Method = GetMethodSpec(); | ||
2584 | fo.EncryptionMethod = GetEncryptionMethodSpec(); | ||
2585 | fo.NumThreads = GetNumThreadsSpec(); | ||
2586 | fo.BlockLogSize = GetBlockSizeSpec(); | ||
2587 | fo.MemUse = Get_MemUse_Spec(); | ||
2588 | } | ||
2589 | |||
2590 | unsigned CCompressDialog::GetFormatIndex() | ||
2591 | { | ||
2592 | return (unsigned)m_Format.GetItemData_of_CurSel(); | ||
2593 | } | ||