Skip to content
Commits on Source (7)
unarr contains code by:
* The Unarchiver project (https://code.google.com/p/theunarchiver/)
* The Unarchiver project (https://bitbucket.org/kosovan/theunarchiver/)
* Simon Bünzli (zeniko at gmail.com, http://www.zeniko.ch/#SumatraPDF)
* Felix Kauselmann (licorn at gmail.com)
* Bastien Nocera (hadess@hadess.net, http://www.hadess.net/)
Most code is licensed under LGPLv3 (see COPYING). Exceptions are in code
included from other projects:
......
# (lib)unarr changelog
## 1.0.1 - 2017-11-04
This is a bugfix release.
### Fixed
* Fixed typo in pkg-config.pc.cmake template
## 1.0.0 - 2017-09-22
### Added
* Cmake based build system for library builds
* Support for pkg-config (libunarr.pc)
* Windows compatible export header for DLL builds
* xz utils / libLZMA can be used as decoder for LZMA1 and XZ (LZMA2) compressed
ZIP archives.
* The internal LZMA1 decoder can be replaced with xz utils / libLZMA if present
### Changed
* LZMA SDK code was updated to version 17.01 beta
* 7z extraction support is currently broken due to LZMA SDK api changes.
* Unarr sample application (unarr-test) and its makefile
(legacy unarr build system) have been moved to the [test](test) folder
### Fixed
* Various small bugfixes related to compiler warnings
cmake_minimum_required(VERSION 3.3 FATAL_ERROR)
project(unarr VERSION 1.0.0 LANGUAGES C)
set(PROJECT_DESCRIPTION
"A decompression library for rar, tar and zip files.")
include(GNUInstallDirs)
# Set build type to default if unset.
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build." FORCE)
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
"MinSizeRel" "RelWithDebInfo")
endif()
# Build options
option(BUILD_SHARED_LIBS "Build ${PROJECT_NAME} as a shared library" ON)
# Build target
add_library(unarr
_7z/_7z.h
_7z/_7z.c
common/allocator.h
common/unarr-imp.h
common/conv.c
common/crc32.c
#common/custalloc.c
common/stream.c
common/unarr.c
lzmasdk/7zTypes.h
lzmasdk/CpuArch.h
lzmasdk/Ppmd.h
lzmasdk/Ppmd7.h
lzmasdk/Ppmd8.h
lzmasdk/Precomp.h
lzmasdk/CpuArch.c
lzmasdk/Ppmd7.c
lzmasdk/Ppmd8.c
lzmasdk/Ppmd7Dec.c
lzmasdk/Ppmd8Dec.c
rar/lzss.h
rar/rar.h
rar/rarvm.h
rar/filter-rar.c
rar/uncompress-rar.c
rar/huffman-rar.c
rar/rar.c
rar/rarvm.c
rar/parse-rar.c
tar/tar.h
tar/parse-tar.c
tar/tar.c
zip/inflate.h
zip/zip.h
zip/inflate.c
zip/parse-zip.c
zip/uncompress-zip.c
zip/zip.c)
set_target_properties(unarr PROPERTIES
PUBLIC_HEADER unarr.h
C_VISIBILITY_PRESET hidden
C_STANDARD 99
C_STANDARD_REQUIRED ON
DEFINE_SYMBOL UNARR_EXPORT_SYMBOLS
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR})
if(BUILD_SHARED_LIBS)
target_compile_definitions(unarr PUBLIC UNARR_IS_SHARED_LIBRARY)
endif()
find_package(BZip2)
if(BZIP2_FOUND)
target_include_directories(unarr PRIVATE ${BZIP_INCLUDE_DIRS})
target_link_libraries(unarr ${BZIP2_LIBRARIES})
target_compile_definitions(unarr PRIVATE -DHAVE_BZIP2)
# Bzip2 upstream does not supply a .pc file. Add it to Libs.private.
set(PROJECT_LIBS_PRIVATE "-I${BZIP_INCLUDE_DIRS} -l${BZIP2_LIBRARIES}")
endif()
find_package(LibLZMA)
if(LIBLZMA_FOUND)
target_include_directories(unarr PRIVATE ${LIBLZMA_INCLUDE_DIRS})
target_link_libraries(unarr ${LIBLZMA_LIBRARIES})
target_compile_definitions(unarr PRIVATE -DHAVE_LIBLZMA)
set(PROJECT_REQUIRES_PRIVATE "${UNARR_REQUIRES_PRIVATE} liblzma")
else()
target_sources(unarr PRIVATE
lzmasdk/LzmaDec.h
lzmasdk/LzmaDec.c)
endif()
find_package(ZLIB)
if(ZLIB_FOUND)
target_include_directories(unarr PRIVATE ${ZLIB_INCLUDE_DIRS})
target_link_libraries(unarr ${ZLIB_LIBRARIES})
target_compile_definitions(unarr PRIVATE -DHAVE_ZLIB)
# Add zlib to libunarr.pc Requires.private
set(PROJECT_REQUIRES_PRIVATE "${PROJECT_REQUIRES_PRIVATE} zlib")
endif()
# Compiler specific settings
if(UNIX OR MINGW OR MSYS)
target_compile_options(unarr PRIVATE -Wall -Wextra -pedantic
-Wstrict-prototypes -Wmissing-prototypes
-Werror-implicit-function-declaration
$<$<CONFIG:Release>:-fomit-frame-pointer>
$<$<OR:$<C_COMPILER_ID:Clang>,$<C_COMPILER_ID:AppleClang>>:
-Wno-missing-field-initializers>
-flto)
target_compile_definitions(unarr PRIVATE -D_FILE_OFFSET_BITS=64)
# Linker flags
# Clang linker needs -flto too when doing lto
if("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang")
set_target_properties(unarr PROPERTIES LINK_FLAGS
"-Wl,--no-undefined -Wl,--as-needed -flto")
# Apple ld uses different syntax for undefined symbol check
elseif("${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang")
set_target_properties(unarr PROPERTIES LINK_FLAGS
"-Wl,-undefined,error -flto")
else()
set_target_properties(unarr PROPERTIES LINK_FLAGS
"-Wl,--no-undefined -Wl,--as-needed")
endif()
endif()
if(MSVC)
target_compile_options(unarr PRIVATE /W3
$<$<CONFIG:Release>:/Ox>)
target_compile_definitions(unarr PRIVATE _CRT_SECURE_NO_WARNINGS)
endif()
# Write pkg-config file
configure_file("pkg-config.pc.cmake" "lib${PROJECT_NAME}.pc" @ONLY)
# Install library and header
install(TARGETS unarr
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
# Install pkg-config file
install(FILES
${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib${PROJECT_NAME}.pc
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
unarr is a decompression library for RAR, TAR, ZIP and 7z archives.
unarr originated as a port of the RAR extraction features from
The Unarchiver project required for extracting images from comic
book archives (.cbr). It was written as an alternative to
libarchive which didn't have support for parsing filters or solid
compression at the time.
There is currently only an experimental Linux Makefile for building
unarr (see ../makefile.msvc for what SumatraPDF does under Windows).
In any case, compiling unarr should be as simple as compiling all
files with a C99 compatible compiler (omit main.c if you want to use
it as a library).
The following symbols can be defined if other libraries are present
in the include path:
Symbol Required header Required for (format/method)
------------------------------------------------------------
HAVE_ZLIB zlib.h faster CRC-32 and Deflate
HAVE_BZIP2 bzlib.h ZIP / Bzip2
HAVE_7Z 7z.h 7Z / LZMA, LZMA2, BCJ
_7ZIP_PPMD_SUPPPORT 7Z / PPMd
# (lib)unarr
**(lib)unarr** is a decompression library for RAR, TAR, ZIP and 7z* archives.
It was forked from **unarr**, which originated as a port of the RAR extraction
features from The Unarchiver project required for extracting images from comic
book archives. [Zeniko](https://github.com/zeniko/) wrote unarr as an
alternative to libarchive which didn't have support for parsing filters or
solid compression at the time.
While (lib)unarr was started with the intent of providing unarr with a proper
cmake based build system suitable for packaging and cross-platform development,
it's focus has now been extended to provide code maintenance and to continue the
development of unarr, which no longer is maintained.
## Getting started
### Building from source
#### Dependencies
(lib)unarr can take advantage of the following libraries if they are present:
* bzip2
* xz / libLZMA
* zlib
More information on what library is used for which purpose can be found in the
description for embedded builds.
#### Cmake
>mkdir build
>cd build
>cmake ..
>make
... as a static library
>cmake .. -DBUILD_SHARED_LIBS=OFF
Install
>make install
#### Embedded build
Make sure your compiler is C99 compatible, grab the source code, copy it into your project and adjust your build system accordingly.
You can define the following symbols to take advantage of third party libraries:
| Symbol | Required header | Required for (format/method)|
|-------------------|:---------------:|:----------------------------|
|HAVE_ZLIB | zlib.h | faster CRC-32 and Deflate |
|HAVE_BZIP2 | bzlib.h | ZIP / Bzip2 |
|HAVE_LIBLZMA | lzma.h | ZIP / LZMA, XZ(LZMA2) |
|HAVE_7Z | 7z.h | 7Z* / LZMA, LZMA2, BCJ |
|_7ZIP_PPMD_SUPPORT | | 7Z* / PPMd |
Make sure the required headers are present in the include path.
## Usage
### Examples
Check [unarr.h](unarr.h) and [unarr-test](test/main.c) to get a general feel
for the api and usage.
## Limitations
Unarr was written for comic book archives, so it currently doesn't support:
* password protected archives
* self extracting archives
* split archives
### 7z support
7z support is currently broken. This is due to two problems:
1. The version of the LZMA SDK used in the 7z extraction code is outdated and
no longer compatible with the LZMA code used in the other formats
2. The ANSI-C based 7z extraction code provided by the LZMA SDK has a known
performance issue that limits it's usefullness for large files with solid
compression (see https://github.com/zeniko/unarr/issues/4).
Fixing these problems requires a partial rewrite of the code involved.
unarr (1.0.1-1) unstable; urgency=medium
* Move to use fork at https://github.com/selmf/unarr
* Handle regular releases at new upstream
* Drop all patches besides a spelling error.
-- Alec Leamas <leamas.alec@gmail.com> Mon, 01 Oct 2018 01:23:17 -0400
unarr (0~20150801.d1be8c4-1) unstable; urgency=medium
* Initial release (Closes: #907070)
......
......@@ -10,7 +10,7 @@ Build-Depends: debhelper (>= 9),
Standards-Version: 4.2.1
Vcs-Browser: https://salsa.debian.org/debian-gis-team/unarr
Vcs-Git: https://salsa.debian.org/debian-gis-team/unarr.git
Homepage: https://github.com/zeniko/unarr
Homepage: https://github.com/selmf/unarr
Package: libunarr-dev
Architecture: any
......
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: unarr
Upstream-Contact: https://github.com/zeniko/unarr/issues
Source: https://github.com/zeniko/unarr
Comment: Source repacked to get rid of upstream crlf line endings.
Upstream-Contact: https://github.com/selmf/unarr/issues
Source: https://github.com/selmf/unarr
Files: *
Copyright: 2015, the unarr project authors (see AUTHORS file).
Simon Bünzli <zeniko at gmail.com, http://www.zeniko.ch/#SumatraPDF>
License: LGPL-3
Files: common/crc32.c lzmasdk/*
Files: debian/*
Copyright: 2018, Alec Leamas <leamas.alec@gmail.com>
License: GPL-2+
Files: lzmasdk/*
Copyright: none
License: public-domain
These files are in public domain.
Files: debian/*
Copyright: 2018 Alec Leamas <leamas.alec@gmail.com>
License: GPL-2+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version
.
On Debian systems, the full text of the GNU General Public
License version 2 can be found in the file
`/usr/share/common-licenses/GPL-2'.
License: LGPL-3
This package is free software; you can redistribute it and/or modify
......@@ -31,13 +40,3 @@ License: LGPL-3
On Debian systems, the full text of the GNU Lesser General Public
License version 3 can be found in the file
`/usr/share/common-licenses/LGPL-3'.
License: GPL-2+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version
.
On Debian systems, the full text of the GNU General Public
License version 2 can be found in the file
`/usr/share/common-licenses/GPL-2'.
......@@ -9,6 +9,8 @@ libunarr.so.1 #PACKAGE# #MINVER#
ar_entry_uncompress@Base 0~20150801.d1be8c4
ar_get_global_comment@Base 0~20150801.d1be8c4
ar_open_7z_archive@Base 0~20150801.d1be8c4
ar_open_file@Base 1.0.1
ar_open_memory@Base 1.0.1
ar_open_rar_archive@Base 0~20150801.d1be8c4
ar_open_tar_archive@Base 0~20150801.d1be8c4
ar_open_zip_archive@Base 0~20150801.d1be8c4
......
From: Alec Leamas <leamas.alec@nowhere.net>
Date: Sun, 2 Sep 2018 06:20:25 -0400
Subject: Build: Add a .gitignore.
---
.gitignore | 5 +++++
1 file changed, 5 insertions(+)
create mode 100644 .gitignore
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..f505019
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+*.o
+*.so
+build
+obj-*
+
Description: Fix spelling errors.
* amout -> amount
Author: Bas Couwenberg <sebastic@debian.org>
From: Bas Couwenberg <sebastic@debian.org>
Date: Thu, 20 Sep 2018 16:41:00 -0400
Subject: Fix spelling errors.
---
rar/filter-rar.c | 2 +-
unarr.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/rar/filter-rar.c b/rar/filter-rar.c
index de4ba3a..2670747 100644
--- a/rar/filter-rar.c
+++ b/rar/filter-rar.c
@@ -645,7 +645,7 @@ bool rar_run_filters(ar_archive_rar *rar
@@ -645,7 +645,7 @@ bool rar_run_filters(ar_archive_rar *rar)
filters->filterstart = SIZE_MAX;
end = (size_t)rar_expand(rar, end);
if (end != start + filter->blocklength) {
......@@ -13,14 +20,16 @@ Author: Bas Couwenberg <sebastic@debian.org>
return false;
}
diff --git a/unarr.h b/unarr.h
index 4999fd5..965e856 100644
--- a/unarr.h
+++ b/unarr.h
@@ -69,7 +69,7 @@ VISIBLE time64_t ar_entry_get_filetime(a
@@ -99,7 +99,7 @@ UNARR_EXPORT time64_t ar_entry_get_filetime(ar_archive *ar);
/* uncompresses the next 'count' bytes of the current entry into buffer; returns false on error */
VISIBLE bool ar_entry_uncompress(ar_archive *ar, void *buffer, size_t count);
UNARR_EXPORT bool ar_entry_uncompress(ar_archive *ar, void *buffer, size_t count);
-/* copies at most 'count' bytes of the archive's global comment (if any) into buffer; returns the actual amout of bytes copied (or, if 'buffer' is NULL, the required buffer size) */
+/* copies at most 'count' bytes of the archive's global comment (if any) into buffer; returns the actual amount of bytes copied (or, if 'buffer' is NULL, the required buffer size) */
VISIBLE size_t ar_get_global_comment(ar_archive *ar, void *buffer, size_t count);
UNARR_EXPORT size_t ar_get_global_comment(ar_archive *ar, void *buffer, size_t count);
/***** rar/rar *****/
From: Alec Leamas <leamas.alec@nowhere.net>
Date: Wed, 22 Aug 2018 09:22:01 -0400
Subject: build: Add Cmake files from https://github.com/selmf/unarr.
Origin: https://github.com/selmf/unarr
Add a CMakelists.txt and pkg-config .pc file from said upstream, a more
elaborated version of the original sources. Submitted to upstream as
https://github.com/zeniko/unarr/issues/9.
---
CMakeLists.txt | 178 ++++++++++++++++++++++++++++++++++++++++++++++++++++
pkg-config.pc.cmake | 11 ++++
2 files changed, 189 insertions(+)
create mode 100644 CMakeLists.txt
create mode 100644 pkg-config.pc.cmake
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..f4babfe
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,178 @@
+cmake_minimum_required(VERSION 3.3 FATAL_ERROR)
+
+project(unarr VERSION 1.0.0 LANGUAGES C)
+set(PROJECT_DESCRIPTION
+ "A decompression library for rar, tar and zip files.")
+
+include(GNUInstallDirs)
+
+# Set build type to default if unset.
+if(NOT CMAKE_BUILD_TYPE)
+ set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build." FORCE)
+ set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
+ "MinSizeRel" "RelWithDebInfo")
+endif()
+
+# Build options
+option(BUILD_SHARED_LIBS "Build ${PROJECT_NAME} as a shared library" ON)
+option(ENABLE_7Z "Build with 7z support" OFF)
+
+# Build target
+add_library(unarr
+ _7z/_7z.h
+ _7z/_7z.c
+ common/allocator.h
+ common/unarr-imp.h
+ common/conv.c
+ common/crc32.c
+ #common/custalloc.c
+ common/stream.c
+ common/unarr.c
+ lzmasdk/7zTypes.h
+ lzmasdk/CpuArch.h
+ lzmasdk/Ppmd.h
+ lzmasdk/Ppmd7.h
+ lzmasdk/Ppmd8.h
+ lzmasdk/Precomp.h
+ lzmasdk/CpuArch.c
+ lzmasdk/Ppmd7.c
+ lzmasdk/Ppmd8.c
+ lzmasdk/Ppmd7Dec.c
+ lzmasdk/Ppmd8Dec.c
+ rar/lzss.h
+ rar/rar.h
+ rar/rarvm.h
+ rar/filter-rar.c
+ rar/uncompress-rar.c
+ rar/huffman-rar.c
+ rar/rar.c
+ rar/rarvm.c
+ rar/parse-rar.c
+ tar/tar.h
+ tar/parse-tar.c
+ tar/tar.c
+ zip/inflate.h
+ zip/zip.h
+ zip/inflate.c
+ zip/parse-zip.c
+ zip/uncompress-zip.c
+ zip/zip.c)
+
+set_target_properties(unarr PROPERTIES
+ PUBLIC_HEADER unarr.h
+ C_VISIBILITY_PRESET hidden
+ C_STANDARD 99
+ C_STANDARD_REQUIRED ON
+ DEFINE_SYMBOL UNARR_EXPORT_SYMBOLS
+ VERSION ${PROJECT_VERSION}
+ SOVERSION ${PROJECT_VERSION_MAJOR})
+
+if(BUILD_SHARED_LIBS)
+ target_compile_definitions(unarr PUBLIC UNARR_IS_SHARED_LIBRARY)
+endif()
+
+find_package(BZip2)
+if(BZIP2_FOUND)
+ target_include_directories(unarr PRIVATE ${BZIP_INCLUDE_DIRS})
+ target_link_libraries(unarr ${BZIP2_LIBRARIES})
+ target_compile_definitions(unarr PRIVATE -DHAVE_BZIP2)
+ # Bzip2 upstream does not supply a .pc file. Add it to Libs.private.
+ set(PROJECT_LIBS_PRIVATE "-I${BZIP_INCLUDE_DIRS} -l${BZIP2_LIBRARIES}")
+endif()
+
+find_package(LibLZMA)
+if(LIBLZMA_FOUND)
+ target_include_directories(unarr PRIVATE ${LIBLZMA_INCLUDE_DIRS})
+ target_link_libraries(unarr ${LIBLZMA_LIBRARIES})
+ target_compile_definitions(unarr PRIVATE -DHAVE_LIBLZMA)
+ set(PROJECT_REQUIRES_PRIVATE "${UNARR_REQUIRES_PRIVATE} liblzma")
+else()
+ target_sources(unarr PRIVATE
+ lzmasdk/LzmaDec.h
+ lzmasdk/LzmaDec.c)
+endif()
+
+find_package(ZLIB)
+if(ZLIB_FOUND)
+ target_include_directories(unarr PRIVATE ${ZLIB_INCLUDE_DIRS})
+ target_link_libraries(unarr ${ZLIB_LIBRARIES})
+ target_compile_definitions(unarr PRIVATE -DHAVE_ZLIB)
+ # Add zlib to libunarr.pc Requires.private
+ set(PROJECT_REQUIRES_PRIVATE "${PROJECT_REQUIRES_PRIVATE} zlib")
+endif()
+
+if(ENABLE_7Z)
+ target_sources(unarr PRIVATE
+ lzmasdk/7z.h
+ lzmasdk/7zArcIn.c
+ lzmasdk/7zBuf.h
+ lzmasdk/7zBuf.c
+ lzmasdk/7zDec.c
+ lzmasdk/7zStream.c
+ lzmasdk/Bcj2.h
+ lzmasdk/Bcj2.c
+ lzmasdk/Bra.c
+ lzmasdk/Bra.h
+ lzmasdk/Bra86.c
+ lzmasdk/BraIA64.c
+ lzmasdk/7zCrc.h
+ lzmasdk/Delta.h
+ lzmasdk/Delta.c
+ lzmasdk/Lzma2Dec.h
+ lzmasdk/Lzma2Dec.c)
+ if(LIBLZMA_FOUND)
+ target_sources(unarr PRIVATE
+ lzmasdk/LzmaDec.h
+ lzmasdk/LzmaDec.c)
+ endif()
+target_compile_definitions(unarr PRIVATE -DHAVE_7Z -D_7ZIP_PPMD_SUPPPORT)
+endif()
+
+# Compiler specific settings
+
+if(UNIX OR MINGW OR MSYS)
+ target_compile_options(unarr PRIVATE -Wall -Wextra -pedantic
+ -Wstrict-prototypes -Wmissing-prototypes
+ -Werror-implicit-function-declaration
+ $<$<CONFIG:Release>:-fomit-frame-pointer>
+ $<$<OR:$<C_COMPILER_ID:Clang>,$<C_COMPILER_ID:AppleClang>>:
+ -Wno-missing-field-initializers>
+ -flto)
+ target_compile_definitions(unarr PRIVATE -D_FILE_OFFSET_BITS=64)
+
+ # Linker flags
+
+ # Clang linker needs -flto too when doing lto
+ if("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang")
+ set_target_properties(unarr PROPERTIES LINK_FLAGS
+ "-Wl,--no-undefined -Wl,--as-needed -flto")
+ # Apple ld uses different syntax for undefined symbol check
+ elseif("${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang")
+ set_target_properties(unarr PROPERTIES LINK_FLAGS
+ "-Wl,-undefined,error -flto")
+ else()
+ set_target_properties(unarr PROPERTIES LINK_FLAGS
+ "-Wl,--no-undefined -Wl,--as-needed")
+ endif()
+endif()
+
+if(MSVC)
+ target_compile_options(unarr PRIVATE /W3
+ $<$<CONFIG:Release>:/Ox>)
+ target_compile_definitions(unarr PRIVATE _CRT_SECURE_NO_WARNINGS)
+endif()
+
+# Write pkg-config file
+configure_file("pkg-config.pc.cmake" "lib${PROJECT_NAME}.pc" @ONLY)
+
+# Install library and header
+install(TARGETS unarr
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
+
+# Install pkg-config file
+install(FILES
+ ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib${PROJECT_NAME}.pc
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
diff --git a/pkg-config.pc.cmake b/pkg-config.pc.cmake
new file mode 100644
index 0000000..ada86f1
--- /dev/null
+++ b/pkg-config.pc.cmake
@@ -0,0 +1,11 @@
+prefix=@CMAKE_INSTALL_PREFIX@
+includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
+libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@
+
+Name: @PROJECT_NAME@
+Description: @PROJECT_DESCRIPTION@
+Version: @PROJECT_VERSION@
+Cflags: -I${includedir}
+Requires.private: @PROJECT_REQUIRES_PRIVATE@
+Libs: -L${libdir} -l@PROJECT_NAME@
+Libs.private: @PROJECT_LIBS_PRIVATE@
From: Alec Leamas <leamas.alec@nowhere.net>
Date: Sun, 2 Sep 2018 10:40:02 -0400
Subject: Build: fix as-needed madness.
---
CMakeLists.txt | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f4babfe..f76b642 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -150,9 +150,9 @@ if(UNIX OR MINGW OR MSYS)
elseif("${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang")
set_target_properties(unarr PROPERTIES LINK_FLAGS
"-Wl,-undefined,error -flto")
- else()
- set_target_properties(unarr PROPERTIES LINK_FLAGS
- "-Wl,--no-undefined -Wl,--as-needed")
+# else()
+# set_target_properties(unarr PROPERTIES LINK_FLAGS
+# "-Wl,--no-undefined -Wl,--as-needed")
endif()
endif()
From: Alec Leamas <leamas.alec@nowhere.net>
Date: Fri, 7 Sep 2018 16:02:20 -0400
Subject: unarr.h: Mark functions as visible.
---
unarr.h | 42 ++++++++++++++++++++++--------------------
1 file changed, 22 insertions(+), 20 deletions(-)
diff --git a/unarr.h b/unarr.h
index 5ef7447..2555017 100644
--- a/unarr.h
+++ b/unarr.h
@@ -4,6 +4,8 @@
#ifndef unarr_h
#define unarr_h
+#define VISIBLE __attribute__ ((visibility ("default")))
+
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
@@ -30,65 +32,65 @@ ar_stream *ar_open_istream(IStream *stream);
#endif
/* closes the stream and releases underlying resources */
-void ar_close(ar_stream *stream);
+VISIBLE void ar_close(ar_stream *stream);
/* tries to read 'count' bytes into buffer, advancing the read offset pointer; returns the actual number of bytes read */
-size_t ar_read(ar_stream *stream, void *buffer, size_t count);
+VISIBLE size_t ar_read(ar_stream *stream, void *buffer, size_t count);
/* moves the read offset pointer (same as fseek); returns false on failure */
-bool ar_seek(ar_stream *stream, off64_t offset, int origin);
+VISIBLE bool ar_seek(ar_stream *stream, off64_t offset, int origin);
/* shortcut for ar_seek(stream, count, SEEK_CUR); returns false on failure */
-bool ar_skip(ar_stream *stream, off64_t count);
+VISIBLE bool ar_skip(ar_stream *stream, off64_t count);
/* returns the current read offset (or 0 on error) */
-off64_t ar_tell(ar_stream *stream);
+VISIBLE off64_t ar_tell(ar_stream *stream);
/***** common/unarr *****/
typedef struct ar_archive_s ar_archive;
/* frees all data stored for the given archive; does not close the underlying stream */
-void ar_close_archive(ar_archive *ar);
+VISIBLE void ar_close_archive(ar_archive *ar);
/* reads the next archive entry; returns false on error or at the end of the file (use ar_at_eof to distinguish the two cases) */
-bool ar_parse_entry(ar_archive *ar);
+VISIBLE bool ar_parse_entry(ar_archive *ar);
/* reads the archive entry at the given offset as returned by ar_entry_get_offset (offset 0 always restarts at the first entry); should always succeed */
-bool ar_parse_entry_at(ar_archive *ar, off64_t offset);
+VISIBLE bool ar_parse_entry_at(ar_archive *ar, off64_t offset);
/* reads the (first) archive entry associated with the given name; returns false if the entry couldn't be found */
-bool ar_parse_entry_for(ar_archive *ar, const char *entry_name);
+VISIBLE bool ar_parse_entry_for(ar_archive *ar, const char *entry_name);
/* returns whether the last ar_parse_entry call has reached the file's expected end */
-bool ar_at_eof(ar_archive *ar);
+VISIBLE bool ar_at_eof(ar_archive *ar);
/* returns the name of the current entry as UTF-8 string; this pointer is only valid until the next call to ar_parse_entry; returns NULL on failure */
-const char *ar_entry_get_name(ar_archive *ar);
+VISIBLE const char *ar_entry_get_name(ar_archive *ar);
/* returns the stream offset of the current entry for use with ar_parse_entry_at */
-off64_t ar_entry_get_offset(ar_archive *ar);
+VISIBLE off64_t ar_entry_get_offset(ar_archive *ar);
/* returns the total size of uncompressed data of the current entry; read exactly that many bytes using ar_entry_uncompress */
-size_t ar_entry_get_size(ar_archive *ar);
+VISIBLE size_t ar_entry_get_size(ar_archive *ar);
/* returns the stored modification date of the current entry in 100ns since 1601/01/01 */
-time64_t ar_entry_get_filetime(ar_archive *ar);
+VISIBLE time64_t ar_entry_get_filetime(ar_archive *ar);
/* WARNING: don't manually seek in the stream between ar_parse_entry and the last corresponding ar_entry_uncompress call! */
/* uncompresses the next 'count' bytes of the current entry into buffer; returns false on error */
-bool ar_entry_uncompress(ar_archive *ar, void *buffer, size_t count);
+VISIBLE bool ar_entry_uncompress(ar_archive *ar, void *buffer, size_t count);
/* copies at most 'count' bytes of the archive's global comment (if any) into buffer; returns the actual amout of bytes copied (or, if 'buffer' is NULL, the required buffer size) */
-size_t ar_get_global_comment(ar_archive *ar, void *buffer, size_t count);
+VISIBLE size_t ar_get_global_comment(ar_archive *ar, void *buffer, size_t count);
/***** rar/rar *****/
/* checks whether 'stream' could contain RAR data and prepares for archive listing/extraction; returns NULL on failure */
-ar_archive *ar_open_rar_archive(ar_stream *stream);
+VISIBLE ar_archive *ar_open_rar_archive(ar_stream *stream);
/***** tar/tar *****/
/* checks whether 'stream' could contain TAR data and prepares for archive listing/extraction; returns NULL on failure */
-ar_archive *ar_open_tar_archive(ar_stream *stream);
+VISIBLE ar_archive *ar_open_tar_archive(ar_stream *stream);
/***** zip/zip *****/
/* checks whether 'stream' could contain ZIP data and prepares for archive listing/extraction; returns NULL on failure */
/* set deflatedonly for extracting XPS, EPUB, etc. documents where non-Deflate compression methods are not supported by specification */
-ar_archive *ar_open_zip_archive(ar_stream *stream, bool deflatedonly);
+VISIBLE ar_archive *ar_open_zip_archive(ar_stream *stream, bool deflatedonly);
/***** _7z/_7z *****/
/* checks whether 'stream' could contain 7Z data and prepares for archive listing/extraction; returns NULL on failure */
-ar_archive *ar_open_7z_archive(ar_stream *stream);
+VISIBLE ar_archive *ar_open_7z_archive(ar_stream *stream);
#endif
0001-Build-Add-a-.gitignore.patch
0002-build-Add-Cmake-files-from-https-github.com-selmf-un.patch
0003-Build-fix-as-needed-madness.patch
0004-unarr.h-Mark-functions-as-visible.patch
spelling-errors.patch
0001-Fix-spelling-errors.patch
version=4
opts="mode=git,pretty=0~%cd.%h" \
https://github.com/zeniko/unarr.git HEAD
# Issue asking for release tags:
# https://github.com/zeniko/unarr/issues/8
opts="filenamemangle=s%(?:.*?)?v?(\d[\d.]*)\.tar\.gz%unarr-$1.tar.gz%" \
https://github.com/selmf/unarr/tags \
(?:.*?/)?v?(\d[\d.]*)\.tar\.gz debian uupdate
/* 7zTypes.h -- Basic types
2013-11-12 : Igor Pavlov : Public domain */
2017-07-17 : Igor Pavlov : Public domain */
#ifndef __7Z_TYPES_H
#define __7Z_TYPES_H
......@@ -42,13 +42,23 @@ EXTERN_C_BEGIN
typedef int SRes;
#ifdef _WIN32
/* typedef DWORD WRes; */
typedef unsigned WRes;
#define MY_SRes_HRESULT_FROM_WRes(x) HRESULT_FROM_WIN32(x)
#else
typedef int WRes;
#define MY__FACILITY_WIN32 7
#define MY__FACILITY__WRes MY__FACILITY_WIN32
#define MY_SRes_HRESULT_FROM_WRes(x) ((HRESULT)(x) <= 0 ? ((HRESULT)(x)) : ((HRESULT) (((x) & 0x0000FFFF) | (MY__FACILITY__WRes << 16) | 0x80000000)))
#endif
#ifndef RINOK
#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
#endif
......@@ -112,48 +122,72 @@ typedef int Bool;
#define MY_NO_INLINE
#endif
#define MY_FORCE_INLINE __forceinline
#define MY_CDECL __cdecl
#define MY_FAST_CALL __fastcall
#else
#define MY_NO_INLINE
#define MY_FORCE_INLINE
#define MY_CDECL
#define MY_FAST_CALL
/* inline keyword : for C++ / C99 */
/* GCC, clang: */
/*
#if defined (__GNUC__) && (__GNUC__ >= 4)
#define MY_FORCE_INLINE __attribute__((always_inline))
#define MY_NO_INLINE __attribute__((noinline))
#endif
*/
#endif
/* The following interfaces use first parameter as pointer to structure */
typedef struct
typedef struct IByteIn IByteIn;
struct IByteIn
{
Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */
} IByteIn;
Byte (*Read)(const IByteIn *p); /* reads one byte, returns 0 in case of EOF or error */
};
#define IByteIn_Read(p) (p)->Read(p)
typedef struct
typedef struct IByteOut IByteOut;
struct IByteOut
{
void (*Write)(void *p, Byte b);
} IByteOut;
void (*Write)(const IByteOut *p, Byte b);
};
#define IByteOut_Write(p, b) (p)->Write(p, b)
typedef struct
typedef struct ISeqInStream ISeqInStream;
struct ISeqInStream
{
SRes (*Read)(void *p, void *buf, size_t *size);
SRes (*Read)(const ISeqInStream *p, void *buf, size_t *size);
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
(output(*size) < input(*size)) is allowed */
} ISeqInStream;
};
#define ISeqInStream_Read(p, buf, size) (p)->Read(p, buf, size)
/* it can return SZ_ERROR_INPUT_EOF */
SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size);
SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType);
SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf);
SRes SeqInStream_Read(const ISeqInStream *stream, void *buf, size_t size);
SRes SeqInStream_Read2(const ISeqInStream *stream, void *buf, size_t size, SRes errorType);
SRes SeqInStream_ReadByte(const ISeqInStream *stream, Byte *buf);
typedef struct
typedef struct ISeqOutStream ISeqOutStream;
struct ISeqOutStream
{
size_t (*Write)(void *p, const void *buf, size_t size);
size_t (*Write)(const ISeqOutStream *p, const void *buf, size_t size);
/* Returns: result - the number of actually written bytes.
(result < size) means error */
} ISeqOutStream;
};
#define ISeqOutStream_Write(p, buf, size) (p)->Write(p, buf, size)
typedef enum
{
......@@ -162,78 +196,162 @@ typedef enum
SZ_SEEK_END = 2
} ESzSeek;
typedef struct
typedef struct ISeekInStream ISeekInStream;
struct ISeekInStream
{
SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */
SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
} ISeekInStream;
SRes (*Read)(const ISeekInStream *p, void *buf, size_t *size); /* same as ISeqInStream::Read */
SRes (*Seek)(const ISeekInStream *p, Int64 *pos, ESzSeek origin);
};
#define ISeekInStream_Read(p, buf, size) (p)->Read(p, buf, size)
#define ISeekInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin)
typedef struct
typedef struct ILookInStream ILookInStream;
struct ILookInStream
{
SRes (*Look)(void *p, const void **buf, size_t *size);
SRes (*Look)(const ILookInStream *p, const void **buf, size_t *size);
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
(output(*size) > input(*size)) is not allowed
(output(*size) < input(*size)) is allowed */
SRes (*Skip)(void *p, size_t offset);
SRes (*Skip)(const ILookInStream *p, size_t offset);
/* offset must be <= output(*size) of Look */
SRes (*Read)(void *p, void *buf, size_t *size);
SRes (*Read)(const ILookInStream *p, void *buf, size_t *size);
/* reads directly (without buffer). It's same as ISeqInStream::Read */
SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
} ILookInStream;
SRes (*Seek)(const ILookInStream *p, Int64 *pos, ESzSeek origin);
};
#define ILookInStream_Look(p, buf, size) (p)->Look(p, buf, size)
#define ILookInStream_Skip(p, offset) (p)->Skip(p, offset)
#define ILookInStream_Read(p, buf, size) (p)->Read(p, buf, size)
#define ILookInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin)
SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size);
SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset);
SRes LookInStream_LookRead(const ILookInStream *stream, void *buf, size_t *size);
SRes LookInStream_SeekTo(const ILookInStream *stream, UInt64 offset);
/* reads via ILookInStream::Read */
SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType);
SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size);
SRes LookInStream_Read2(const ILookInStream *stream, void *buf, size_t size, SRes errorType);
SRes LookInStream_Read(const ILookInStream *stream, void *buf, size_t size);
#define LookToRead_BUF_SIZE (1 << 14)
typedef struct
{
ILookInStream s;
ISeekInStream *realStream;
ILookInStream vt;
const ISeekInStream *realStream;
size_t pos;
size_t size;
Byte buf[LookToRead_BUF_SIZE];
} CLookToRead;
size_t size; /* it's data size */
/* the following variables must be set outside */
Byte *buf;
size_t bufSize;
} CLookToRead2;
void LookToRead2_CreateVTable(CLookToRead2 *p, int lookahead);
#define LookToRead2_Init(p) { (p)->pos = (p)->size = 0; }
void LookToRead_CreateVTable(CLookToRead *p, int lookahead);
void LookToRead_Init(CLookToRead *p);
typedef struct
{
ISeqInStream s;
ILookInStream *realStream;
ISeqInStream vt;
const ILookInStream *realStream;
} CSecToLook;
void SecToLook_CreateVTable(CSecToLook *p);
typedef struct
{
ISeqInStream s;
ILookInStream *realStream;
ISeqInStream vt;
const ILookInStream *realStream;
} CSecToRead;
void SecToRead_CreateVTable(CSecToRead *p);
typedef struct
typedef struct ICompressProgress ICompressProgress;
struct ICompressProgress
{
SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize);
SRes (*Progress)(const ICompressProgress *p, UInt64 inSize, UInt64 outSize);
/* Returns: result. (result != SZ_OK) means break.
Value (UInt64)(Int64)-1 for size means unknown value. */
} ICompressProgress;
};
#define ICompressProgress_Progress(p, inSize, outSize) (p)->Progress(p, inSize, outSize)
typedef struct
typedef struct ISzAlloc ISzAlloc;
typedef const ISzAlloc * ISzAllocPtr;
struct ISzAlloc
{
void *(*Alloc)(void *p, size_t size);
void (*Free)(void *p, void *address); /* address can be 0 */
} ISzAlloc;
void *(*Alloc)(ISzAllocPtr p, size_t size);
void (*Free)(ISzAllocPtr p, void *address); /* address can be 0 */
};
#define ISzAlloc_Alloc(p, size) (p)->Alloc(p, size)
#define ISzAlloc_Free(p, a) (p)->Free(p, a)
/* deprecated */
#define IAlloc_Alloc(p, size) ISzAlloc_Alloc(p, size)
#define IAlloc_Free(p, a) ISzAlloc_Free(p, a)
#ifndef MY_offsetof
#ifdef offsetof
#define MY_offsetof(type, m) offsetof(type, m)
/*
#define MY_offsetof(type, m) FIELD_OFFSET(type, m)
*/
#else
#define MY_offsetof(type, m) ((size_t)&(((type *)0)->m))
#endif
#endif
#ifndef MY_container_of
/*
#define MY_container_of(ptr, type, m) container_of(ptr, type, m)
#define MY_container_of(ptr, type, m) CONTAINING_RECORD(ptr, type, m)
#define MY_container_of(ptr, type, m) ((type *)((char *)(ptr) - offsetof(type, m)))
#define MY_container_of(ptr, type, m) (&((type *)0)->m == (ptr), ((type *)(((char *)(ptr)) - MY_offsetof(type, m))))
*/
/*
GCC shows warning: "perhaps the 'offsetof' macro was used incorrectly"
GCC 3.4.4 : classes with constructor
GCC 4.8.1 : classes with non-public variable members"
*/
#define MY_container_of(ptr, type, m) ((type *)((char *)(1 ? (ptr) : &((type *)0)->m) - MY_offsetof(type, m)))
#endif
#define CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) ((type *)(ptr))
/*
#define CONTAINER_FROM_VTBL(ptr, type, m) CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m)
*/
#define CONTAINER_FROM_VTBL(ptr, type, m) MY_container_of(ptr, type, m)
#define CONTAINER_FROM_VTBL_CLS(ptr, type, m) CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m)
/*
#define CONTAINER_FROM_VTBL_CLS(ptr, type, m) CONTAINER_FROM_VTBL(ptr, type, m)
*/
#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
#define IAlloc_Free(p, a) (p)->Free((p), a)
#ifdef _WIN32
......
/* CpuArch.c -- CPU specific code
2012-05-29: Igor Pavlov : Public domain */
2016-02-25: Igor Pavlov : Public domain */
#include "Precomp.h"
......@@ -45,7 +45,8 @@ static UInt32 CheckFlag(UInt32 flag)
"push %%EDX\n\t"
"popf\n\t"
"andl %%EAX, %0\n\t":
"=c" (flag) : "c" (flag));
"=c" (flag) : "c" (flag) :
"%eax", "%edx");
#endif
return flag;
}
......@@ -54,7 +55,7 @@ static UInt32 CheckFlag(UInt32 flag)
#define CHECK_CPUID_IS_SUPPORTED
#endif
static void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
{
#ifdef USE_ASM
......@@ -79,7 +80,13 @@ static void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
#else
__asm__ __volatile__ (
#if defined(MY_CPU_X86) && defined(__PIC__)
#if defined(MY_CPU_AMD64) && defined(__PIC__)
"mov %%rbx, %%rdi;"
"cpuid;"
"xchg %%rbx, %%rdi;"
: "=a" (*a) ,
"=D" (*b) ,
#elif defined(MY_CPU_X86) && defined(__PIC__)
"mov %%ebx, %%edi;"
"cpuid;"
"xchgl %%ebx, %%edi;"
......@@ -116,7 +123,7 @@ Bool x86cpuid_CheckAndRead(Cx86cpuid *p)
return True;
}
static UInt32 kVendors[][3] =
static const UInt32 kVendors[][3] =
{
{ 0x756E6547, 0x49656E69, 0x6C65746E},
{ 0x68747541, 0x69746E65, 0x444D4163},
......@@ -144,18 +151,21 @@ Bool CPU_Is_InOrder()
UInt32 family, model;
if (!x86cpuid_CheckAndRead(&p))
return True;
family = x86cpuid_GetFamily(&p);
model = x86cpuid_GetModel(&p);
family = x86cpuid_GetFamily(p.ver);
model = x86cpuid_GetModel(p.ver);
firm = x86cpuid_GetFirm(&p);
switch (firm)
{
case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && (
/* Atom CPU */
model == 0x100C /* 45 nm, N4xx, D4xx, N5xx, D5xx, 230, 330 */
|| model == 0x2006 /* 45 nm, Z6xx */
|| model == 0x2007 /* 32 nm, Z2460 */
|| model == 0x3005 /* 32 nm, Z2760 */
|| model == 0x3006 /* 32 nm, N2xxx, D2xxx */
/* In-Order Atom CPU */
model == 0x1C /* 45 nm, N4xx, D4xx, N5xx, D5xx, 230, 330 */
|| model == 0x26 /* 45 nm, Z6xx */
|| model == 0x27 /* 32 nm, Z2460 */
|| model == 0x35 /* 32 nm, Z2760 */
|| model == 0x36 /* 32 nm, N2xxx, D2xxx */
)));
case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || model == 0xA)));
case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF));
......
/* CpuArch.h -- CPU specific code
2013-11-12: Igor Pavlov : Public domain */
2017-06-30 : Igor Pavlov : Public domain */
#ifndef __CPU_ARCH_H
#define __CPU_ARCH_H
......@@ -10,68 +10,207 @@ EXTERN_C_BEGIN
/*
MY_CPU_LE means that CPU is LITTLE ENDIAN.
If MY_CPU_LE is not defined, we don't know about that property of platform (it can be LITTLE ENDIAN).
MY_CPU_BE means that CPU is BIG ENDIAN.
If MY_CPU_LE and MY_CPU_BE are not defined, we don't know about ENDIANNESS of platform.
MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses.
If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of platform.
*/
#if defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__)
#if defined(_M_X64) \
|| defined(_M_AMD64) \
|| defined(__x86_64__) \
|| defined(__AMD64__) \
|| defined(__amd64__)
#define MY_CPU_AMD64
#ifdef __ILP32__
#define MY_CPU_NAME "x32"
#else
#define MY_CPU_NAME "x64"
#endif
#if defined(MY_CPU_AMD64) || defined(_M_IA64)
#define MY_CPU_64BIT
#endif
#if defined(_M_IX86) || defined(__i386__)
#if defined(_M_IX86) \
|| defined(__i386__)
#define MY_CPU_X86
#define MY_CPU_NAME "x86"
#define MY_CPU_32BIT
#endif
#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64)
#define MY_CPU_X86_OR_AMD64
#if defined(_M_ARM64) \
|| defined(__AARCH64EL__) \
|| defined(__AARCH64EB__) \
|| defined(__aarch64__)
#define MY_CPU_ARM64
#define MY_CPU_NAME "arm64"
#define MY_CPU_64BIT
#endif
#if defined(MY_CPU_X86) || defined(_M_ARM)
#if defined(_M_ARM) \
|| defined(_M_ARM_NT) \
|| defined(_M_ARMT) \
|| defined(__arm__) \
|| defined(__thumb__) \
|| defined(__ARMEL__) \
|| defined(__ARMEB__) \
|| defined(__THUMBEL__) \
|| defined(__THUMBEB__)
#define MY_CPU_ARM
#define MY_CPU_NAME "arm"
#define MY_CPU_32BIT
#endif
#if defined(_WIN32) && defined(_M_ARM)
#if defined(_M_IA64) \
|| defined(__ia64__)
#define MY_CPU_IA64
#define MY_CPU_NAME "ia64"
#define MY_CPU_64BIT
#endif
#if defined(__mips64) \
|| defined(__mips64__) \
|| (defined(__mips) && (__mips == 64 || __mips == 4 || __mips == 3))
#define MY_CPU_NAME "mips64"
#define MY_CPU_64BIT
#elif defined(__mips__)
#define MY_CPU_NAME "mips"
/* #define MY_CPU_32BIT */
#endif
#if defined(__ppc64__) \
|| defined(__powerpc64__)
#ifdef __ILP32__
#define MY_CPU_NAME "ppc64-32"
#else
#define MY_CPU_NAME "ppc64"
#endif
#define MY_CPU_64BIT
#elif defined(__ppc__) \
|| defined(__powerpc__)
#define MY_CPU_NAME "ppc"
#define MY_CPU_32BIT
#endif
#if defined(__sparc64__)
#define MY_CPU_NAME "sparc64"
#define MY_CPU_64BIT
#elif defined(__sparc__)
#define MY_CPU_NAME "sparc"
/* #define MY_CPU_32BIT */
#endif
#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64)
#define MY_CPU_X86_OR_AMD64
#endif
#ifdef _WIN32
#ifdef MY_CPU_ARM
#define MY_CPU_ARM_LE
#endif
#if defined(_WIN32) && defined(_M_IA64)
#ifdef MY_CPU_ARM64
#define MY_CPU_ARM64_LE
#endif
#ifdef _M_IA64
#define MY_CPU_IA64_LE
#endif
#if defined(MY_CPU_X86_OR_AMD64)
#define MY_CPU_LE_UNALIGN
#endif
#if defined(MY_CPU_X86_OR_AMD64) || defined(MY_CPU_ARM_LE) || defined(MY_CPU_IA64_LE) || defined(__ARMEL__) || defined(__MIPSEL__) || defined(__LITTLE_ENDIAN__)
#if defined(MY_CPU_X86_OR_AMD64) \
|| defined(MY_CPU_ARM_LE) \
|| defined(MY_CPU_ARM64_LE) \
|| defined(MY_CPU_IA64_LE) \
|| defined(__LITTLE_ENDIAN__) \
|| defined(__ARMEL__) \
|| defined(__THUMBEL__) \
|| defined(__AARCH64EL__) \
|| defined(__MIPSEL__) \
|| defined(__MIPSEL) \
|| defined(_MIPSEL) \
|| defined(__BFIN__) \
|| (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
#define MY_CPU_LE
#endif
#if defined(__BIG_ENDIAN__) || defined(__m68k__) || defined(__ARMEB__) || defined(__MIPSEB__)
#if defined(__BIG_ENDIAN__) \
|| defined(__ARMEB__) \
|| defined(__THUMBEB__) \
|| defined(__AARCH64EB__) \
|| defined(__MIPSEB__) \
|| defined(__MIPSEB) \
|| defined(_MIPSEB) \
|| defined(__m68k__) \
|| defined(__s390__) \
|| defined(__s390x__) \
|| defined(__zarch__) \
|| (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
#define MY_CPU_BE
#endif
#if defined(MY_CPU_LE) && defined(MY_CPU_BE)
Stop_Compiling_Bad_Endian
#error Stop_Compiling_Bad_Endian
#endif
#if defined(MY_CPU_32BIT) && defined(MY_CPU_64BIT)
#error Stop_Compiling_Bad_32_64_BIT
#endif
#ifndef MY_CPU_NAME
#ifdef MY_CPU_LE
#define MY_CPU_NAME "LE"
#elif defined (MY_CPU_BE)
#define MY_CPU_NAME "BE"
#else
/*
#define MY_CPU_NAME ""
*/
#endif
#endif
#ifdef MY_CPU_LE
#if defined(MY_CPU_X86_OR_AMD64) \
|| defined(MY_CPU_ARM64) \
|| defined(__ARM_FEATURE_UNALIGNED)
#define MY_CPU_LE_UNALIGN
#endif
#endif
#ifdef MY_CPU_LE_UNALIGN
#define GetUi16(p) (*(const UInt16 *)(const void *)(p))
#define GetUi32(p) (*(const UInt32 *)(const void *)(p))
#define GetUi64(p) (*(const UInt64 *)(const void *)(p))
#define SetUi16(p, d) *(UInt16 *)(p) = (d);
#define SetUi32(p, d) *(UInt32 *)(p) = (d);
#define SetUi64(p, d) *(UInt64 *)(p) = (d);
#define SetUi16(p, v) { *(UInt16 *)(p) = (v); }
#define SetUi32(p, v) { *(UInt32 *)(p) = (v); }
#define SetUi64(p, v) { *(UInt64 *)(p) = (v); }
#else
#define GetUi16(p) (((const Byte *)(p))[0] | ((UInt16)((const Byte *)(p))[1] << 8))
#define GetUi16(p) ( (UInt16) ( \
((const Byte *)(p))[0] | \
((UInt16)((const Byte *)(p))[1] << 8) ))
#define GetUi32(p) ( \
((const Byte *)(p))[0] | \
......@@ -81,31 +220,54 @@ Stop_Compiling_Bad_Endian
#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32))
#define SetUi16(p, d) { UInt32 _x_ = (d); \
((Byte *)(p))[0] = (Byte)_x_; \
((Byte *)(p))[1] = (Byte)(_x_ >> 8); }
#define SetUi16(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
_ppp_[0] = (Byte)_vvv_; \
_ppp_[1] = (Byte)(_vvv_ >> 8); }
#define SetUi32(p, d) { UInt32 _x_ = (d); \
((Byte *)(p))[0] = (Byte)_x_; \
((Byte *)(p))[1] = (Byte)(_x_ >> 8); \
((Byte *)(p))[2] = (Byte)(_x_ >> 16); \
((Byte *)(p))[3] = (Byte)(_x_ >> 24); }
#define SetUi32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
_ppp_[0] = (Byte)_vvv_; \
_ppp_[1] = (Byte)(_vvv_ >> 8); \
_ppp_[2] = (Byte)(_vvv_ >> 16); \
_ppp_[3] = (Byte)(_vvv_ >> 24); }
#define SetUi64(p, d) { UInt64 _x64_ = (d); \
SetUi32(p, (UInt32)_x64_); \
SetUi32(((Byte *)(p)) + 4, (UInt32)(_x64_ >> 32)); }
#define SetUi64(p, v) { Byte *_ppp2_ = (Byte *)(p); UInt64 _vvv2_ = (v); \
SetUi32(_ppp2_ , (UInt32)_vvv2_); \
SetUi32(_ppp2_ + 4, (UInt32)(_vvv2_ >> 32)); }
#endif
#ifdef __has_builtin
#define MY__has_builtin(x) __has_builtin(x)
#else
#define MY__has_builtin(x) 0
#endif
#if defined(MY_CPU_LE_UNALIGN) && defined(_WIN64) && (_MSC_VER >= 1300)
#if defined(MY_CPU_LE_UNALIGN) && /* defined(_WIN64) && */ (_MSC_VER >= 1300)
/* Note: we use bswap instruction, that is unsupported in 386 cpu */
#include <stdlib.h>
#pragma intrinsic(_byteswap_ushort)
#pragma intrinsic(_byteswap_ulong)
#pragma intrinsic(_byteswap_uint64)
/* #define GetBe16(p) _byteswap_ushort(*(const UInt16 *)(const Byte *)(p)) */
#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p))
#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p))
#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = _byteswap_ulong(v)
#elif defined(MY_CPU_LE_UNALIGN) && ( \
(defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) \
|| (defined(__clang__) && MY__has_builtin(__builtin_bswap16)) )
/* #define GetBe16(p) __builtin_bswap16(*(const UInt16 *)(const Byte *)(p)) */
#define GetBe32(p) __builtin_bswap32(*(const UInt32 *)(const Byte *)(p))
#define GetBe64(p) __builtin_bswap64(*(const UInt64 *)(const Byte *)(p))
#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = __builtin_bswap32(v)
#else
#define GetBe32(p) ( \
......@@ -116,9 +278,23 @@ Stop_Compiling_Bad_Endian
#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4))
#define SetBe32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
_ppp_[0] = (Byte)(_vvv_ >> 24); \
_ppp_[1] = (Byte)(_vvv_ >> 16); \
_ppp_[2] = (Byte)(_vvv_ >> 8); \
_ppp_[3] = (Byte)_vvv_; }
#endif
#ifndef GetBe16
#define GetBe16(p) ( (UInt16) ( \
((UInt16)((const Byte *)(p))[0] << 8) | \
((const Byte *)(p))[1] ))
#endif
#define GetBe16(p) ((UInt16)(((UInt16)((const Byte *)(p))[0] << 8) | ((const Byte *)(p))[1]))
#ifdef MY_CPU_X86_OR_AMD64
......@@ -140,15 +316,17 @@ enum
CPU_FIRM_VIA
};
void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d);
Bool x86cpuid_CheckAndRead(Cx86cpuid *p);
int x86cpuid_GetFirm(const Cx86cpuid *p);
#define x86cpuid_GetFamily(p) (((p)->ver >> 8) & 0xFF00F)
#define x86cpuid_GetModel(p) (((p)->ver >> 4) & 0xF00F)
#define x86cpuid_GetStepping(p) ((p)->ver & 0xF)
#define x86cpuid_GetFamily(ver) (((ver >> 16) & 0xFF0) | ((ver >> 8) & 0xF))
#define x86cpuid_GetModel(ver) (((ver >> 12) & 0xF0) | ((ver >> 4) & 0xF))
#define x86cpuid_GetStepping(ver) (ver & 0xF)
Bool CPU_Is_InOrder();
Bool CPU_Is_Aes_Supported();
Bool CPU_Is_InOrder(void);
Bool CPU_Is_Aes_Supported(void);
#endif
......
/* LzmaDec.c -- LZMA Decoder
2015-01-01 : Igor Pavlov : Public domain */
2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h"
......@@ -114,14 +114,14 @@
#define Literal (RepLenCoder + kNumLenProbs)
#define LZMA_BASE_SIZE 1846
#define LZMA_LIT_SIZE 768
#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
#define LZMA_LIT_SIZE 0x300
#if Literal != LZMA_BASE_SIZE
StopCompilingDueBUG
#endif
#define LzmaProps_GetNumProbs(p) (Literal + ((UInt32)LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
#define LZMA_DIC_MIN (1 << 12)
/* First LZMA-symbol is always decoded.
......@@ -133,8 +133,8 @@ Out:
p->remainLen:
< kMatchSpecLenStart : normal remain
= kMatchSpecLenStart : finished
= kMatchSpecLenStart + 1 : Flush marker
= kMatchSpecLenStart + 2 : State Init Marker
= kMatchSpecLenStart + 1 : Flush marker (unused now)
= kMatchSpecLenStart + 2 : State Init Marker (unused now)
*/
static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
......@@ -172,9 +172,10 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
unsigned symbol;
UPDATE_0(prob);
prob = probs + Literal;
if (checkDicSize != 0 || processedPos != 0)
prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +
if (processedPos != 0 || checkDicSize != 0)
prob += ((UInt32)LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +
(dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));
processedPos++;
if (state < kNumLitStates)
{
......@@ -195,7 +196,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
}
else
{
unsigned matchByte = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
unsigned matchByte = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)];
unsigned offs = 0x100;
state -= (state < 10) ? 3 : 6;
symbol = 1;
......@@ -222,11 +223,11 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
}
#endif
}
dic[dicPos++] = (Byte)symbol;
processedPos++;
continue;
}
else
{
UPDATE_1(prob);
prob = probs + IsRep + state;
......@@ -249,7 +250,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
IF_BIT_0(prob)
{
UPDATE_0(prob);
dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
dic[dicPos] = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)];
dicPos++;
processedPos++;
state = state < kNumLitStates ? 9 : 11;
......@@ -290,15 +291,17 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
state = state < kNumLitStates ? 8 : 11;
prob = probs + RepLenCoder;
}
#ifdef _LZMA_SIZE_OPT
{
unsigned limit, offset;
unsigned lim, offset;
CLzmaProb *probLen = prob + LenChoice;
IF_BIT_0(probLen)
{
UPDATE_0(probLen);
probLen = prob + LenLow + (posState << kLenNumLowBits);
offset = 0;
limit = (1 << kLenNumLowBits);
lim = (1 << kLenNumLowBits);
}
else
{
......@@ -309,19 +312,55 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
UPDATE_0(probLen);
probLen = prob + LenMid + (posState << kLenNumMidBits);
offset = kLenNumLowSymbols;
limit = (1 << kLenNumMidBits);
lim = (1 << kLenNumMidBits);
}
else
{
UPDATE_1(probLen);
probLen = prob + LenHigh;
offset = kLenNumLowSymbols + kLenNumMidSymbols;
limit = (1 << kLenNumHighBits);
lim = (1 << kLenNumHighBits);
}
}
TREE_DECODE(probLen, limit, len);
TREE_DECODE(probLen, lim, len);
len += offset;
}
#else
{
CLzmaProb *probLen = prob + LenChoice;
IF_BIT_0(probLen)
{
UPDATE_0(probLen);
probLen = prob + LenLow + (posState << kLenNumLowBits);
len = 1;
TREE_GET_BIT(probLen, len);
TREE_GET_BIT(probLen, len);
TREE_GET_BIT(probLen, len);
len -= 8;
}
else
{
UPDATE_1(probLen);
probLen = prob + LenChoice2;
IF_BIT_0(probLen)
{
UPDATE_0(probLen);
probLen = prob + LenMid + (posState << kLenNumMidBits);
len = 1;
TREE_GET_BIT(probLen, len);
TREE_GET_BIT(probLen, len);
TREE_GET_BIT(probLen, len);
}
else
{
UPDATE_1(probLen);
probLen = prob + LenHigh;
TREE_DECODE(probLen, (1 << kLenNumHighBits), len);
len += kLenNumLowSymbols + kLenNumMidSymbols;
}
}
}
#endif
if (state >= kNumStates)
{
......@@ -332,7 +371,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
if (distance >= kStartPosModelIndex)
{
unsigned posSlot = (unsigned)distance;
int numDirectBits = (int)(((distance >> 1) - 1));
unsigned numDirectBits = (unsigned)(((distance >> 1) - 1));
distance = (2 | (distance & 1));
if (posSlot < kEndPosModelIndex)
{
......@@ -391,6 +430,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
}
}
}
rep3 = rep2;
rep2 = rep1;
rep1 = rep0;
......@@ -398,26 +438,39 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
if (checkDicSize == 0)
{
if (distance >= processedPos)
{
p->dicPos = dicPos;
return SZ_ERROR_DATA;
}
}
else if (distance >= checkDicSize)
{
p->dicPos = dicPos;
return SZ_ERROR_DATA;
}
state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
}
len += kMatchMinLen;
if (limit == dicPos)
return SZ_ERROR_DATA;
{
SizeT rem = limit - dicPos;
unsigned curLen = ((rem < len) ? (unsigned)rem : len);
SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0);
SizeT rem;
unsigned curLen;
SizeT pos;
if ((rem = limit - dicPos) == 0)
{
p->dicPos = dicPos;
return SZ_ERROR_DATA;
}
curLen = ((rem < len) ? (unsigned)rem : len);
pos = dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0);
processedPos += curLen;
len -= curLen;
if (pos + curLen <= dicBufSize)
if (curLen <= dicBufSize - pos)
{
Byte *dest = dic + dicPos;
ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos;
......@@ -441,7 +494,9 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
}
}
while (dicPos < limit && buf < bufLimit);
NORMALIZE;
p->buf = buf;
p->range = range;
p->code = code;
......@@ -465,9 +520,10 @@ static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
SizeT dicPos = p->dicPos;
SizeT dicBufSize = p->dicBufSize;
unsigned len = p->remainLen;
UInt32 rep0 = p->reps[0];
if (limit - dicPos < len)
len = (unsigned)(limit - dicPos);
SizeT rep0 = p->reps[0]; /* we use SizeT to avoid the BUG of VC14 for AMD64 */
SizeT rem = limit - dicPos;
if (rem < len)
len = (unsigned)(rem);
if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len)
p->checkDicSize = p->prop.dicSize;
......@@ -477,7 +533,7 @@ static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
while (len != 0)
{
len--;
dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
dic[dicPos] = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)];
dicPos++;
}
p->dicPos = dicPos;
......@@ -495,17 +551,19 @@ static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte
if (limit - p->dicPos > rem)
limit2 = p->dicPos + rem;
}
RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit));
if (p->processedPos >= p->prop.dicSize)
if (p->checkDicSize == 0 && p->processedPos >= p->prop.dicSize)
p->checkDicSize = p->prop.dicSize;
LzmaDec_WriteRem(p, limit);
}
while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart);
if (p->remainLen > kMatchSpecLenStart)
{
p->remainLen = kMatchSpecLenStart;
}
return 0;
}
......@@ -522,12 +580,12 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
UInt32 range = p->range;
UInt32 code = p->code;
const Byte *bufLimit = buf + inSize;
CLzmaProb *probs = p->probs;
const CLzmaProb *probs = p->probs;
unsigned state = p->state;
ELzmaDummy res;
{
CLzmaProb *prob;
const CLzmaProb *prob;
UInt32 bound;
unsigned ttt;
unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1);
......@@ -541,7 +599,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
prob = probs + Literal;
if (p->checkDicSize != 0 || p->processedPos != 0)
prob += (LZMA_LIT_SIZE *
prob += ((UInt32)LZMA_LIT_SIZE *
((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +
(p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));
......@@ -553,13 +611,13 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
else
{
unsigned matchByte = p->dic[p->dicPos - p->reps[0] +
((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)];
(p->dicPos < p->reps[0] ? p->dicBufSize : 0)];
unsigned offs = 0x100;
unsigned symbol = 1;
do
{
unsigned bit;
CLzmaProb *probLit;
const CLzmaProb *probLit;
matchByte <<= 1;
bit = (matchByte & offs);
probLit = prob + offs + bit + symbol;
......@@ -629,7 +687,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
}
{
unsigned limit, offset;
CLzmaProb *probLen = prob + LenChoice;
const CLzmaProb *probLen = prob + LenChoice;
IF_BIT_0_CHECK(probLen)
{
UPDATE_0_CHECK;
......@@ -669,7 +727,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);
if (posSlot >= kStartPosModelIndex)
{
int numDirectBits = ((posSlot >> 1) - 1);
unsigned numDirectBits = ((posSlot >> 1) - 1);
/* if (bufLimit - buf >= 8) return DUMMY_MATCH; */
......@@ -708,14 +766,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
}
static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data)
{
p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]);
p->range = 0xFFFFFFFF;
p->needFlush = 0;
}
void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
static void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
{
p->needFlush = 1;
p->remainLen = 0;
......@@ -739,8 +790,8 @@ void LzmaDec_Init(CLzmaDec *p)
static void LzmaDec_InitStateReal(CLzmaDec *p)
{
UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp));
UInt32 i;
SizeT numProbs = LzmaProps_GetNumProbs(&p->prop);
SizeT i;
CLzmaProb *probs = p->probs;
for (i = 0; i < numProbs; i++)
probs[i] = kBitModelTotal >> 1;
......@@ -762,7 +813,7 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
{
int checkEndMarkNow;
if (p->needFlush != 0)
if (p->needFlush)
{
for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)
p->tempBuf[p->tempBufSize++] = *src++;
......@@ -773,8 +824,13 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
}
if (p->tempBuf[0] != 0)
return SZ_ERROR_DATA;
LzmaDec_InitRc(p, p->tempBuf);
p->code =
((UInt32)p->tempBuf[1] << 24)
| ((UInt32)p->tempBuf[2] << 16)
| ((UInt32)p->tempBuf[3] << 8)
| ((UInt32)p->tempBuf[4]);
p->range = 0xFFFFFFFF;
p->needFlush = 0;
p->tempBufSize = 0;
}
......@@ -858,7 +914,16 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
p->buf = p->tempBuf;
if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0)
return SZ_ERROR_DATA;
lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf));
{
unsigned kkk = (unsigned)(p->buf - p->tempBuf);
if (rem < kkk)
return SZ_ERROR_FAIL; /* some internal error */
rem -= kkk;
if (lookAhead < rem)
return SZ_ERROR_FAIL; /* some internal error */
lookAhead -= rem;
}
(*srcLen) += lookAhead;
src += lookAhead;
inSize -= lookAhead;
......@@ -910,19 +975,19 @@ SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *sr
}
}
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAllocPtr alloc)
{
alloc->Free(alloc, p->probs);
p->probs = 0;
ISzAlloc_Free(alloc, p->probs);
p->probs = NULL;
}
static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc)
static void LzmaDec_FreeDict(CLzmaDec *p, ISzAllocPtr alloc)
{
alloc->Free(alloc, p->dic);
p->dic = 0;
ISzAlloc_Free(alloc, p->dic);
p->dic = NULL;
}
void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)
void LzmaDec_Free(CLzmaDec *p, ISzAllocPtr alloc)
{
LzmaDec_FreeProbs(p, alloc);
LzmaDec_FreeDict(p, alloc);
......@@ -954,21 +1019,21 @@ SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
return SZ_OK;
}
static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc)
static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAllocPtr alloc)
{
UInt32 numProbs = LzmaProps_GetNumProbs(propNew);
if (p->probs == 0 || numProbs != p->numProbs)
if (!p->probs || numProbs != p->numProbs)
{
LzmaDec_FreeProbs(p, alloc);
p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb));
p->probs = (CLzmaProb *)ISzAlloc_Alloc(alloc, numProbs * sizeof(CLzmaProb));
p->numProbs = numProbs;
if (p->probs == 0)
if (!p->probs)
return SZ_ERROR_MEM;
}
return SZ_OK;
}
SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc)
{
CLzmaProps propNew;
RINOK(LzmaProps_Decode(&propNew, props, propsSize));
......@@ -977,18 +1042,28 @@ SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, I
return SZ_OK;
}
SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc)
{
CLzmaProps propNew;
SizeT dicBufSize;
RINOK(LzmaProps_Decode(&propNew, props, propsSize));
RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
dicBufSize = propNew.dicSize;
if (p->dic == 0 || dicBufSize != p->dicBufSize)
{
UInt32 dictSize = propNew.dicSize;
SizeT mask = ((UInt32)1 << 12) - 1;
if (dictSize >= ((UInt32)1 << 30)) mask = ((UInt32)1 << 22) - 1;
else if (dictSize >= ((UInt32)1 << 22)) mask = ((UInt32)1 << 20) - 1;;
dicBufSize = ((SizeT)dictSize + mask) & ~mask;
if (dicBufSize < dictSize)
dicBufSize = dictSize;
}
if (!p->dic || dicBufSize != p->dicBufSize)
{
LzmaDec_FreeDict(p, alloc);
p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize);
if (p->dic == 0)
p->dic = (Byte *)ISzAlloc_Alloc(alloc, dicBufSize);
if (!p->dic)
{
LzmaDec_FreeProbs(p, alloc);
return SZ_ERROR_MEM;
......@@ -1001,7 +1076,7 @@ SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAll
SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
ELzmaStatus *status, ISzAlloc *alloc)
ELzmaStatus *status, ISzAllocPtr alloc)
{
CLzmaDec p;
SRes res;
......