diff --git a/makefile.deps b/makefile.deps index d8fef0d7cf16..848898745851 100644 --- a/makefile.deps +++ b/makefile.deps @@ -325,9 +325,6 @@ $(OS)\Installer.obj: $B\src\utils\FileUtil.h $B\src\utils\FrameTimeoutCalculator $(OS)\Installer.obj: $B\src\utils\LzmaSimpleArchive.h $B\src\utils\Scoped.h $B\src\utils\SettingsUtil.h $(OS)\Installer.obj: $B\src\utils\StrUtil.h $B\src\utils\Timer.h $B\src\utils\Vec.h $(OS)\Installer.obj: $B\src\utils\WinUtil.h $B\src\Version.h -$(OS)\LzzaEnc.obj: $B\src\utils\Allocator.h $B\src\utils\BaseUtil.h $B\src\utils\CmdLineParser.h -$(OS)\LzzaEnc.obj: $B\src\utils\FileUtil.h $B\src\utils\GeomUtil.h $B\src\utils\LzzaUtil.h -$(OS)\LzzaEnc.obj: $B\src\utils\Scoped.h $B\src\utils\StrUtil.h $B\src\utils\Vec.h $(OS)\MakeLzSA.obj: $B\src\utils\Allocator.h $B\src\utils\BaseUtil.h $B\src\utils\CmdLineParser.h $(OS)\MakeLzSA.obj: $B\src\utils\FileUtil.h $B\src\utils\GeomUtil.h $B\src\utils\LzmaSimpleArchive.h $(OS)\MakeLzSA.obj: $B\src\utils\Scoped.h $B\src\utils\StrUtil.h $B\src\utils\Vec.h @@ -727,11 +724,6 @@ $(OU)\LzmaSimpleArchive.obj: $B\ext\lzma\C\Types.h $B\src\utils\Allocator.h $B\s $(OU)\LzmaSimpleArchive.obj: $B\src\utils\ByteOrderDecoder.h $B\src\utils\ByteWriter.h $B\src\utils\FileUtil.h $(OU)\LzmaSimpleArchive.obj: $B\src\utils\GeomUtil.h $B\src\utils\LzmaSimpleArchive.h $B\src\utils\Scoped.h $(OU)\LzmaSimpleArchive.obj: $B\src\utils\StrUtil.h $B\src\utils\Vec.h -$(OU)\LzzaUtil.obj: $B\ext\lzma\C\LzmaDec.h $B\ext\lzma\C\LzmaEnc.h $B\ext\lzma\C\Types.h -$(OU)\LzzaUtil.obj: $B\src\utils\Allocator.h $B\src\utils\BaseUtil.h $B\src\utils\ByteReader.h -$(OU)\LzzaUtil.obj: $B\src\utils\ByteWriter.h $B\src\utils\FileUtil.h $B\src\utils\GeomUtil.h -$(OU)\LzzaUtil.obj: $B\src\utils\LzzaUtil.h $B\src\utils\Scoped.h $B\src\utils\StrUtil.h -$(OU)\LzzaUtil.obj: $B\src\utils\Vec.h $(OU)\NoFreeAllocator.obj: $B\src\utils\Allocator.h $B\src\utils\BaseUtil.h $B\src\utils\GeomUtil.h $(OU)\NoFreeAllocator.obj: $B\src\utils\NoFreeAllocator.h $B\src\utils\Scoped.h $B\src\utils\StrUtil.h $(OU)\NoFreeAllocator.obj: $B\src\utils\Vec.h diff --git a/makefile.msvc b/makefile.msvc index 6b043557ff28..c756f7461d27 100644 --- a/makefile.msvc +++ b/makefile.msvc @@ -145,7 +145,6 @@ MEMTRACE_CFLAGS = $(SUMATRA_CFLAGS) ENGINEDUMP_APP = $(O)\EngineDump.exe MAKELZSA_APP = $(O)\MakeLzsa.exe -LZZAENC_APP = $(O)\LzzaEnc.exe MUPDF_LIB = $(O)\libmupdfs.lib UNARR_LIB = $(O)\unarr.lib @@ -172,8 +171,7 @@ UTILS_OBJS = \ $(OU)\SquareTreeParser.obj $(OU)\SettingsUtil.obj $(OU)\SplitterWnd.obj \ $(OU)\WebpReader.obj $(OU)\FzImgReader.obj \ $(OU)\ZipUtil.obj $(OU)\RarUtil.obj $(OU)\LzmaSimpleArchive.obj \ - $(OU)\LabelWithCloseWnd.obj $(OU)\WinCursors.obj $(OU)\FrameRateWnd.obj \ - $(OU)\LzzaUtil.obj + $(OU)\LabelWithCloseWnd.obj $(OU)\WinCursors.obj $(OU)\FrameRateWnd.obj MUI_OBJS = \ $(OMUI)\MuiBase.obj $(OMUI)\Mui.obj $(OMUI)\MuiCss.obj $(OMUI)\MuiLayout.obj \ @@ -240,9 +238,6 @@ ENGINEDUMP_OBJS = \ MAKELZSA_OBJS = \ $(OS)\MakeLzsa.obj $(UTILS_LIB) $(ZLIB_OBJS) $(LZMA_OBJS) -LZZAENC_OBJS = \ - $(OS)\LzzaEnc.obj $(UTILS_LIB) $(ZLIB_OBJS) $(LZMA_OBJS) - MEMTRACE_OBJS = \ $(OM)\MemTraceDll.obj $(UTILS_LIB) @@ -334,7 +329,7 @@ Uninstaller: $(OS) $(UNINSTALLER_APP) PDFFilter: $(OS) $(PDFFILTER_DLL) PdfPreview: $(OS) $(PDFPREVIEW_DLL) EngineDump: $(OS) $(ENGINEDUMP_APP) -MakeLzsa: $(OS) $(MAKELZSA_APP) $(LZZAENC_APP) +MakeLzsa: $(OS) $(MAKELZSA_APP) memtrace: $(OS) $(MEMTRACE_DLL) mudraw: $(O) $(MUDRAW_APP) mutool: $(O) $(MUTOOL_APP) @@ -403,9 +398,6 @@ $(ENGINEDUMP_APP): $(ENGINEDUMP_OBJS) $(MAKELZSA_APP): $(MAKELZSA_OBJS) $(LD) $(LDFLAGS) $** $(LIBS) /PDB:$*.pdb /OUT:$@ /SUBSYSTEM:CONSOLE -$(LZZAENC_APP): $(LZZAENC_OBJS) - $(LD) $(LDFLAGS) $** $(LIBS) /PDB:$*.pdb /OUT:$@ /SUBSYSTEM:CONSOLE - {$(SRCDIR)\utils}.cpp{$(OU)}.obj:: $(CC) $(UTILS_CFLAGS) /Fo$(OU)\ /Fd$(O)\vc80.pdb $< diff --git a/scripts/build.py b/scripts/build.py index 6c6d96fa8e96..f10607baf513 100644 --- a/scripts/build.py +++ b/scripts/build.py @@ -59,7 +59,6 @@ import trans_upload import trans_download import upload_sources -from binascii import crc32 def usage(): @@ -74,130 +73,20 @@ def get_top_dir(): return os.path.realpath(os.path.join(scripts_dir, "..")) -def lzma_compress(src, dst): - d = os.path.dirname(__file__) - lzma = os.path.realpath(os.path.join(d, "..", "bin", "lzma.exe")) - run_cmd_throw(lzma, "e", src, dst, "-f86") - - def copy_to_dst_dir(src_path, dst_dir): name_in_obj_rel = os.path.basename(src_path) dst_path = os.path.join(dst_dir, name_in_obj_rel) shutil.copy(src_path, dst_path) -def is_more_recent(src_path, dst_path): - return os.path.getmtime(src_path) > os.path.getmtime(dst_path) - - -def get_real_name(f): - if type(f) in [types.ListType, types.TupleType]: - assert len(f) == 2 - return f[0] - return f - - -def get_in_archive_name(f): - if type(f) in [types.ListType, types.TupleType]: - assert len(f) == 2 - return f[1].encode("UTF-8") - return f.encode("UTF-8") - - -def get_file_crc32(path): - with open(path, "rb") as fo: - d = fo.read() - checksum = crc32(d, 0) - return checksum & 0xFFFFFFFF - - -g_lzsa_archive_magic_id = 0x41537a4c - -""" -Create a simple lzma archive in format: - -u32 magic_id 0x41537a4c ("LzSA' for "Lzma Simple Archive") -u32 number of files -for each file: - u32 length of file metadata (from this field to file name's 0-terminator) - u32 file size compressed - u32 file size uncompressed - u32 crc32 checksum of uncompressed data - FILETIME last modification time in Windows's FILETIME format - char[...] file name, 0-terminated -u32 crc32 checksum of the header (i.e. data so far) -for each file: - compressed file data - -Integers are little-endian. - -You can over-write the file name in the archive by using list instead of -a string in files: ["foo.txt", "bar.txt"] will add file "foo.txt" under name -"bar.txt" -""" -def create_lzsa_archive(dir, archiveName, files): - for f in files: - f = get_real_name(f) - src = os.path.join(dir, f) - dst = src + ".lzma" - if not os.path.exists(dst) or is_more_recent(src, dst): - lzma_compress(src, dst) - - d = struct.pack(" lzzaData(file::ReadAll(args.At(1), &lzza.dataLen)); - lzza.data = lzzaData.Get(); - FailIf(!lzza.data, "Failed to read \"%S\"", args.At(1)); - int i = 0; - for (;;) { - ScopedMem fd(lzza::GetFileData(&lzza, i++)); - FailIf(!fd, "Managed to extract %d files", i - 1); - } - } - - FailIf(args.Count() < 3, "Syntax: %S [:] [...]", path::GetBaseName(args.At(0))); - - WStrVec names; - for (size_t i = 2; i < args.Count(); i++) { - const WCHAR *sep = str::FindChar(args.At(i), ':'); - if (sep) { - names.Append(str::DupN(args.At(i), sep - args.At(i))); - names.Append(str::Dup(sep + 1)); - } - else { - names.Append(str::Dup(args.At(i))); - names.Append(NULL); - } - } - - WCHAR srcDir[MAX_PATH]; - DWORD srcDirLen = GetCurrentDirectory(dimof(srcDir), srcDir); - FailIf(!srcDirLen || srcDirLen == dimof(srcDir), "Failed to determine the current directory"); - - bool ok = lzza::CreateArchive(args.At(1), srcDir, names); - FailIf(!ok, "Failed to create \"%S\"", args.At(1)); - - return 0; -} diff --git a/src/utils/LzmaSimpleArchive.cpp b/src/utils/LzmaSimpleArchive.cpp index 69877e874e5a..c05e69fbf06d 100644 --- a/src/utils/LzmaSimpleArchive.cpp +++ b/src/utils/LzmaSimpleArchive.cpp @@ -44,16 +44,16 @@ struct ISzAllocatorAlloc : ISzAlloc { }; // adapted from lzma/C/Lzma86Dec.c +// (main difference: the uncompressed size isn't stored in bytes 6 to 13) -#define LZMA86_HEADER_SIZE (1 + LZMA_PROPS_SIZE + sizeof(uint64_t)) +#define LZMA_HEADER_SIZE (1 + LZMA_PROPS_SIZE) bool Decompress(const char *compressed, size_t compressedSize, char *uncompressed, size_t uncompressedSize, Allocator *allocator) { if (compressedSize < 1) return false; - ByteOrderDecoder br(compressed, compressedSize, ByteOrderDecoder::LittleEndian); - uint8_t usesX86Filter = br.UInt8(); + uint8_t usesX86Filter = compressed[0]; // handle stored data if (usesX86Filter == (uint8_t)-1) { if (uncompressedSize != compressedSize - 1) @@ -62,24 +62,20 @@ bool Decompress(const char *compressed, size_t compressedSize, char *uncompresse return true; } - if (compressedSize < LZMA86_HEADER_SIZE || usesX86Filter > 1) + if (compressedSize < LZMA_HEADER_SIZE || usesX86Filter > 1) return false; - br.Skip(LZMA_PROPS_SIZE); - SizeT uncompressedSizeCmp = (SizeT)br.UInt64(); - if (uncompressedSizeCmp != uncompressedSize) - return false; - CrashIf(br.Offset() != LZMA86_HEADER_SIZE); - SizeT compressedSizeTmp = compressedSize - LZMA86_HEADER_SIZE; + SizeT uncompressedSizeCmp = uncompressedSize; + SizeT compressedSizeTmp = compressedSize - LZMA_HEADER_SIZE; ISzAllocatorAlloc lzmaAlloc(allocator); ELzmaStatus status; int res = LzmaDecode((Byte *)uncompressed, &uncompressedSizeCmp, - (Byte *)compressed + LZMA86_HEADER_SIZE, &compressedSizeTmp, - (Byte *)compressed + 1, LZMA_PROPS_SIZE, LZMA_FINISH_ANY, &status, + (Byte *)compressed + LZMA_HEADER_SIZE, &compressedSizeTmp, + (Byte *)compressed + 1, LZMA_PROPS_SIZE, LZMA_FINISH_END, &status, &lzmaAlloc); - if (SZ_OK != res || (status != LZMA_STATUS_FINISHED_WITH_MARK && status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)) + if (SZ_OK != res || status != LZMA_STATUS_FINISHED_WITH_MARK) return false; if (uncompressedSizeCmp != uncompressedSize) return false; @@ -99,58 +95,43 @@ bool Compress(const char *uncompressed, size_t uncompressedSize, char *compresse if (*compressedSize < uncompressedSize + 1) return false; - if (*compressedSize < LZMA86_HEADER_SIZE) + if (*compressedSize < LZMA_HEADER_SIZE) goto Store; CLzmaEncProps props; LzmaEncProps_Init(&props); - size_t bjc_size = (size_t)-1, lzma_size = (size_t)-1; - - SizeT outSize = *compressedSize - LZMA86_HEADER_SIZE; - SizeT propsSize = LZMA_PROPS_SIZE; - SRes res = LzmaEncode((Byte *)compressed + LZMA86_HEADER_SIZE, &outSize, (const Byte *)uncompressed, uncompressedSize, &props, (Byte *)compressed + 1, &propsSize, FALSE, NULL, &lzmaAlloc, &lzmaAlloc); - if (SZ_OK == res && propsSize == LZMA_PROPS_SIZE) - lzma_size = outSize + LZMA86_HEADER_SIZE; - + // always apply the BJC filter for speed (else two or three compression passes would be required) + size_t lzma_size = (size_t)-1; uint8_t *bjc_enc = (uint8_t *)Allocator::Alloc(allocator, uncompressedSize); if (bjc_enc) { memcpy(bjc_enc, uncompressed, uncompressedSize); UInt32 x86State; x86_Convert_Init(x86State); x86_Convert(bjc_enc, uncompressedSize, 0, &x86State, 1); - - outSize = *compressedSize - LZMA86_HEADER_SIZE; - propsSize = LZMA_PROPS_SIZE; - res = LzmaEncode((Byte *)compressed + LZMA86_HEADER_SIZE, &outSize, bjc_enc, uncompressedSize, &props, (Byte *)compressed + 1, &propsSize, FALSE, NULL, &lzmaAlloc, &lzmaAlloc); - if (SZ_OK == res && propsSize == LZMA_PROPS_SIZE) - bjc_size = outSize + LZMA86_HEADER_SIZE; - - Allocator::Free(allocator, bjc_enc); } - if (bjc_size < lzma_size) { - compressed[0] = 1; - *compressedSize = bjc_size; - } - else if (lzma_size < uncompressedSize + 1) { - compressed[0] = 0; + SizeT outSize = *compressedSize - LZMA_HEADER_SIZE; + SizeT propsSize = LZMA_PROPS_SIZE; + SRes res = LzmaEncode((Byte *)compressed + LZMA_HEADER_SIZE, &outSize, + bjc_enc ? bjc_enc : (const Byte *)uncompressed, uncompressedSize, + &props, (Byte *)compressed + 1, &propsSize, + TRUE /* add EOS marker */, NULL, &lzmaAlloc, &lzmaAlloc); + if (SZ_OK == res && propsSize == LZMA_PROPS_SIZE) + lzma_size = outSize + LZMA_HEADER_SIZE; + Allocator::Free(allocator, bjc_enc); + + if (lzma_size < uncompressedSize + 1) { + compressed[0] = bjc_enc ? 1 : 0; *compressedSize = lzma_size; - if (bjc_enc) { - outSize = *compressedSize - LZMA86_HEADER_SIZE; - propsSize = LZMA_PROPS_SIZE; - LzmaEncode((Byte *)compressed + LZMA86_HEADER_SIZE, &outSize, (const Byte *)uncompressed, uncompressedSize, &props, (Byte *)compressed + 1, &propsSize, FALSE, NULL, &lzmaAlloc, &lzmaAlloc); - } } else { Store: compressed[0] = (uint8_t)-1; memcpy(compressed + 1, uncompressed, uncompressedSize); *compressedSize = uncompressedSize + 1; - return true; } - // TODO: don't save this redundant information - ByteWriterLE(compressed + 1 + LZMA_PROPS_SIZE, LZMA86_HEADER_SIZE - 1 - LZMA_PROPS_SIZE).Write64(uncompressedSize); + return true; } diff --git a/src/utils/LzzaUtil.cpp b/src/utils/LzzaUtil.cpp deleted file mode 100644 index f19ceb8b6d48..000000000000 --- a/src/utils/LzzaUtil.cpp +++ /dev/null @@ -1,323 +0,0 @@ -/* Copyright 2014 the SumatraPDF project authors (see AUTHORS file). - License: Simplified BSD (see COPYING.BSD) */ - -#define __STDC_LIMIT_MACROS -#include "BaseUtil.h" -#include "LzzaUtil.h" - -#include "ByteReader.h" -#include "ByteWriter.h" -#include "FileUtil.h" - -#include -#include -#include - -namespace lzza { - -// the signature must appear right before the first ZIP file entry -#define LZZA_SIGNATURE 0x415a7a4c -#define ZIP_LOCAL_SIGNATURE 0x04034b50 -#define ZIP_CDIR_SIGNATURE 0x02014b50 -#define ZIP_EOCD_SIGNATURE 0x06054b50 - -#define ZIP_LZMA_HEADER_LEN (4 + LZMA_PROPS_SIZE) -// LZMA data has EOS marker; filename is UTF-8 -#define ZIP_LZMA_ENTRY_FLAGS ((1 << 1) | (1 << 11)) - -struct ISzAllocatorAlloc : ISzAlloc { - Allocator *allocator; - - static void *_Alloc(void *p, size_t size) { - ISzAllocatorAlloc *a = (ISzAllocatorAlloc *)p; - return Allocator::Alloc(a->allocator, size); - } - static void _Free(void *p, void *address) { - ISzAllocatorAlloc *a = (ISzAllocatorAlloc *)p; - Allocator::Free(a->allocator, address); - } - - ISzAllocatorAlloc(Allocator *allocator) { - this->Alloc = _Alloc; - this->Free = _Free; - this->allocator = allocator; - } -}; - -static uint32_t LzmaCompress(uint8_t *out, uint32_t outsize, const uint8_t *in, uint32_t insize, Allocator *allocator=NULL) -{ - if (outsize < ZIP_LZMA_HEADER_LEN) - return 0; - - ISzAllocatorAlloc lzmaAlloc(allocator); - SizeT destLen = outsize - ZIP_LZMA_HEADER_LEN; - SizeT propsLen = LZMA_PROPS_SIZE; - CLzmaEncProps props; - - LzmaEncProps_Init(&props); - SRes res = LzmaEncode(out + ZIP_LZMA_HEADER_LEN, &destLen, in, insize, &props, out + 4, &propsLen, TRUE, NULL, &lzmaAlloc, &lzmaAlloc); - if (res != SZ_OK || propsLen != LZMA_PROPS_SIZE) - return 0; - - ByteWriterLE lzmaZipHeader(out, 4); - lzmaZipHeader.Write16(0); - lzmaZipHeader.Write16((uint16_t)propsLen); - return (uint32_t)(destLen + ZIP_LZMA_HEADER_LEN); -} - -static bool LzmaDecompress(uint8_t *out, uint32_t outsize, const uint8_t *in, uint32_t insize, Allocator *allocator=NULL) -{ - if (insize < ZIP_LZMA_HEADER_LEN) - return false; - - ByteReader br(in, 4); - if (br.WordLE(0) != 0 || br.WordLE(2) != LZMA_PROPS_SIZE) - return false; - - ISzAllocatorAlloc lzmaAlloc(allocator); - SizeT uncompressedSize = outsize; - SizeT compressedSize = insize - ZIP_LZMA_HEADER_LEN; - ELzmaStatus status; - - SRes res = LzmaDecode(out, &uncompressedSize, in + ZIP_LZMA_HEADER_LEN, &compressedSize, in + 4, LZMA_PROPS_SIZE, LZMA_FINISH_END, &status, &lzmaAlloc); - - return res == SZ_OK && status == LZMA_STATUS_FINISHED_WITH_MARK && uncompressedSize == outsize; -} - -struct ArchiveEntry { - const char *name; - const uint8_t *data; - uint16_t method; - uint32_t crc32; - uint32_t dosdate; - uint32_t compressedSize; - uint32_t uncompressedSize; -}; - -// TODO: optimize by verifying the entire archive and caching all entry data? -static bool FindArchiveEntry(Archive *lzza, ArchiveEntry *entry, const char *fileName, int idx) -{ - ByteReader br(lzza->data, lzza->dataLen); - if (br.DWordLE(0) != LZZA_SIGNATURE) - return false; - - size_t offset = 4; - for (;;) { - // sanity checks - if (offset + 30 > lzza->dataLen) - return false; - if (br.DWordLE(offset + 0) != ZIP_LOCAL_SIGNATURE) - return false; - if (br.WordLE(offset + 28) != 4) - return false; - if (br.WordLE(offset + 6) != ZIP_LZMA_ENTRY_FLAGS) - return false; - // read entry values - entry->method = br.WordLE(offset + 8); - entry->dosdate = br.DWordLE(offset + 10); - entry->crc32 = br.DWordLE(offset + 14); - entry->compressedSize = br.DWordLE(offset + 18); - entry->uncompressedSize = br.DWordLE(offset + 22); - uint16_t nameLen = br.WordLE(offset + 26); - // sanity checks - if (entry->method != 0 && entry->method != 14) - return false; - if (0 == entry->method && entry->compressedSize != entry->uncompressedSize) - return false; - if (entry->compressedSize > lzza->dataLen || offset + 34 + nameLen + entry->compressedSize > lzza->dataLen) - return false; - if (br.Byte(offset + 30 + nameLen)) - return false; - // name and data are now safe to use - entry->name = &lzza->data[offset + 30]; - entry->data = (const uint8_t *)lzza->data + offset + 34 + nameLen; - - if (fileName && str::Eq(entry->name, fileName)) - return true; - if (idx-- == 0) - return true; - offset += 34 + nameLen + entry->compressedSize; - } -} - -static FileData *GetFileData(Archive *lzza, const char *fileName, int idx, Allocator *allocator=NULL) -{ - ArchiveEntry entry; - if (!FindArchiveEntry(lzza, &entry, fileName, idx)) - return NULL; - - FileData *fd = (FileData *)Allocator::Alloc(allocator, sizeof(FileData) + entry.uncompressedSize); - if (!fd) - return NULL; - fd->dataSize = entry.uncompressedSize; - fd->name = entry.name; - - FILETIME localFt; - if (!DosDateTimeToFileTime(HIWORD(entry.dosdate), LOWORD(entry.dosdate), &localFt) || - !LocalFileTimeToFileTime(&localFt, &fd->ft)) { - fd->ft.dwLowDateTime = fd->ft.dwHighDateTime = 0; - } - - if (entry.method == 0) { - memcpy(fd->data, entry.data, fd->dataSize); - } - else if (!LzmaDecompress((uint8_t *)fd->data, fd->dataSize, (const uint8_t *)entry.data, entry.compressedSize, allocator)) { - Allocator::Free(allocator, fd); - return NULL; - } - - uint32_t realCrc = crc32(0, (const uint8_t *)fd->data, (uint32_t)fd->dataSize); - if (realCrc != entry.crc32) { - Allocator::Free(allocator, fd); - return NULL; - } - - return fd; -} - -FileData *GetFileData(Archive *lzza, int idx, Allocator *allocator) -{ - return GetFileData(lzza, NULL, idx, allocator); -} - -FileData *GetFileData(Archive *lzza, const char *fileName, Allocator *allocator) -{ - return GetFileData(lzza, fileName, -1, allocator); -} - -bool ExtractFiles(const char *archivePath, const char *dstDir, const char **files, Allocator *allocator) -{ - Archive lzza; - lzza.data = file::ReadAllUtf(archivePath, &lzza.dataLen, allocator); - if (!lzza.data) - return false; - - bool ok = true; - for (; *files; files++) { - FileData *fd = GetFileData(&lzza, *files, -1, allocator); - if (!fd) { - ok = false; - continue; - } - char *filePath = path::JoinUtf(dstDir, fd->name, allocator); - if (filePath) { - str::TransChars(filePath, "/", "\\"); - ok &= file::WriteAllUtf(filePath, fd->data, fd->dataSize); - Allocator::Free(allocator, filePath); - } - else { - ok = false; - } - Allocator::Free(allocator, fd); - } - return ok; -} - -static bool AppendEntry(str::Str& data, str::Str& centralDir, const char *nameUtf8, const char *filedata, size_t filelen, uint32_t dosdate) -{ - CrashIf(filelen >= UINT32_MAX); - CrashIf(str::Len(nameUtf8) >= UINT16_MAX); - - size_t fileOffset = data.Size(); - uInt crc = crc32(0, (const Bytef *)filedata, (uInt)filelen); - size_t namelen = str::Len(nameUtf8); - - uint16_t method = 14 /* LZMA */; - uLongf compressedSize = (uint32_t)filelen; - ScopedMem compressed((uint8_t *)malloc(filelen)); - if (!compressed) - return false; - compressedSize = LzmaCompress(compressed, (uint32_t)filelen, (const uint8_t *)filedata, (uint32_t)filelen); - if (!compressedSize) { - method = 0 /* Stored */; - memcpy(compressed.Get(), filedata, filelen); - compressedSize = (uint32_t)filelen; - } - - ByteWriterLE local(data.AppendBlanks(30), 30); - local.Write32(ZIP_LOCAL_SIGNATURE); - local.Write16(63); // version needed to extract - local.Write16(ZIP_LZMA_ENTRY_FLAGS); - local.Write16(method); - local.Write32(dosdate); - local.Write32(crc); - local.Write32(compressedSize); - local.Write32((uint32_t)filelen); - local.Write16((uint16_t)namelen); - local.Write16(4); // 0-terminator(s) in extra data field - data.Append(nameUtf8, namelen); - data.AppendBlanks(4); - data.Append((const char *)compressed.Get(), compressedSize); - - ByteWriterLE central(centralDir.AppendBlanks(46), 46); - central.Write32(ZIP_CDIR_SIGNATURE); - central.Write32(63 | (63 << 16)); // versions - central.Write16(ZIP_LZMA_ENTRY_FLAGS); - central.Write16(method); - central.Write32(dosdate); - central.Write32(crc); - central.Write32(compressedSize); - central.Write32((uint32_t)filelen); - central.Write16((uint16_t)namelen); - central.Write32(0); // extra field and file comment lengths - central.Write32(0); // disk number and internal attributes - central.Write32(0); // external file attributes - central.Write32((uint32_t)fileOffset); - centralDir.Append(nameUtf8, namelen); - - return true; -} - -bool CreateArchive(const WCHAR *archivePath, const WCHAR *srcDir, WStrVec& names) -{ - str::Str data; - str::Str centralDir; - - ByteWriterLE lzzaHeader(data.AppendBlanks(4), 4); - lzzaHeader.Write32(LZZA_SIGNATURE); - - for (size_t i = 0; i < names.Count(); i += 2) { - ScopedMem filepath(path::Join(srcDir, names.At(i))); - size_t filelen; - ScopedMem filedata(file::ReadAll(filepath, &filelen)); - if (!filedata) - return false; - - uint32_t dosdatetime = 0; - FILETIME ft = file::GetModificationTime(filepath); - if (ft.dwLowDateTime || ft.dwHighDateTime) { - FILETIME ftLocal; - WORD dosDate, dosTime; - if (FileTimeToLocalFileTime(&ft, &ftLocal) && - FileTimeToDosDateTime(&ftLocal, &dosDate, &dosTime)) { - dosdatetime = MAKELONG(dosTime, dosDate); - } - } - - ScopedMem inArchiveName(str::conv::ToUtf8(names.At(names.At(i + 1) ? i + 1 : i))); - str::TransChars(inArchiveName, "\\", "/"); - - if (!AppendEntry(data, centralDir, inArchiveName, filedata, filelen, dosdatetime)) - return false; - } - - CrashIf(data.Count() >= UINT32_MAX); - CrashIf(names.Count() / 2 >= UINT16_MAX); - - // central directory is only needed so that LZZA archives are proper ZIP archives - // (it isn't read or verified by the extraction code above) - size_t centralDirOffset = data.Size(); - data.Append(centralDir.Get(), centralDir.Size()); - ByteWriterLE eocd(data.AppendBlanks(22), 22); - eocd.Write32(ZIP_EOCD_SIGNATURE); - eocd.Write32(0); // disk numbers - eocd.Write16((uint16_t)(names.Count() / 2)); - eocd.Write16((uint16_t)(names.Count() / 2)); - eocd.Write32((uint32_t)centralDir.Size()); - eocd.Write32((uint32_t)centralDirOffset); - eocd.Write16(0); // comment len - - return file::WriteAll(archivePath, data.Get(), data.Size()); -} - -} diff --git a/src/utils/LzzaUtil.h b/src/utils/LzzaUtil.h deleted file mode 100644 index c27bf2fd94b9..000000000000 --- a/src/utils/LzzaUtil.h +++ /dev/null @@ -1,37 +0,0 @@ -/* Copyright 2014 the SumatraPDF project authors (see AUTHORS file). - License: Simplified BSD (see COPYING.BSD) */ - -#ifndef LzzaUtil_h -#define LzzaUtil_h - -// Lzma ZIP Archive is a restricted ZIP-subset containing only LZMA compressed data -// (this allows for less code required for reading and writing such files) - -namespace lzza { - -struct Archive { - const char *data; - size_t dataLen; - - Archive(const char *data=NULL, size_t dataLen=0) : data(data), dataLen(dataLen) { } -}; - -struct FileData { - const char *name; - FILETIME ft; - size_t dataSize; - char data[1]; -}; - -FileData *GetFileData(Archive *lzza, int idx, Allocator *allocator=NULL); -FileData *GetFileData(Archive *lzza, const char *fileName, Allocator *allocator=NULL); - -// files must be NULL-terminated, all paths must be UTF-8 encoded -bool ExtractFiles(const char *archivePath, const char *dstDir, const char **files, Allocator *allocator=NULL); - -// for every file, names must contain a relative path to srcDir followed by either NULL or the desired in-archive name -bool CreateArchive(const WCHAR *archivePath, const WCHAR *srcDir, WStrVec& names); - -} - -#endif diff --git a/vs/sumatrapdf-vc2008.vcproj b/vs/sumatrapdf-vc2008.vcproj index 57b266987b73..0176b3e19c20 100644 --- a/vs/sumatrapdf-vc2008.vcproj +++ b/vs/sumatrapdf-vc2008.vcproj @@ -187,14 +187,6 @@ RelativePath="..\src\utils\LzmaSimpleArchive.h" > - - - - @@ -1217,10 +1209,6 @@ - - diff --git a/vs/sumatrapdf-vc2010.vcxproj b/vs/sumatrapdf-vc2010.vcxproj index eb08e918f025..2b8ba3414cf0 100755 --- a/vs/sumatrapdf-vc2010.vcxproj +++ b/vs/sumatrapdf-vc2010.vcxproj @@ -99,7 +99,6 @@ - @@ -188,7 +187,6 @@ - @@ -473,7 +471,6 @@ - diff --git a/vs/sumatrapdf-vc2010.vcxproj.filters b/vs/sumatrapdf-vc2010.vcxproj.filters index eba8e9cee6b1..d76ff3e709fc 100755 --- a/vs/sumatrapdf-vc2010.vcxproj.filters +++ b/vs/sumatrapdf-vc2010.vcxproj.filters @@ -99,9 +99,6 @@ sumatra - - sumatra - sumatra @@ -366,9 +363,6 @@ utils - - utils - utils @@ -1217,9 +1211,6 @@ utils - - utils - utils diff --git a/vs/sumatrapdf-vc2012.vcxproj b/vs/sumatrapdf-vc2012.vcxproj index daddb2e09d12..ca06e91364c5 100755 --- a/vs/sumatrapdf-vc2012.vcxproj +++ b/vs/sumatrapdf-vc2012.vcxproj @@ -118,7 +118,6 @@ - @@ -207,7 +206,6 @@ - @@ -492,7 +490,6 @@ - diff --git a/vs/sumatrapdf-vc2012.vcxproj.filters b/vs/sumatrapdf-vc2012.vcxproj.filters index eba8e9cee6b1..d76ff3e709fc 100755 --- a/vs/sumatrapdf-vc2012.vcxproj.filters +++ b/vs/sumatrapdf-vc2012.vcxproj.filters @@ -99,9 +99,6 @@ sumatra - - sumatra - sumatra @@ -366,9 +363,6 @@ utils - - utils - utils @@ -1217,9 +1211,6 @@ utils - - utils - utils