mirror of
https://github.com/1dot13/source.git
synced 2026-09-09 14:46:05 +02:00
- Added missing projects "VFS" & "export" to SVN
git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@4447 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
@@ -0,0 +1,30 @@
|
|||||||
|
|
||||||
|
## bfVFS version
|
||||||
|
set(BFVFS_VERSION_MAJOR @BFVFS_VERSION_MAJOR@)
|
||||||
|
set(BFVFS_VERSION_MINOR @BFVFS_VERSION_MINOR@)
|
||||||
|
set(BFVFS_VERSION_PATCH @BFVFS_VERSION_PATCH@)
|
||||||
|
|
||||||
|
set(BFVFS_VERSION_STRING "@BFVFS_VERSION_MAJOR@.@BFVFS_VERSION_MINOR@.@BFVFS_VERSION_PATCH@")
|
||||||
|
|
||||||
|
## bfVFS options
|
||||||
|
set(BFVFS_WITH_7ZIP @BFVFS_WITH_7ZIP@)
|
||||||
|
set(BFVFS_WITH_SLF @BFVFS_WITH_SLF@)
|
||||||
|
|
||||||
|
## is VFS build as a static or shared library
|
||||||
|
set(BUILD_BFVFS_SHARED @BUILD_BFVFS_SHARED@)
|
||||||
|
|
||||||
|
## definitions to add via ADD_DEFINITIONS(...)
|
||||||
|
set(BFVFS_DEFINITIONS "@BFVFS_DEFINITIONS@")
|
||||||
|
|
||||||
|
## include directories
|
||||||
|
set(BFVFS_INCLUDE_DIRS "@BFVFS_INCLUDE_DIRS@")
|
||||||
|
|
||||||
|
## library directories to include via LINK_DIRECTORIES(...)
|
||||||
|
set(BFVFS_LIBRARY_DIRS "@BFVFS_LIBRARY_DIRS@")
|
||||||
|
|
||||||
|
## libraries to include via TARGET_LINK_LIBRARIES(...)
|
||||||
|
set(BFVFS_LIBRARIES "@BFVFS_LIBRARIES@")
|
||||||
|
|
||||||
|
set(BFVFS_RUNTIME_DIRS "@BFVFS_RUNTIME_DIRS@")
|
||||||
|
|
||||||
|
set(BFVFS_FOUND ON)
|
||||||
@@ -0,0 +1,129 @@
|
|||||||
|
cmake_minimum_required(VERSION 2.6)
|
||||||
|
|
||||||
|
project(bfVFS)
|
||||||
|
|
||||||
|
set(BFVFS_VERSION_MAJOR 1)
|
||||||
|
set(BFVFS_VERSION_MINOR 0)
|
||||||
|
set(BFVFS_VERSION_PATCH 0)
|
||||||
|
|
||||||
|
##
|
||||||
|
## determine input/output directories
|
||||||
|
##
|
||||||
|
if(BFVFS_INTEGRATED_SOURCE_DIR)
|
||||||
|
set(BFVFS_SOURCE_DIR ${BFVFS_INTEGRATED_SOURCE_DIR})
|
||||||
|
else()
|
||||||
|
set(BFVFS_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(BFVFS_INTEGRATED_OUTPUT_DIR)
|
||||||
|
set(BFVFS_OUTPUT_DIR ${BFVFS_INTEGRATED_OUTPUT_DIR})
|
||||||
|
else()
|
||||||
|
set(BFVFS_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
if(BFVFS_INTEGRATED_LIBRARY_DIR)
|
||||||
|
set(BFVFS_LIBRARY_DIR ${BFVFS_INTEGRATED_LIBRARY_DIR})
|
||||||
|
else()
|
||||||
|
set(BFVFS_LIBRARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/lib)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(BFVFS_INTEGRATED_RUNTIME_DIR)
|
||||||
|
set(BFVFS_RUNTIME_DIR ${BFVFS_INTEGRATED_RUNTIME_DIR})
|
||||||
|
else()
|
||||||
|
set(BFVFS_RUNTIME_DIR ${CMAKE_CURRENT_BINARY_DIR}/bin)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(BFVFS_INCLUDE_DIR ${BFVFS_SOURCE_DIR}/include)
|
||||||
|
|
||||||
|
##
|
||||||
|
## set bfVFS "output" variables
|
||||||
|
##
|
||||||
|
set(BFVFS_INCLUDE_DIRS ${BFVFS_INCLUDE_DIR})
|
||||||
|
set(BFVFS_LIBRARY_DIRS ${BFVFS_LIBRARY_DIR})
|
||||||
|
set(BFVFS_RUNTIME_DIRS ${BFVFS_RUNTIME_DIR})
|
||||||
|
|
||||||
|
##
|
||||||
|
## Options
|
||||||
|
##
|
||||||
|
option(BUILD_BFVFS_SHARED "Build shared libraries" OFF)
|
||||||
|
option(BFVFS_WITH_SLF "Enable SLF support" ON)
|
||||||
|
option(BFVFS_WITH_7ZIP "Enable 7-zip support" ON)
|
||||||
|
|
||||||
|
if(BFVFS_WITH_7ZIP)
|
||||||
|
set(BFVFS_7ZIP_DIR ${BFVFS_SOURCE_DIR}/ext/7z)
|
||||||
|
|
||||||
|
if(BUILD_BFVFS_SHARED)
|
||||||
|
set(BUILD_BFVFS_7ZIP_SHARED ON)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
##
|
||||||
|
## set include directories for projects
|
||||||
|
##
|
||||||
|
include_directories(${BFVFS_INCLUDE_DIRS}
|
||||||
|
${BFVFS_SOURCE_DIR}/ext/utfcpp/source
|
||||||
|
)
|
||||||
|
|
||||||
|
##
|
||||||
|
## Build 7zip (if selected)
|
||||||
|
##
|
||||||
|
if(BFVFS_WITH_7ZIP)
|
||||||
|
add_subdirectory(${BFVFS_7ZIP_DIR})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
##
|
||||||
|
## Build bfVFS
|
||||||
|
##
|
||||||
|
add_subdirectory(src)
|
||||||
|
|
||||||
|
##
|
||||||
|
## set more "output" variables
|
||||||
|
##
|
||||||
|
set(BFVFS_LIBRARIES ${BFVFS_TARGET})
|
||||||
|
if(BFVFS_WITH_7ZIP)
|
||||||
|
set(BFVFS_LIBRARIES ${BFVFS_LIBRARIES} ${BFVFS_7ZIP_TARGET})
|
||||||
|
endif()
|
||||||
|
set(BFVFS_DEFINITIONS ${BFVFS_VFS_DEFINITIONS} ${BFVFS_7ZIP_DEFINITIONS})
|
||||||
|
|
||||||
|
##
|
||||||
|
## make bfVFS easier to use in other applications
|
||||||
|
##
|
||||||
|
configure_file(${BFVFS_SOURCE_DIR}/BFVFSConfig.cmake.in
|
||||||
|
${BFVFS_OUTPUT_DIR}/BFVFSConfig.cmake @ONLY IMMEDIATE)
|
||||||
|
|
||||||
|
configure_file(${BFVFS_SOURCE_DIR}/UseBFVFS.cmake.in
|
||||||
|
${BFVFS_OUTPUT_DIR}/UseBFVFS.cmake @ONLY IMMEDIATE)
|
||||||
|
|
||||||
|
##
|
||||||
|
## debug CMake
|
||||||
|
##
|
||||||
|
mark_as_advanced(BFVFS_DEBUG_CMAKE)
|
||||||
|
option(BFVFS_DEBUG_CMAKE OFF)
|
||||||
|
if(BFVFS_DEBUG_CMAKE)
|
||||||
|
message("OPTIONS :")
|
||||||
|
message(" BUILD_BFVFS_SHARED - " ${BUILD_BFVFS_SHARED})
|
||||||
|
message(" BFVFS_WITH_7ZIP - " ${BFVFS_WITH_7ZIP})
|
||||||
|
message(" BFVFS_WITH_SLF - " ${BFVFS_WITH_SLF})
|
||||||
|
|
||||||
|
message("BFVFS_DEFINITIONS :")
|
||||||
|
foreach(def ${BFVFS_DEFINITIONS})
|
||||||
|
message(" " ${def})
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
message("BFVFS_INCLUDE_DIRS :")
|
||||||
|
foreach(dir ${BFVFS_INCLUDE_DIRS})
|
||||||
|
message(" " ${dir})
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
message("BFVFS_LIBRARY_DIRS :")
|
||||||
|
foreach(dir ${BFVFS_LIBRARY_DIRS})
|
||||||
|
message(" " ${dir})
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
message("BFVFS_LIBRARIES :")
|
||||||
|
foreach(lib ${BFVFS_LIBRARIES})
|
||||||
|
message(" " ${lib})
|
||||||
|
endforeach()
|
||||||
|
endif()
|
||||||
|
|
||||||
+502
@@ -0,0 +1,502 @@
|
|||||||
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
|
Version 2.1, February 1999
|
||||||
|
|
||||||
|
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
[This is the first released version of the Lesser GPL. It also counts
|
||||||
|
as the successor of the GNU Library Public License, version 2, hence
|
||||||
|
the version number 2.1.]
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
Licenses are intended to guarantee your freedom to share and change
|
||||||
|
free software--to make sure the software is free for all its users.
|
||||||
|
|
||||||
|
This license, the Lesser General Public License, applies to some
|
||||||
|
specially designated software packages--typically libraries--of the
|
||||||
|
Free Software Foundation and other authors who decide to use it. You
|
||||||
|
can use it too, but we suggest you first think carefully about whether
|
||||||
|
this license or the ordinary General Public License is the better
|
||||||
|
strategy to use in any particular case, based on the explanations below.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom of use,
|
||||||
|
not price. Our General Public Licenses are designed to make sure that
|
||||||
|
you have the freedom to distribute copies of free software (and charge
|
||||||
|
for this service if you wish); that you receive source code or can get
|
||||||
|
it if you want it; that you can change the software and use pieces of
|
||||||
|
it in new free programs; and that you are informed that you can do
|
||||||
|
these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
distributors to deny you these rights or to ask you to surrender these
|
||||||
|
rights. These restrictions translate to certain responsibilities for
|
||||||
|
you if you distribute copies of the library or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of the library, whether gratis
|
||||||
|
or for a fee, you must give the recipients all the rights that we gave
|
||||||
|
you. You must make sure that they, too, receive or can get the source
|
||||||
|
code. If you link other code with the library, you must provide
|
||||||
|
complete object files to the recipients, so that they can relink them
|
||||||
|
with the library after making changes to the library and recompiling
|
||||||
|
it. And you must show them these terms so they know their rights.
|
||||||
|
|
||||||
|
We protect your rights with a two-step method: (1) we copyright the
|
||||||
|
library, and (2) we offer you this license, which gives you legal
|
||||||
|
permission to copy, distribute and/or modify the library.
|
||||||
|
|
||||||
|
To protect each distributor, we want to make it very clear that
|
||||||
|
there is no warranty for the free library. Also, if the library is
|
||||||
|
modified by someone else and passed on, the recipients should know
|
||||||
|
that what they have is not the original version, so that the original
|
||||||
|
author's reputation will not be affected by problems that might be
|
||||||
|
introduced by others.
|
||||||
|
|
||||||
|
Finally, software patents pose a constant threat to the existence of
|
||||||
|
any free program. We wish to make sure that a company cannot
|
||||||
|
effectively restrict the users of a free program by obtaining a
|
||||||
|
restrictive license from a patent holder. Therefore, we insist that
|
||||||
|
any patent license obtained for a version of the library must be
|
||||||
|
consistent with the full freedom of use specified in this license.
|
||||||
|
|
||||||
|
Most GNU software, including some libraries, is covered by the
|
||||||
|
ordinary GNU General Public License. This license, the GNU Lesser
|
||||||
|
General Public License, applies to certain designated libraries, and
|
||||||
|
is quite different from the ordinary General Public License. We use
|
||||||
|
this license for certain libraries in order to permit linking those
|
||||||
|
libraries into non-free programs.
|
||||||
|
|
||||||
|
When a program is linked with a library, whether statically or using
|
||||||
|
a shared library, the combination of the two is legally speaking a
|
||||||
|
combined work, a derivative of the original library. The ordinary
|
||||||
|
General Public License therefore permits such linking only if the
|
||||||
|
entire combination fits its criteria of freedom. The Lesser General
|
||||||
|
Public License permits more lax criteria for linking other code with
|
||||||
|
the library.
|
||||||
|
|
||||||
|
We call this license the "Lesser" General Public License because it
|
||||||
|
does Less to protect the user's freedom than the ordinary General
|
||||||
|
Public License. It also provides other free software developers Less
|
||||||
|
of an advantage over competing non-free programs. These disadvantages
|
||||||
|
are the reason we use the ordinary General Public License for many
|
||||||
|
libraries. However, the Lesser license provides advantages in certain
|
||||||
|
special circumstances.
|
||||||
|
|
||||||
|
For example, on rare occasions, there may be a special need to
|
||||||
|
encourage the widest possible use of a certain library, so that it becomes
|
||||||
|
a de-facto standard. To achieve this, non-free programs must be
|
||||||
|
allowed to use the library. A more frequent case is that a free
|
||||||
|
library does the same job as widely used non-free libraries. In this
|
||||||
|
case, there is little to gain by limiting the free library to free
|
||||||
|
software only, so we use the Lesser General Public License.
|
||||||
|
|
||||||
|
In other cases, permission to use a particular library in non-free
|
||||||
|
programs enables a greater number of people to use a large body of
|
||||||
|
free software. For example, permission to use the GNU C Library in
|
||||||
|
non-free programs enables many more people to use the whole GNU
|
||||||
|
operating system, as well as its variant, the GNU/Linux operating
|
||||||
|
system.
|
||||||
|
|
||||||
|
Although the Lesser General Public License is Less protective of the
|
||||||
|
users' freedom, it does ensure that the user of a program that is
|
||||||
|
linked with the Library has the freedom and the wherewithal to run
|
||||||
|
that program using a modified version of the Library.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow. Pay close attention to the difference between a
|
||||||
|
"work based on the library" and a "work that uses the library". The
|
||||||
|
former contains code derived from the library, whereas the latter must
|
||||||
|
be combined with the library in order to run.
|
||||||
|
|
||||||
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License Agreement applies to any software library or other
|
||||||
|
program which contains a notice placed by the copyright holder or
|
||||||
|
other authorized party saying it may be distributed under the terms of
|
||||||
|
this Lesser General Public License (also called "this License").
|
||||||
|
Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
A "library" means a collection of software functions and/or data
|
||||||
|
prepared so as to be conveniently linked with application programs
|
||||||
|
(which use some of those functions and data) to form executables.
|
||||||
|
|
||||||
|
The "Library", below, refers to any such software library or work
|
||||||
|
which has been distributed under these terms. A "work based on the
|
||||||
|
Library" means either the Library or any derivative work under
|
||||||
|
copyright law: that is to say, a work containing the Library or a
|
||||||
|
portion of it, either verbatim or with modifications and/or translated
|
||||||
|
straightforwardly into another language. (Hereinafter, translation is
|
||||||
|
included without limitation in the term "modification".)
|
||||||
|
|
||||||
|
"Source code" for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For a library, complete source code means
|
||||||
|
all the source code for all modules it contains, plus any associated
|
||||||
|
interface definition files, plus the scripts used to control compilation
|
||||||
|
and installation of the library.
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running a program using the Library is not restricted, and output from
|
||||||
|
such a program is covered only if its contents constitute a work based
|
||||||
|
on the Library (independent of the use of the Library in a tool for
|
||||||
|
writing it). Whether that is true depends on what the Library does
|
||||||
|
and what the program that uses the Library does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Library's
|
||||||
|
complete source code as you receive it, in any medium, provided that
|
||||||
|
you conspicuously and appropriately publish on each copy an
|
||||||
|
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||||
|
all the notices that refer to this License and to the absence of any
|
||||||
|
warranty; and distribute a copy of this License along with the
|
||||||
|
Library.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy,
|
||||||
|
and you may at your option offer warranty protection in exchange for a
|
||||||
|
fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Library or any portion
|
||||||
|
of it, thus forming a work based on the Library, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The modified work must itself be a software library.
|
||||||
|
|
||||||
|
b) You must cause the files modified to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
c) You must cause the whole of the work to be licensed at no
|
||||||
|
charge to all third parties under the terms of this License.
|
||||||
|
|
||||||
|
d) If a facility in the modified Library refers to a function or a
|
||||||
|
table of data to be supplied by an application program that uses
|
||||||
|
the facility, other than as an argument passed when the facility
|
||||||
|
is invoked, then you must make a good faith effort to ensure that,
|
||||||
|
in the event an application does not supply such function or
|
||||||
|
table, the facility still operates, and performs whatever part of
|
||||||
|
its purpose remains meaningful.
|
||||||
|
|
||||||
|
(For example, a function in a library to compute square roots has
|
||||||
|
a purpose that is entirely well-defined independent of the
|
||||||
|
application. Therefore, Subsection 2d requires that any
|
||||||
|
application-supplied function or table used by this function must
|
||||||
|
be optional: if the application does not supply it, the square
|
||||||
|
root function must still compute square roots.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Library,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Library, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote
|
||||||
|
it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Library.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Library
|
||||||
|
with the Library (or with a work based on the Library) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||||
|
License instead of this License to a given copy of the Library. To do
|
||||||
|
this, you must alter all the notices that refer to this License, so
|
||||||
|
that they refer to the ordinary GNU General Public License, version 2,
|
||||||
|
instead of to this License. (If a newer version than version 2 of the
|
||||||
|
ordinary GNU General Public License has appeared, then you can specify
|
||||||
|
that version instead if you wish.) Do not make any other change in
|
||||||
|
these notices.
|
||||||
|
|
||||||
|
Once this change is made in a given copy, it is irreversible for
|
||||||
|
that copy, so the ordinary GNU General Public License applies to all
|
||||||
|
subsequent copies and derivative works made from that copy.
|
||||||
|
|
||||||
|
This option is useful when you wish to copy part of the code of
|
||||||
|
the Library into a program that is not a library.
|
||||||
|
|
||||||
|
4. You may copy and distribute the Library (or a portion or
|
||||||
|
derivative of it, under Section 2) in object code or executable form
|
||||||
|
under the terms of Sections 1 and 2 above provided that you accompany
|
||||||
|
it with the complete corresponding machine-readable source code, which
|
||||||
|
must be distributed under the terms of Sections 1 and 2 above on a
|
||||||
|
medium customarily used for software interchange.
|
||||||
|
|
||||||
|
If distribution of object code is made by offering access to copy
|
||||||
|
from a designated place, then offering equivalent access to copy the
|
||||||
|
source code from the same place satisfies the requirement to
|
||||||
|
distribute the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
5. A program that contains no derivative of any portion of the
|
||||||
|
Library, but is designed to work with the Library by being compiled or
|
||||||
|
linked with it, is called a "work that uses the Library". Such a
|
||||||
|
work, in isolation, is not a derivative work of the Library, and
|
||||||
|
therefore falls outside the scope of this License.
|
||||||
|
|
||||||
|
However, linking a "work that uses the Library" with the Library
|
||||||
|
creates an executable that is a derivative of the Library (because it
|
||||||
|
contains portions of the Library), rather than a "work that uses the
|
||||||
|
library". The executable is therefore covered by this License.
|
||||||
|
Section 6 states terms for distribution of such executables.
|
||||||
|
|
||||||
|
When a "work that uses the Library" uses material from a header file
|
||||||
|
that is part of the Library, the object code for the work may be a
|
||||||
|
derivative work of the Library even though the source code is not.
|
||||||
|
Whether this is true is especially significant if the work can be
|
||||||
|
linked without the Library, or if the work is itself a library. The
|
||||||
|
threshold for this to be true is not precisely defined by law.
|
||||||
|
|
||||||
|
If such an object file uses only numerical parameters, data
|
||||||
|
structure layouts and accessors, and small macros and small inline
|
||||||
|
functions (ten lines or less in length), then the use of the object
|
||||||
|
file is unrestricted, regardless of whether it is legally a derivative
|
||||||
|
work. (Executables containing this object code plus portions of the
|
||||||
|
Library will still fall under Section 6.)
|
||||||
|
|
||||||
|
Otherwise, if the work is a derivative of the Library, you may
|
||||||
|
distribute the object code for the work under the terms of Section 6.
|
||||||
|
Any executables containing that work also fall under Section 6,
|
||||||
|
whether or not they are linked directly with the Library itself.
|
||||||
|
|
||||||
|
6. As an exception to the Sections above, you may also combine or
|
||||||
|
link a "work that uses the Library" with the Library to produce a
|
||||||
|
work containing portions of the Library, and distribute that work
|
||||||
|
under terms of your choice, provided that the terms permit
|
||||||
|
modification of the work for the customer's own use and reverse
|
||||||
|
engineering for debugging such modifications.
|
||||||
|
|
||||||
|
You must give prominent notice with each copy of the work that the
|
||||||
|
Library is used in it and that the Library and its use are covered by
|
||||||
|
this License. You must supply a copy of this License. If the work
|
||||||
|
during execution displays copyright notices, you must include the
|
||||||
|
copyright notice for the Library among them, as well as a reference
|
||||||
|
directing the user to the copy of this License. Also, you must do one
|
||||||
|
of these things:
|
||||||
|
|
||||||
|
a) Accompany the work with the complete corresponding
|
||||||
|
machine-readable source code for the Library including whatever
|
||||||
|
changes were used in the work (which must be distributed under
|
||||||
|
Sections 1 and 2 above); and, if the work is an executable linked
|
||||||
|
with the Library, with the complete machine-readable "work that
|
||||||
|
uses the Library", as object code and/or source code, so that the
|
||||||
|
user can modify the Library and then relink to produce a modified
|
||||||
|
executable containing the modified Library. (It is understood
|
||||||
|
that the user who changes the contents of definitions files in the
|
||||||
|
Library will not necessarily be able to recompile the application
|
||||||
|
to use the modified definitions.)
|
||||||
|
|
||||||
|
b) Use a suitable shared library mechanism for linking with the
|
||||||
|
Library. A suitable mechanism is one that (1) uses at run time a
|
||||||
|
copy of the library already present on the user's computer system,
|
||||||
|
rather than copying library functions into the executable, and (2)
|
||||||
|
will operate properly with a modified version of the library, if
|
||||||
|
the user installs one, as long as the modified version is
|
||||||
|
interface-compatible with the version that the work was made with.
|
||||||
|
|
||||||
|
c) Accompany the work with a written offer, valid for at
|
||||||
|
least three years, to give the same user the materials
|
||||||
|
specified in Subsection 6a, above, for a charge no more
|
||||||
|
than the cost of performing this distribution.
|
||||||
|
|
||||||
|
d) If distribution of the work is made by offering access to copy
|
||||||
|
from a designated place, offer equivalent access to copy the above
|
||||||
|
specified materials from the same place.
|
||||||
|
|
||||||
|
e) Verify that the user has already received a copy of these
|
||||||
|
materials or that you have already sent this user a copy.
|
||||||
|
|
||||||
|
For an executable, the required form of the "work that uses the
|
||||||
|
Library" must include any data and utility programs needed for
|
||||||
|
reproducing the executable from it. However, as a special exception,
|
||||||
|
the materials to be distributed need not include anything that is
|
||||||
|
normally distributed (in either source or binary form) with the major
|
||||||
|
components (compiler, kernel, and so on) of the operating system on
|
||||||
|
which the executable runs, unless that component itself accompanies
|
||||||
|
the executable.
|
||||||
|
|
||||||
|
It may happen that this requirement contradicts the license
|
||||||
|
restrictions of other proprietary libraries that do not normally
|
||||||
|
accompany the operating system. Such a contradiction means you cannot
|
||||||
|
use both them and the Library together in an executable that you
|
||||||
|
distribute.
|
||||||
|
|
||||||
|
7. You may place library facilities that are a work based on the
|
||||||
|
Library side-by-side in a single library together with other library
|
||||||
|
facilities not covered by this License, and distribute such a combined
|
||||||
|
library, provided that the separate distribution of the work based on
|
||||||
|
the Library and of the other library facilities is otherwise
|
||||||
|
permitted, and provided that you do these two things:
|
||||||
|
|
||||||
|
a) Accompany the combined library with a copy of the same work
|
||||||
|
based on the Library, uncombined with any other library
|
||||||
|
facilities. This must be distributed under the terms of the
|
||||||
|
Sections above.
|
||||||
|
|
||||||
|
b) Give prominent notice with the combined library of the fact
|
||||||
|
that part of it is a work based on the Library, and explaining
|
||||||
|
where to find the accompanying uncombined form of the same work.
|
||||||
|
|
||||||
|
8. You may not copy, modify, sublicense, link with, or distribute
|
||||||
|
the Library except as expressly provided under this License. Any
|
||||||
|
attempt otherwise to copy, modify, sublicense, link with, or
|
||||||
|
distribute the Library is void, and will automatically terminate your
|
||||||
|
rights under this License. However, parties who have received copies,
|
||||||
|
or rights, from you under this License will not have their licenses
|
||||||
|
terminated so long as such parties remain in full compliance.
|
||||||
|
|
||||||
|
9. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Library or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Library (or any work based on the
|
||||||
|
Library), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Library or works based on it.
|
||||||
|
|
||||||
|
10. Each time you redistribute the Library (or any work based on the
|
||||||
|
Library), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute, link with or modify the Library
|
||||||
|
subject to these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties with
|
||||||
|
this License.
|
||||||
|
|
||||||
|
11. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Library at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Library by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Library.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under any
|
||||||
|
particular circumstance, the balance of the section is intended to apply,
|
||||||
|
and the section as a whole is intended to apply in other circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
12. If the distribution and/or use of the Library is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Library under this License may add
|
||||||
|
an explicit geographical distribution limitation excluding those countries,
|
||||||
|
so that distribution is permitted only in or among countries not thus
|
||||||
|
excluded. In such case, this License incorporates the limitation as if
|
||||||
|
written in the body of this License.
|
||||||
|
|
||||||
|
13. The Free Software Foundation may publish revised and/or new
|
||||||
|
versions of the Lesser General Public License from time to time.
|
||||||
|
Such new versions will be similar in spirit to the present version,
|
||||||
|
but may differ in detail to address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Library
|
||||||
|
specifies a version number of this License which applies to it and
|
||||||
|
"any later version", you have the option of following the terms and
|
||||||
|
conditions either of that version or of any later version published by
|
||||||
|
the Free Software Foundation. If the Library does not specify a
|
||||||
|
license version number, you may choose any version ever published by
|
||||||
|
the Free Software Foundation.
|
||||||
|
|
||||||
|
14. If you wish to incorporate parts of the Library into other free
|
||||||
|
programs whose distribution conditions are incompatible with these,
|
||||||
|
write to the author to ask for permission. For software which is
|
||||||
|
copyrighted by the Free Software Foundation, write to the Free
|
||||||
|
Software Foundation; we sometimes make exceptions for this. Our
|
||||||
|
decision will be guided by the two goals of preserving the free status
|
||||||
|
of all derivatives of our free software and of promoting the sharing
|
||||||
|
and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||||
|
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||||
|
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||||
|
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||||
|
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||||
|
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||||
|
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||||
|
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||||
|
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||||
|
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||||
|
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||||
|
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||||
|
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||||
|
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||||
|
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
|
DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Libraries
|
||||||
|
|
||||||
|
If you develop a new library, and you want it to be of the greatest
|
||||||
|
possible use to the public, we recommend making it free software that
|
||||||
|
everyone can redistribute and change. You can do so by permitting
|
||||||
|
redistribution under these terms (or, alternatively, under the terms of the
|
||||||
|
ordinary General Public License).
|
||||||
|
|
||||||
|
To apply these terms, attach the following notices to the library. It is
|
||||||
|
safest to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least the
|
||||||
|
"copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the library's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||||
|
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1990
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
That's all there is to it!
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
---------------------
|
||||||
|
--- Description ---
|
||||||
|
|
||||||
|
The bfVFS library allows an application to link or mount many different
|
||||||
|
directories from the file system, thus creating a unified application-level
|
||||||
|
Virtual File System. Additionally, file archives can be used as read-only
|
||||||
|
locations in the VFS. For now only uncompressed 7-zip ans SLF archives are
|
||||||
|
supported.
|
||||||
|
|
||||||
|
The library supports multiple platforms and was tested under Windows with
|
||||||
|
MSVC 2008 and 2010, MinGW and Linux gcc.
|
||||||
|
|
||||||
|
---------------
|
||||||
|
--- Build ---
|
||||||
|
|
||||||
|
Instead of system-dependant project or makefiles, bfVFS uses the system-
|
||||||
|
independant CMake for its configuration (see www.cmake.org). To compile the
|
||||||
|
source code you can start the CMake GUI (consult the CMake documentation
|
||||||
|
for that) and choose the source and destination directories. Then, in
|
||||||
|
multiple configure runs, you can setup the build configuration and finally
|
||||||
|
generate the system dependant project or makefiles. Both in-source and
|
||||||
|
out-of-source builds are supported.
|
||||||
|
|
||||||
|
You can select the following options:
|
||||||
|
|
||||||
|
BUILD_BFVFS_SHARED - creates a DLL or a shared library when selected
|
||||||
|
|
||||||
|
BFVFS_WITH_7ZIP - enables support for 7-zip archives, also compiles
|
||||||
|
the 7z library itself (either as static or shared
|
||||||
|
library)
|
||||||
|
|
||||||
|
BFVFS_WITH_SLF - enables SLF support
|
||||||
|
|
||||||
|
** advanced options **
|
||||||
|
BFVFS_7ZIP_MT - compiles the 7-zip library with multithreading
|
||||||
|
support (Windows only)
|
||||||
|
|
||||||
|
BFVFS_DEBUG_CMAKE - prints configuration results
|
||||||
|
|
||||||
|
NOTE: Although in the configuration phase the prefix BFVFS is used, the
|
||||||
|
code itself uses the shorter VFS_ or vfs_ or vfs:: prefix/namespace.
|
||||||
|
If you can think of situations where this can lead to a conflict with
|
||||||
|
other libraries, please inform me about it.
|
||||||
|
|
||||||
|
----------------------------
|
||||||
|
--- External libraries ---
|
||||||
|
|
||||||
|
The bfVFS uses two external libraries, "utfcpp" (http://utfcpp.sourceforge.net/)
|
||||||
|
and "7-zip" (http://www.7-zip.org/).
|
||||||
|
|
||||||
|
utfcpp is used for unicode strings, as C++ does not (yet) support then
|
||||||
|
natively, and its use is mandatory.
|
||||||
|
|
||||||
|
The 7-zip library is only used for the archive format, compression is not
|
||||||
|
supported (yet). If you don't want or cannot use the 7-zip library code
|
||||||
|
you can simple deactivate it in the CMake configuration or remove it from
|
||||||
|
source tree (see ext/7z). The 7-zip library is the, slightly modified,
|
||||||
|
C-code portion from the LZMA SDK. The bfVFS library uses the 7-zip library
|
||||||
|
to read-in 7z archives. Creating uncompressed 7z archives is also suppored,
|
||||||
|
but self implemented.
|
||||||
|
|
||||||
|
As a second archive format the SLF format is supported (which probably
|
||||||
|
stands for SirTech Library Format). This is for historical reasons of the
|
||||||
|
bfVFS library.
|
||||||
|
|
||||||
|
------------------
|
||||||
|
--- Feedback ---
|
||||||
|
|
||||||
|
Contact me under john.bf.smith at googlemail.com
|
||||||
|
or go to http://sourceforge.net/projects/bfvfs/
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
INCLUDE(@BFVFS_OUTPUT_DIR@/BFVFSConfig.cmake)
|
||||||
|
|
||||||
|
ADD_DEFINITIONS(${BFVFS_DEFINITIONS})
|
||||||
|
|
||||||
|
INCLUDE_DIRECTORIES(${BFVFS_INCLUDE_DIRS})
|
||||||
|
|
||||||
|
LINK_DIRECTORIES(${BFVFS_LIBRARY_DIRS})
|
||||||
@@ -0,0 +1,673 @@
|
|||||||
|
<?xml version="1.0" encoding="Windows-1252"?>
|
||||||
|
<VisualStudioProject
|
||||||
|
ProjectType="Visual C++"
|
||||||
|
Version="8,00"
|
||||||
|
Name="7z"
|
||||||
|
ProjectGUID="{9AD14886-DB5C-4EFF-AE17-35F9BD684692}"
|
||||||
|
RootNamespace="7z"
|
||||||
|
>
|
||||||
|
<Platforms>
|
||||||
|
<Platform
|
||||||
|
Name="Win32"
|
||||||
|
/>
|
||||||
|
</Platforms>
|
||||||
|
<ToolFiles>
|
||||||
|
</ToolFiles>
|
||||||
|
<Configurations>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|Win32"
|
||||||
|
OutputDirectory="..\..\..\lib\VS2005\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="..\..\..\build\VS2005\$(ProjectName)_$(ConfigurationName)"
|
||||||
|
ConfigurationType="4"
|
||||||
|
UseOfMFC="0"
|
||||||
|
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||||
|
CharacterSet="2"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
TypeLibraryName=".\Release/7z.tlb"
|
||||||
|
HeaderFileName=""
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="2"
|
||||||
|
InlineFunctionExpansion="1"
|
||||||
|
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;SZIP_STATIC"
|
||||||
|
StringPooling="true"
|
||||||
|
RuntimeLibrary="0"
|
||||||
|
EnableFunctionLevelLinking="true"
|
||||||
|
PrecompiledHeaderFile="$(IntDir)\7z.pch"
|
||||||
|
AssemblerOutput="4"
|
||||||
|
AssemblerListingLocation="$(IntDir)\"
|
||||||
|
ObjectFile="$(IntDir)\"
|
||||||
|
ProgramDataBaseFileName="$(IntDir)\"
|
||||||
|
WarningLevel="3"
|
||||||
|
SuppressStartupBanner="true"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
PreprocessorDefinitions="NDEBUG"
|
||||||
|
Culture="1049"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLibrarianTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
SuppressStartupBanner="true"
|
||||||
|
OutputFile=".\Release/7z.bsc"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
OutputDirectory="..\..\..\lib\VS2005\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="..\..\..\build\VS2005\$(ProjectName)_$(ConfigurationName)"
|
||||||
|
ConfigurationType="4"
|
||||||
|
UseOfMFC="0"
|
||||||
|
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||||
|
CharacterSet="2"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
TypeLibraryName=".\Debug/7z.tlb"
|
||||||
|
HeaderFileName=""
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_SZ_ALLOC_DEBUG2;_SZ_NO_INT_64_A;SZIP_STATIC"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="1"
|
||||||
|
PrecompiledHeaderFile="$(IntDir)\7z.pch"
|
||||||
|
AssemblerListingLocation="$(IntDir)\"
|
||||||
|
ObjectFile="$(IntDir)\"
|
||||||
|
ProgramDataBaseFileName="$(IntDir)\"
|
||||||
|
WarningLevel="4"
|
||||||
|
SuppressStartupBanner="true"
|
||||||
|
DebugInformationFormat="4"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
PreprocessorDefinitions="_DEBUG"
|
||||||
|
Culture="1049"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLibrarianTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
SuppressStartupBanner="true"
|
||||||
|
OutputFile=".\Debug/7z.bsc"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="MapEditorD|Win32"
|
||||||
|
OutputDirectory="..\..\..\lib\VS2005\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="..\..\..\build\VS2005\$(ProjectName)_$(ConfigurationName)"
|
||||||
|
ConfigurationType="4"
|
||||||
|
UseOfMFC="0"
|
||||||
|
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||||
|
CharacterSet="2"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
TypeLibraryName=".\Debug/7z.tlb"
|
||||||
|
HeaderFileName=""
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_SZ_ALLOC_DEBUG2;_SZ_NO_INT_64_A;SZIP_STATIC"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="1"
|
||||||
|
PrecompiledHeaderFile="$(IntDir)\7z.pch"
|
||||||
|
AssemblerListingLocation="$(IntDir)\"
|
||||||
|
ObjectFile="$(IntDir)\"
|
||||||
|
ProgramDataBaseFileName="$(IntDir)\"
|
||||||
|
WarningLevel="4"
|
||||||
|
SuppressStartupBanner="true"
|
||||||
|
DebugInformationFormat="4"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
PreprocessorDefinitions="_DEBUG"
|
||||||
|
Culture="1049"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLibrarianTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
SuppressStartupBanner="true"
|
||||||
|
OutputFile=".\Debug/7z.bsc"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="MapEditor|Win32"
|
||||||
|
OutputDirectory="..\..\..\lib\VS2005\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="..\..\..\build\VS2005\$(ProjectName)_$(ConfigurationName)"
|
||||||
|
ConfigurationType="4"
|
||||||
|
UseOfMFC="0"
|
||||||
|
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||||
|
CharacterSet="2"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
TypeLibraryName=".\Release/7z.tlb"
|
||||||
|
HeaderFileName=""
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="2"
|
||||||
|
InlineFunctionExpansion="1"
|
||||||
|
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;SZIP_STATIC"
|
||||||
|
StringPooling="true"
|
||||||
|
RuntimeLibrary="0"
|
||||||
|
EnableFunctionLevelLinking="true"
|
||||||
|
PrecompiledHeaderFile="$(IntDir)\7z.pch"
|
||||||
|
AssemblerOutput="4"
|
||||||
|
AssemblerListingLocation="$(IntDir)\"
|
||||||
|
ObjectFile="$(IntDir)\"
|
||||||
|
ProgramDataBaseFileName="$(IntDir)\"
|
||||||
|
WarningLevel="3"
|
||||||
|
SuppressStartupBanner="true"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
PreprocessorDefinitions="NDEBUG"
|
||||||
|
Culture="1049"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLibrarianTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
SuppressStartupBanner="true"
|
||||||
|
OutputFile=".\Release/7z.bsc"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release_WithDebugInfo|Win32"
|
||||||
|
OutputDirectory="..\..\..\lib\VS2005\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="..\..\..\build\VS2005\$(ProjectName)_$(ConfigurationName)"
|
||||||
|
ConfigurationType="4"
|
||||||
|
UseOfMFC="0"
|
||||||
|
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||||
|
CharacterSet="2"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
TypeLibraryName=".\Release/7z.tlb"
|
||||||
|
HeaderFileName=""
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
InlineFunctionExpansion="1"
|
||||||
|
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;SZIP_STATIC"
|
||||||
|
StringPooling="true"
|
||||||
|
RuntimeLibrary="0"
|
||||||
|
EnableFunctionLevelLinking="true"
|
||||||
|
PrecompiledHeaderFile="$(IntDir)\7z.pch"
|
||||||
|
AssemblerOutput="4"
|
||||||
|
AssemblerListingLocation="$(IntDir)\"
|
||||||
|
ObjectFile="$(IntDir)\"
|
||||||
|
ProgramDataBaseFileName="$(IntDir)\"
|
||||||
|
WarningLevel="3"
|
||||||
|
SuppressStartupBanner="true"
|
||||||
|
DebugInformationFormat="0"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
PreprocessorDefinitions="NDEBUG"
|
||||||
|
Culture="1049"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLibrarianTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
SuppressStartupBanner="true"
|
||||||
|
OutputFile=".\Release/7z.bsc"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
</Configurations>
|
||||||
|
<References>
|
||||||
|
</References>
|
||||||
|
<Files>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\7z.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\7zAlloc.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\7zAlloc.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\7zBuf.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\7zBuf.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\7zBuf2.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\7zCrc.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\7zCrc.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\7zCrcOpt.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\7zDec.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\7zFile.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\7zFile.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\7zIn.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\7zStream.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\7zVersion.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Alloc.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Alloc.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Bcj2.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Bcj2.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Bra.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Bra.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Bra86.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\BraIA64.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\CpuArch.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\CpuArch.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Delta.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Delta.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\LzFind.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\LzFind.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\LzFindMt.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\LzFindMt.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\LzHash.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Lzma2Dec.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Lzma2Dec.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Lzma2Enc.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Lzma2Enc.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Lzma86.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Lzma86Dec.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Lzma86Enc.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\LzmaDec.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\LzmaDec.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\LzmaEnc.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\LzmaEnc.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\LzmaLib.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\LzmaLib.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\MtCoder.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\MtCoder.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Ppmd.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Ppmd7.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Ppmd7.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Ppmd7Dec.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Ppmd7Enc.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Ppmd8.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Ppmd8.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Ppmd8Dec.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Ppmd8Enc.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\RotateDefs.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Sha256.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Sha256.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Threads.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Threads.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Types.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Xz.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Xz.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\XzCrc64.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\XzCrc64.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\XzDec.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\XzEnc.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\XzEnc.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\XzIn.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Files>
|
||||||
|
<Globals>
|
||||||
|
</Globals>
|
||||||
|
</VisualStudioProject>
|
||||||
@@ -0,0 +1,674 @@
|
|||||||
|
<?xml version="1.0" encoding="Windows-1252"?>
|
||||||
|
<VisualStudioProject
|
||||||
|
ProjectType="Visual C++"
|
||||||
|
Version="9,00"
|
||||||
|
Name="7z"
|
||||||
|
ProjectGUID="{9AD14886-DB5C-4EFF-AE17-35F9BD684692}"
|
||||||
|
RootNamespace="7z"
|
||||||
|
TargetFrameworkVersion="0"
|
||||||
|
>
|
||||||
|
<Platforms>
|
||||||
|
<Platform
|
||||||
|
Name="Win32"
|
||||||
|
/>
|
||||||
|
</Platforms>
|
||||||
|
<ToolFiles>
|
||||||
|
</ToolFiles>
|
||||||
|
<Configurations>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|Win32"
|
||||||
|
OutputDirectory="..\..\..\lib\VS2008\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="..\..\..\build\VS2008\$(ProjectName)_$(ConfigurationName)"
|
||||||
|
ConfigurationType="4"
|
||||||
|
UseOfMFC="0"
|
||||||
|
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||||
|
CharacterSet="2"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
TypeLibraryName=".\Release/7z.tlb"
|
||||||
|
HeaderFileName=""
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="2"
|
||||||
|
InlineFunctionExpansion="1"
|
||||||
|
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;SZIP_STATIC"
|
||||||
|
StringPooling="true"
|
||||||
|
RuntimeLibrary="0"
|
||||||
|
EnableFunctionLevelLinking="true"
|
||||||
|
PrecompiledHeaderFile="$(IntDir)\7z.pch"
|
||||||
|
AssemblerOutput="4"
|
||||||
|
AssemblerListingLocation="$(IntDir)\"
|
||||||
|
ObjectFile="$(IntDir)\"
|
||||||
|
ProgramDataBaseFileName="$(IntDir)\"
|
||||||
|
WarningLevel="3"
|
||||||
|
SuppressStartupBanner="true"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
PreprocessorDefinitions="NDEBUG"
|
||||||
|
Culture="1049"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLibrarianTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
SuppressStartupBanner="true"
|
||||||
|
OutputFile=".\Release/7z.bsc"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
OutputDirectory="..\..\..\lib\VS2008\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="..\..\..\build\VS2008\$(ProjectName)_$(ConfigurationName)"
|
||||||
|
ConfigurationType="4"
|
||||||
|
UseOfMFC="0"
|
||||||
|
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||||
|
CharacterSet="2"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
TypeLibraryName=".\Debug/7z.tlb"
|
||||||
|
HeaderFileName=""
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_SZ_ALLOC_DEBUG2;_SZ_NO_INT_64_A;SZIP_STATIC"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="1"
|
||||||
|
PrecompiledHeaderFile="$(IntDir)\7z.pch"
|
||||||
|
AssemblerListingLocation="$(IntDir)\"
|
||||||
|
ObjectFile="$(IntDir)\"
|
||||||
|
ProgramDataBaseFileName="$(IntDir)\"
|
||||||
|
WarningLevel="4"
|
||||||
|
SuppressStartupBanner="true"
|
||||||
|
DebugInformationFormat="4"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
PreprocessorDefinitions="_DEBUG"
|
||||||
|
Culture="1049"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLibrarianTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
SuppressStartupBanner="true"
|
||||||
|
OutputFile=".\Debug/7z.bsc"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="MapEditorD|Win32"
|
||||||
|
OutputDirectory="..\..\..\lib\VS2008\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="..\..\..\build\VS2008\$(ProjectName)_$(ConfigurationName)"
|
||||||
|
ConfigurationType="4"
|
||||||
|
UseOfMFC="0"
|
||||||
|
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||||
|
CharacterSet="2"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
TypeLibraryName=".\Debug/7z.tlb"
|
||||||
|
HeaderFileName=""
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_SZ_ALLOC_DEBUG2;_SZ_NO_INT_64_A;SZIP_STATIC"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="1"
|
||||||
|
PrecompiledHeaderFile="$(IntDir)\7z.pch"
|
||||||
|
AssemblerListingLocation="$(IntDir)\"
|
||||||
|
ObjectFile="$(IntDir)\"
|
||||||
|
ProgramDataBaseFileName="$(IntDir)\"
|
||||||
|
WarningLevel="4"
|
||||||
|
SuppressStartupBanner="true"
|
||||||
|
DebugInformationFormat="4"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
PreprocessorDefinitions="_DEBUG"
|
||||||
|
Culture="1049"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLibrarianTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
SuppressStartupBanner="true"
|
||||||
|
OutputFile=".\Debug/7z.bsc"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="MapEditor|Win32"
|
||||||
|
OutputDirectory="..\..\..\lib\VS2008\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="..\..\..\build\VS2008\$(ProjectName)_$(ConfigurationName)"
|
||||||
|
ConfigurationType="4"
|
||||||
|
UseOfMFC="0"
|
||||||
|
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||||
|
CharacterSet="2"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
TypeLibraryName=".\Release/7z.tlb"
|
||||||
|
HeaderFileName=""
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="2"
|
||||||
|
InlineFunctionExpansion="1"
|
||||||
|
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;SZIP_STATIC"
|
||||||
|
StringPooling="true"
|
||||||
|
RuntimeLibrary="0"
|
||||||
|
EnableFunctionLevelLinking="true"
|
||||||
|
PrecompiledHeaderFile="$(IntDir)\7z.pch"
|
||||||
|
AssemblerOutput="4"
|
||||||
|
AssemblerListingLocation="$(IntDir)\"
|
||||||
|
ObjectFile="$(IntDir)\"
|
||||||
|
ProgramDataBaseFileName="$(IntDir)\"
|
||||||
|
WarningLevel="3"
|
||||||
|
SuppressStartupBanner="true"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
PreprocessorDefinitions="NDEBUG"
|
||||||
|
Culture="1049"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLibrarianTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
SuppressStartupBanner="true"
|
||||||
|
OutputFile=".\Release/7z.bsc"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release_WithDebugInfo|Win32"
|
||||||
|
OutputDirectory="..\..\..\lib\VS2008\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="..\..\..\build\VS2008\$(ProjectName)_$(ConfigurationName)"
|
||||||
|
ConfigurationType="4"
|
||||||
|
UseOfMFC="0"
|
||||||
|
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||||
|
CharacterSet="2"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
TypeLibraryName=".\Release/7z.tlb"
|
||||||
|
HeaderFileName=""
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
InlineFunctionExpansion="0"
|
||||||
|
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;SZIP_STATIC"
|
||||||
|
StringPooling="true"
|
||||||
|
RuntimeLibrary="0"
|
||||||
|
EnableFunctionLevelLinking="true"
|
||||||
|
PrecompiledHeaderFile="$(IntDir)\7z.pch"
|
||||||
|
AssemblerOutput="4"
|
||||||
|
AssemblerListingLocation="$(IntDir)\"
|
||||||
|
ObjectFile="$(IntDir)\"
|
||||||
|
ProgramDataBaseFileName="$(IntDir)\"
|
||||||
|
WarningLevel="3"
|
||||||
|
SuppressStartupBanner="true"
|
||||||
|
DebugInformationFormat="4"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
PreprocessorDefinitions="NDEBUG"
|
||||||
|
Culture="1049"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLibrarianTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
SuppressStartupBanner="true"
|
||||||
|
OutputFile=".\Release/7z.bsc"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
</Configurations>
|
||||||
|
<References>
|
||||||
|
</References>
|
||||||
|
<Files>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\7z.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\7zAlloc.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\7zAlloc.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\7zBuf.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\7zBuf.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\7zBuf2.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\7zCrc.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\7zCrc.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\7zCrcOpt.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\7zDec.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\7zFile.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\7zFile.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\7zIn.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\7zStream.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\7zVersion.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Alloc.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Alloc.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Bcj2.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Bcj2.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Bra.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Bra.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Bra86.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\BraIA64.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\CpuArch.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\CpuArch.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Delta.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Delta.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\LzFind.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\LzFind.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\LzFindMt.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\LzFindMt.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\LzHash.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Lzma2Dec.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Lzma2Dec.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Lzma2Enc.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Lzma2Enc.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Lzma86.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Lzma86Dec.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Lzma86Enc.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\LzmaDec.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\LzmaDec.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\LzmaEnc.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\LzmaEnc.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\LzmaLib.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\LzmaLib.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\MtCoder.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\MtCoder.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Ppmd.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Ppmd7.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Ppmd7.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Ppmd7Dec.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Ppmd7Enc.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Ppmd8.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Ppmd8.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Ppmd8Dec.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Ppmd8Enc.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\RotateDefs.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Sha256.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Sha256.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Threads.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Threads.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Types.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Xz.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\Xz.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\XzCrc64.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\XzCrc64.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\XzDec.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\XzEnc.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\XzEnc.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\ext\7z\src\XzIn.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Files>
|
||||||
|
<Globals>
|
||||||
|
</Globals>
|
||||||
|
</VisualStudioProject>
|
||||||
@@ -0,0 +1,278 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="MapEditorD|Win32">
|
||||||
|
<Configuration>MapEditorD</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="MapEditor|Win32">
|
||||||
|
<Configuration>MapEditor</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Relese_WithDebugInfo|Win32">
|
||||||
|
<Configuration>Relese_WithDebugInfo</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\ext\7z\src\7z.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\7zAlloc.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\7zBuf.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\7zCrc.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\7zFile.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\7zVersion.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\Alloc.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\Bcj2.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\Bra.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\CpuArch.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\Delta.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\LzFind.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\LzFindMt.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\LzHash.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\Lzma2Dec.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\Lzma2Enc.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\Lzma86.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\LzmaDec.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\LzmaEnc.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\LzmaLib.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\MtCoder.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\Ppmd.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\Ppmd7.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\Ppmd8.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\RotateDefs.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\Sha256.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\Threads.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\Types.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\Xz.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\XzCrc64.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\XzEnc.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\ext\7z\src\7zAlloc.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\7zBuf.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\7zBuf2.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\7zCrc.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\7zCrcOpt.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\7zDec.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\7zFile.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\7zIn.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\7zStream.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\Alloc.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\Bcj2.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\Bra.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\Bra86.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\BraIA64.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\CpuArch.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\Delta.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\LzFind.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\LzFindMt.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\Lzma2Dec.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\Lzma2Enc.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\Lzma86Dec.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\Lzma86Enc.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\LzmaDec.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\LzmaEnc.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\LzmaLib.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\MtCoder.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\Ppmd7.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\Ppmd7Dec.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\Ppmd7Enc.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\Ppmd8.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\Ppmd8Dec.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\Ppmd8Enc.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\Sha256.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\Threads.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\Xz.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\XzCrc64.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\XzDec.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\XzEnc.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\XzIn.c" />
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>{3B7B950D-0DC8-4ADD-9FE2-7DE4297C62F6}</ProjectGuid>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<RootNamespace>My7z</RootNamespace>
|
||||||
|
<ProjectName>7z</ProjectName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<CharacterSet>NotSet</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='MapEditorD|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<CharacterSet>NotSet</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||||
|
<CharacterSet>NotSet</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='MapEditor|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||||
|
<CharacterSet>NotSet</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Relese_WithDebugInfo|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||||
|
<CharacterSet>NotSet</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='MapEditorD|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='MapEditor|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Relese_WithDebugInfo|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<OutDir>..\..\..\lib\VS2010\$(Configuration)\</OutDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='MapEditorD|Win32'">
|
||||||
|
<OutDir>..\..\..\lib\VS2010\$(Configuration)\</OutDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<IntDir>..\..\..\build\VS2010\$(ProjectName)_$(Configuration)\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='MapEditorD|Win32'">
|
||||||
|
<IntDir>..\..\..\build\VS2010\$(ProjectName)_$(Configuration)\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<OutDir>..\..\..\lib\VS2010\$(Configuration)\</OutDir>
|
||||||
|
<IntDir>..\..\..\build\VS2010\$(ProjectName)_$(Configuration)\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='MapEditor|Win32'">
|
||||||
|
<OutDir>..\..\..\lib\VS2010\$(Configuration)\</OutDir>
|
||||||
|
<IntDir>..\..\..\build\VS2010\$(ProjectName)_$(Configuration)\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Relese_WithDebugInfo|Win32'">
|
||||||
|
<OutDir>..\..\..\lib\VS2010\$(Configuration)\</OutDir>
|
||||||
|
<IntDir>..\..\..\build\VS2010\$(ProjectName)_$(Configuration)\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;SZIP_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||||
|
<PrecompiledHeaderFile>
|
||||||
|
</PrecompiledHeaderFile>
|
||||||
|
<PrecompiledHeaderOutputFile>
|
||||||
|
</PrecompiledHeaderOutputFile>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='MapEditorD|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;SZIP_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||||
|
<PrecompiledHeaderFile>
|
||||||
|
</PrecompiledHeaderFile>
|
||||||
|
<PrecompiledHeaderOutputFile>
|
||||||
|
</PrecompiledHeaderOutputFile>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;SZIP_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
<PrecompiledHeaderFile>
|
||||||
|
</PrecompiledHeaderFile>
|
||||||
|
<PrecompiledHeaderOutputFile>
|
||||||
|
</PrecompiledHeaderOutputFile>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='MapEditor|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;SZIP_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
<PrecompiledHeaderFile>
|
||||||
|
</PrecompiledHeaderFile>
|
||||||
|
<PrecompiledHeaderOutputFile>
|
||||||
|
</PrecompiledHeaderOutputFile>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Relese_WithDebugInfo|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;SZIP_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
<PrecompiledHeaderFile>
|
||||||
|
</PrecompiledHeaderFile>
|
||||||
|
<PrecompiledHeaderOutputFile>
|
||||||
|
</PrecompiledHeaderOutputFile>
|
||||||
|
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\ext\7z\src\7z.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\7zAlloc.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\7zBuf.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\7zCrc.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\7zFile.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\7zVersion.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\Alloc.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\Bcj2.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\Bra.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\CpuArch.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\Delta.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\LzFind.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\LzFindMt.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\LzHash.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\Lzma2Dec.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\Lzma2Enc.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\Lzma86.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\LzmaDec.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\LzmaEnc.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\LzmaLib.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\MtCoder.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\Ppmd.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\Ppmd7.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\Ppmd8.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\RotateDefs.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\Sha256.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\Threads.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\Types.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\Xz.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\XzCrc64.h" />
|
||||||
|
<ClInclude Include="..\ext\7z\src\XzEnc.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\ext\7z\src\7zAlloc.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\7zBuf.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\7zBuf2.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\7zCrc.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\7zCrcOpt.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\7zDec.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\7zFile.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\7zIn.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\7zStream.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\Alloc.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\Bcj2.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\Bra.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\Bra86.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\BraIA64.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\CpuArch.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\Delta.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\LzFind.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\LzFindMt.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\Lzma2Dec.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\Lzma2Enc.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\Lzma86Dec.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\Lzma86Enc.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\LzmaDec.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\LzmaEnc.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\LzmaLib.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\MtCoder.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\Ppmd7.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\Ppmd7Dec.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\Ppmd7Enc.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\Ppmd8.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\Ppmd8Dec.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\Ppmd8Enc.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\Sha256.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\Threads.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\Xz.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\XzCrc64.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\XzDec.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\XzEnc.c" />
|
||||||
|
<ClCompile Include="..\ext\7z\src\XzIn.c" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,656 @@
|
|||||||
|
<?xml version="1.0" encoding="Windows-1252"?>
|
||||||
|
<VisualStudioProject
|
||||||
|
ProjectType="Visual C++"
|
||||||
|
Version="8,00"
|
||||||
|
Name="VFS"
|
||||||
|
ProjectGUID="{C63466D6-49B5-4C54-AA0D-864F6171FD9B}"
|
||||||
|
RootNamespace="VFS"
|
||||||
|
Keyword="Win32Proj"
|
||||||
|
>
|
||||||
|
<Platforms>
|
||||||
|
<Platform
|
||||||
|
Name="Win32"
|
||||||
|
/>
|
||||||
|
</Platforms>
|
||||||
|
<ToolFiles>
|
||||||
|
</ToolFiles>
|
||||||
|
<Configurations>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
OutputDirectory="..\..\..\lib\VS2005\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="..\..\..\build\VS2005\$(ProjectName)_$(ConfigurationName)"
|
||||||
|
ConfigurationType="4"
|
||||||
|
CharacterSet="0"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories="..\include;..\ext\7z\src;..\ext\utfcpp\source"
|
||||||
|
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;SZIP_STATIC;VFS_STATIC;VFS_WITH_SLF;VFS_WITH_7ZIP"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="1"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
DebugInformationFormat="4"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLibrarianTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|Win32"
|
||||||
|
OutputDirectory="..\..\..\lib\VS2005\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="..\..\..\build\VS2005\$(ProjectName)_$(ConfigurationName)"
|
||||||
|
ConfigurationType="4"
|
||||||
|
CharacterSet="0"
|
||||||
|
WholeProgramOptimization="0"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="2"
|
||||||
|
EnableIntrinsicFunctions="true"
|
||||||
|
AdditionalIncludeDirectories="..\include;..\ext\7z\src;..\ext\utfcpp\source"
|
||||||
|
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;SZIP_STATIC;VFS_STATIC;VFS_WITH_SLF;VFS_WITH_7ZIP"
|
||||||
|
StringPooling="true"
|
||||||
|
RuntimeLibrary="0"
|
||||||
|
EnableFunctionLevelLinking="false"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
SuppressStartupBanner="true"
|
||||||
|
DebugInformationFormat="0"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLibrarianTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="MapEditorD|Win32"
|
||||||
|
OutputDirectory="..\..\..\lib\VS2005\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="..\..\..\build\VS2005\$(ProjectName)_$(ConfigurationName)"
|
||||||
|
ConfigurationType="4"
|
||||||
|
CharacterSet="0"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories="..\include;..\ext\7z\src;..\ext\utfcpp\source"
|
||||||
|
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;SZIP_STATIC;VFS_STATIC;VFS_WITH_SLF;VFS_WITH_7ZIP"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="1"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
DebugInformationFormat="4"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLibrarianTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="MapEditor|Win32"
|
||||||
|
OutputDirectory="..\..\..\lib\VS2005\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="..\..\..\build\VS2005\$(ProjectName)_$(ConfigurationName)"
|
||||||
|
ConfigurationType="4"
|
||||||
|
CharacterSet="0"
|
||||||
|
WholeProgramOptimization="0"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="2"
|
||||||
|
EnableIntrinsicFunctions="true"
|
||||||
|
AdditionalIncludeDirectories="..\include;..\ext\7z\src;..\ext\utfcpp\source"
|
||||||
|
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;SZIP_STATIC;VFS_STATIC;VFS_WITH_SLF;VFS_WITH_7ZIP"
|
||||||
|
StringPooling="true"
|
||||||
|
RuntimeLibrary="0"
|
||||||
|
EnableFunctionLevelLinking="false"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
SuppressStartupBanner="true"
|
||||||
|
DebugInformationFormat="0"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLibrarianTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release_WithDebugInfo|Win32"
|
||||||
|
OutputDirectory="..\..\..\lib\VS2005\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="..\..\..\build\VS2005\$(ProjectName)_$(ConfigurationName)"
|
||||||
|
ConfigurationType="4"
|
||||||
|
CharacterSet="0"
|
||||||
|
WholeProgramOptimization="0"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
EnableIntrinsicFunctions="true"
|
||||||
|
AdditionalIncludeDirectories="..\include;..\ext\7z\src;..\ext\utfcpp\source"
|
||||||
|
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;SZIP_STATIC;VFS_STATIC;VFS_SYNCHRONIZE;VFS_WITH_SLF;VFS_WITH_7ZIP"
|
||||||
|
StringPooling="true"
|
||||||
|
RuntimeLibrary="0"
|
||||||
|
EnableFunctionLevelLinking="false"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
SuppressStartupBanner="true"
|
||||||
|
DebugInformationFormat="4"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLibrarianTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
</Configurations>
|
||||||
|
<References>
|
||||||
|
</References>
|
||||||
|
<Files>
|
||||||
|
<Filter
|
||||||
|
Name="Aspects"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Aspects\vfs_logging.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Aspects\vfs_logging.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Aspects\vfs_settings.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Aspects\vfs_settings.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Aspects\vfs_synchronization.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Aspects\vfs_synchronization.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Core"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Core\vfs.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Core\vfs.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Core\vfs_debug.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Core\vfs_debug.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Core\vfs_file_raii.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Core\vfs_file_raii.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Core\vfs_init.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Core\vfs_init.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Core\vfs_os_functions.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Core\vfs_os_functions.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Core\vfs_path.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Core\vfs_path.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Core\vfs_profile.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Core\vfs_profile.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Core\vfs_string.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Core\vfs_string.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Core\vfs_types.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Core\vfs_types.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Core\vfs_vfile.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Core\vfs_vfile.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Core\vfs_vloc.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Core\vfs_vloc.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<Filter
|
||||||
|
Name="File"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Core\File\vfs_buffer_file.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Core\File\vfs_buffer_file.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Core\File\vfs_dir_file.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Core\File\vfs_dir_file.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Core\File\vfs_file.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Core\File\vfs_file.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Core\File\vfs_lib_file.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Core\File\vfs_lib_file.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Interface"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Core\Interface\vfs_directory_interface.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Core\Interface\vfs_file_interface.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Core\Interface\vfs_interface_members.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Core\Interface\vfs_iterator_interface.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Core\Interface\vfs_library_interface.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Core\Interface\vfs_location_interface.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Location"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Core\Location\vfs_directory_tree.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Core\Location\vfs_directory_tree.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Core\Location\vfs_lib_dir.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Core\Location\vfs_lib_dir.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Core\Location\vfs_uncompressed_lib_base.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Core\Location\vfs_uncompressed_lib_base.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Ext"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Ext\7z\vfs_7z_library.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Ext\7z\vfs_7z_library.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Ext\7z\vfs_create_7z_library.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Ext\7z\vfs_create_7z_library.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Ext\slf\vfs_slf_library.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Ext\slf\vfs_slf_library.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Tools"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Tools\vfs_allocator.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Tools\vfs_allocator.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Tools\vfs_file_logger.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Tools\vfs_file_logger.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Tools\vfs_hp_timer.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Tools\vfs_hp_timer.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Tools\vfs_log.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Tools\vfs_log.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Tools\vfs_parser_tools.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Tools\vfs_parser_tools.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Tools\vfs_profiler.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Tools\vfs_profiler.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Tools\vfs_property_container.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Tools\vfs_property_container.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Tools\vfs_tools.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Tools\vfs_tools.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\vfs_config.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Files>
|
||||||
|
<Globals>
|
||||||
|
</Globals>
|
||||||
|
</VisualStudioProject>
|
||||||
@@ -0,0 +1,657 @@
|
|||||||
|
<?xml version="1.0" encoding="Windows-1252"?>
|
||||||
|
<VisualStudioProject
|
||||||
|
ProjectType="Visual C++"
|
||||||
|
Version="9,00"
|
||||||
|
Name="VFS"
|
||||||
|
ProjectGUID="{C63466D6-49B5-4C54-AA0D-864F6171FD9B}"
|
||||||
|
RootNamespace="VFS"
|
||||||
|
Keyword="Win32Proj"
|
||||||
|
TargetFrameworkVersion="196613"
|
||||||
|
>
|
||||||
|
<Platforms>
|
||||||
|
<Platform
|
||||||
|
Name="Win32"
|
||||||
|
/>
|
||||||
|
</Platforms>
|
||||||
|
<ToolFiles>
|
||||||
|
</ToolFiles>
|
||||||
|
<Configurations>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
OutputDirectory="..\..\..\lib\VS2008\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="..\..\..\build\VS2008\$(ProjectName)_$(ConfigurationName)"
|
||||||
|
ConfigurationType="4"
|
||||||
|
CharacterSet="0"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories="..\include;..\ext\7z\src;..\ext\utfcpp\source"
|
||||||
|
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;SZIP_STATIC;VFS_STATIC;VFS_WITH_SLF;VFS_WITH_7ZIP"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="1"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
DebugInformationFormat="4"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLibrarianTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|Win32"
|
||||||
|
OutputDirectory="..\..\..\lib\VS2008\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="..\..\..\build\VS2008\$(ProjectName)_$(ConfigurationName)"
|
||||||
|
ConfigurationType="4"
|
||||||
|
CharacterSet="0"
|
||||||
|
WholeProgramOptimization="0"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="2"
|
||||||
|
EnableIntrinsicFunctions="true"
|
||||||
|
AdditionalIncludeDirectories="..\include;..\ext\7z\src;..\ext\utfcpp\source"
|
||||||
|
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;SZIP_STATIC;VFS_STATIC;VFS_WITH_SLF;VFS_WITH_7ZIP"
|
||||||
|
StringPooling="true"
|
||||||
|
RuntimeLibrary="0"
|
||||||
|
EnableFunctionLevelLinking="false"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
SuppressStartupBanner="true"
|
||||||
|
DebugInformationFormat="0"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLibrarianTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="MapEditorD|Win32"
|
||||||
|
OutputDirectory="..\..\..\lib\VS2008\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="..\..\..\build\VS2008\$(ProjectName)_$(ConfigurationName)"
|
||||||
|
ConfigurationType="4"
|
||||||
|
CharacterSet="0"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories="..\include;..\ext\7z\src;..\ext\utfcpp\source"
|
||||||
|
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;SZIP_STATIC;VFS_STATIC;VFS_WITH_SLF;VFS_WITH_7ZIP"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="1"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
DebugInformationFormat="4"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLibrarianTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="MapEditor|Win32"
|
||||||
|
OutputDirectory="..\..\..\lib\VS2008\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="..\..\..\build\VS2008\$(ProjectName)_$(ConfigurationName)"
|
||||||
|
ConfigurationType="4"
|
||||||
|
CharacterSet="0"
|
||||||
|
WholeProgramOptimization="0"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="2"
|
||||||
|
EnableIntrinsicFunctions="true"
|
||||||
|
AdditionalIncludeDirectories="..\include;..\ext\7z\src;..\ext\utfcpp\source"
|
||||||
|
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;SZIP_STATIC;VFS_STATIC;VFS_WITH_SLF;VFS_WITH_7ZIP"
|
||||||
|
StringPooling="true"
|
||||||
|
RuntimeLibrary="0"
|
||||||
|
EnableFunctionLevelLinking="false"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
SuppressStartupBanner="true"
|
||||||
|
DebugInformationFormat="0"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLibrarianTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release_WithDebugInfo|Win32"
|
||||||
|
OutputDirectory="..\..\..\lib\VS2008\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="..\..\..\build\VS2008\$(ProjectName)_$(ConfigurationName)"
|
||||||
|
ConfigurationType="4"
|
||||||
|
CharacterSet="0"
|
||||||
|
WholeProgramOptimization="0"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
EnableIntrinsicFunctions="true"
|
||||||
|
AdditionalIncludeDirectories="..\include;..\ext\7z\src;..\ext\utfcpp\source"
|
||||||
|
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;SZIP_STATIC;VFS_STATIC;VFS_SYNCHRONIZE;VFS_WITH_SLF;VFS_WITH_7ZIP"
|
||||||
|
StringPooling="true"
|
||||||
|
RuntimeLibrary="0"
|
||||||
|
EnableFunctionLevelLinking="false"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
SuppressStartupBanner="true"
|
||||||
|
DebugInformationFormat="4"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLibrarianTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
</Configurations>
|
||||||
|
<References>
|
||||||
|
</References>
|
||||||
|
<Files>
|
||||||
|
<Filter
|
||||||
|
Name="Aspects"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Aspects\vfs_logging.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Aspects\vfs_logging.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Aspects\vfs_settings.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Aspects\vfs_settings.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Aspects\vfs_synchronization.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Aspects\vfs_synchronization.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Core"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Core\vfs.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Core\vfs.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Core\vfs_debug.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Core\vfs_debug.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Core\vfs_file_raii.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Core\vfs_file_raii.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Core\vfs_init.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Core\vfs_init.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Core\vfs_os_functions.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Core\vfs_os_functions.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Core\vfs_path.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Core\vfs_path.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Core\vfs_profile.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Core\vfs_profile.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Core\vfs_string.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Core\vfs_string.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Core\vfs_types.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Core\vfs_types.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Core\vfs_vfile.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Core\vfs_vfile.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Core\vfs_vloc.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Core\vfs_vloc.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<Filter
|
||||||
|
Name="File"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Core\File\vfs_buffer_file.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Core\File\vfs_buffer_file.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Core\File\vfs_dir_file.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Core\File\vfs_dir_file.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Core\File\vfs_file.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Core\File\vfs_file.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Core\File\vfs_lib_file.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Core\File\vfs_lib_file.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Interface"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Core\Interface\vfs_directory_interface.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Core\Interface\vfs_file_interface.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Core\Interface\vfs_interface_members.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Core\Interface\vfs_iterator_interface.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Core\Interface\vfs_library_interface.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Core\Interface\vfs_location_interface.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Location"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Core\Location\vfs_directory_tree.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Core\Location\vfs_directory_tree.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Core\Location\vfs_lib_dir.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Core\Location\vfs_lib_dir.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Core\Location\vfs_uncompressed_lib_base.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Core\Location\vfs_uncompressed_lib_base.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Ext"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Ext\7z\vfs_7z_library.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Ext\7z\vfs_7z_library.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Ext\7z\vfs_create_7z_library.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Ext\7z\vfs_create_7z_library.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Ext\slf\vfs_slf_library.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Ext\slf\vfs_slf_library.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Tools"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Tools\vfs_allocator.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Tools\vfs_allocator.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Tools\vfs_file_logger.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Tools\vfs_file_logger.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Tools\vfs_hp_timer.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Tools\vfs_hp_timer.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Tools\vfs_log.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Tools\vfs_log.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Tools\vfs_parser_tools.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Tools\vfs_parser_tools.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Tools\vfs_profiler.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Tools\vfs_profiler.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Tools\vfs_property_container.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Tools\vfs_property_container.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\Tools\vfs_tools.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\Tools\vfs_tools.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<File
|
||||||
|
RelativePath="..\include\vfs\vfs_config.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Files>
|
||||||
|
<Globals>
|
||||||
|
</Globals>
|
||||||
|
</VisualStudioProject>
|
||||||
@@ -0,0 +1,284 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="MapEditorD|Win32">
|
||||||
|
<Configuration>MapEditorD</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="MapEditor|Win32">
|
||||||
|
<Configuration>MapEditor</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Relese_WithDebugInfo|Win32">
|
||||||
|
<Configuration>Relese_WithDebugInfo</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\include\vfs\Aspects\vfs_logging.h" />
|
||||||
|
<ClInclude Include="..\include\vfs\Aspects\vfs_settings.h" />
|
||||||
|
<ClInclude Include="..\include\vfs\Aspects\vfs_synchronization.h" />
|
||||||
|
<ClInclude Include="..\include\vfs\Core\File\vfs_buffer_file.h" />
|
||||||
|
<ClInclude Include="..\include\vfs\Core\File\vfs_dir_file.h" />
|
||||||
|
<ClInclude Include="..\include\vfs\Core\File\vfs_file.h" />
|
||||||
|
<ClInclude Include="..\include\vfs\Core\File\vfs_lib_file.h" />
|
||||||
|
<ClInclude Include="..\include\vfs\Core\Interface\vfs_directory_interface.h" />
|
||||||
|
<ClInclude Include="..\include\vfs\Core\Interface\vfs_file_interface.h" />
|
||||||
|
<ClInclude Include="..\include\vfs\Core\Interface\vfs_iterator_interface.h" />
|
||||||
|
<ClInclude Include="..\include\vfs\Core\Interface\vfs_library_interface.h" />
|
||||||
|
<ClInclude Include="..\include\vfs\Core\Interface\vfs_location_interface.h" />
|
||||||
|
<ClInclude Include="..\include\vfs\Core\Location\vfs_directory_tree.h" />
|
||||||
|
<ClInclude Include="..\include\vfs\Core\Location\vfs_lib_dir.h" />
|
||||||
|
<ClInclude Include="..\include\vfs\Core\Location\vfs_uncompressed_lib_base.h" />
|
||||||
|
<ClInclude Include="..\include\vfs\Core\vfs.h" />
|
||||||
|
<ClInclude Include="..\include\vfs\Core\vfs_debug.h" />
|
||||||
|
<ClInclude Include="..\include\vfs\Core\vfs_file_raii.h" />
|
||||||
|
<ClInclude Include="..\include\vfs\Core\vfs_init.h" />
|
||||||
|
<ClInclude Include="..\include\vfs\Core\vfs_os_functions.h" />
|
||||||
|
<ClInclude Include="..\include\vfs\Core\vfs_path.h" />
|
||||||
|
<ClInclude Include="..\include\vfs\Core\vfs_profile.h" />
|
||||||
|
<ClInclude Include="..\include\vfs\Core\vfs_string.h" />
|
||||||
|
<ClInclude Include="..\include\vfs\Core\vfs_types.h" />
|
||||||
|
<ClInclude Include="..\include\vfs\Core\vfs_vfile.h" />
|
||||||
|
<ClInclude Include="..\include\vfs\Core\vfs_vloc.h" />
|
||||||
|
<ClInclude Include="..\include\vfs\Ext\7z\vfs_7z_library.h" />
|
||||||
|
<ClInclude Include="..\include\vfs\Ext\7z\vfs_create_7z_library.h" />
|
||||||
|
<ClInclude Include="..\include\vfs\Ext\slf\vfs_slf_library.h" />
|
||||||
|
<ClInclude Include="..\include\vfs\Tools\vfs_allocator.h" />
|
||||||
|
<ClInclude Include="..\include\vfs\Tools\vfs_file_logger.h" />
|
||||||
|
<ClInclude Include="..\include\vfs\Tools\vfs_hp_timer.h" />
|
||||||
|
<ClInclude Include="..\include\vfs\Tools\vfs_log.h" />
|
||||||
|
<ClInclude Include="..\include\vfs\Tools\vfs_parser_tools.h" />
|
||||||
|
<ClInclude Include="..\include\vfs\Tools\vfs_profiler.h" />
|
||||||
|
<ClInclude Include="..\include\vfs\Tools\vfs_property_container.h" />
|
||||||
|
<ClInclude Include="..\include\vfs\Tools\vfs_tools.h" />
|
||||||
|
<ClInclude Include="..\include\vfs\vfs_config.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\src\Aspects\vfs_logging.cpp" />
|
||||||
|
<ClCompile Include="..\src\Aspects\vfs_settings.cpp" />
|
||||||
|
<ClCompile Include="..\src\Aspects\vfs_synchronization.cpp" />
|
||||||
|
<ClCompile Include="..\src\Core\File\vfs_buffer_file.cpp" />
|
||||||
|
<ClCompile Include="..\src\Core\File\vfs_dir_file.cpp" />
|
||||||
|
<ClCompile Include="..\src\Core\File\vfs_file.cpp" />
|
||||||
|
<ClCompile Include="..\src\Core\File\vfs_lib_file.cpp" />
|
||||||
|
<ClCompile Include="..\src\Core\Interface\vfs_interface_members.cpp" />
|
||||||
|
<ClCompile Include="..\src\Core\Location\vfs_directory_tree.cpp" />
|
||||||
|
<ClCompile Include="..\src\Core\Location\vfs_lib_dir.cpp" />
|
||||||
|
<ClCompile Include="..\src\Core\Location\vfs_uncompressed_lib_base.cpp" />
|
||||||
|
<ClCompile Include="..\src\Core\vfs.cpp" />
|
||||||
|
<ClCompile Include="..\src\Core\vfs_debug.cpp" />
|
||||||
|
<ClCompile Include="..\src\Core\vfs_file_raii.cpp" />
|
||||||
|
<ClCompile Include="..\src\Core\vfs_init.cpp" />
|
||||||
|
<ClCompile Include="..\src\Core\vfs_os_functions.cpp" />
|
||||||
|
<ClCompile Include="..\src\Core\vfs_path.cpp" />
|
||||||
|
<ClCompile Include="..\src\Core\vfs_profile.cpp" />
|
||||||
|
<ClCompile Include="..\src\Core\vfs_string.cpp" />
|
||||||
|
<ClCompile Include="..\src\Core\vfs_types.cpp" />
|
||||||
|
<ClCompile Include="..\src\Core\vfs_vfile.cpp" />
|
||||||
|
<ClCompile Include="..\src\Core\vfs_vloc.cpp" />
|
||||||
|
<ClCompile Include="..\src\Ext\7z\vfs_7z_library.cpp" />
|
||||||
|
<ClCompile Include="..\src\Ext\7z\vfs_create_7z_library.cpp" />
|
||||||
|
<ClCompile Include="..\src\Ext\slf\vfs_slf_library.cpp" />
|
||||||
|
<ClCompile Include="..\src\Tools\vfs_allocator.cpp" />
|
||||||
|
<ClCompile Include="..\src\Tools\vfs_file_logger.cpp" />
|
||||||
|
<ClCompile Include="..\src\Tools\vfs_hp_timer.cpp" />
|
||||||
|
<ClCompile Include="..\src\Tools\vfs_log.cpp" />
|
||||||
|
<ClCompile Include="..\src\Tools\vfs_parser_tools.cpp" />
|
||||||
|
<ClCompile Include="..\src\Tools\vfs_profiler.cpp" />
|
||||||
|
<ClCompile Include="..\src\Tools\vfs_property_container.cpp" />
|
||||||
|
<ClCompile Include="..\src\Tools\vfs_tools.cpp" />
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>{463CB476-2798-493F-9CE8-CEAC5ECE5664}</ProjectGuid>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<RootNamespace>VFS</RootNamespace>
|
||||||
|
<ProjectName>VFS</ProjectName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<CharacterSet>NotSet</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='MapEditorD|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<CharacterSet>NotSet</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||||
|
<CharacterSet>NotSet</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='MapEditor|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||||
|
<CharacterSet>NotSet</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Relese_WithDebugInfo|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||||
|
<CharacterSet>NotSet</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='MapEditorD|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='MapEditor|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Relese_WithDebugInfo|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<OutDir>..\..\..\lib\VS2010\$(Configuration)\</OutDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='MapEditorD|Win32'">
|
||||||
|
<OutDir>..\..\..\lib\VS2010\$(Configuration)\</OutDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<IntDir>..\..\..\build\VS2010\$(ProjectName)_$(Configuration)\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='MapEditorD|Win32'">
|
||||||
|
<IntDir>..\..\..\build\VS2010\$(ProjectName)_$(Configuration)\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<OutDir>..\..\..\lib\VS2010\$(Configuration)\</OutDir>
|
||||||
|
<IntDir>..\..\..\build\VS2010\$(ProjectName)_$(Configuration)\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='MapEditor|Win32'">
|
||||||
|
<OutDir>..\..\..\lib\VS2010\$(Configuration)\</OutDir>
|
||||||
|
<IntDir>..\..\..\build\VS2010\$(ProjectName)_$(Configuration)\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Relese_WithDebugInfo|Win32'">
|
||||||
|
<OutDir>..\..\..\lib\VS2010\$(Configuration)\</OutDir>
|
||||||
|
<IntDir>..\..\..\build\VS2010\$(ProjectName)_$(Configuration)\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;SZIP_STATIC;VFS_STATIC;VFS_WITH_SLF;VFS_WITH_7ZIP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<AdditionalIncludeDirectories>..\include;..\ext\7z\src;..\ext\utfcpp\source</AdditionalIncludeDirectories>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||||
|
<PrecompiledHeaderFile>
|
||||||
|
</PrecompiledHeaderFile>
|
||||||
|
<PrecompiledHeaderOutputFile>
|
||||||
|
</PrecompiledHeaderOutputFile>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='MapEditorD|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;SZIP_STATIC;VFS_STATIC;VFS_WITH_SLF;VFS_WITH_7ZIP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<AdditionalIncludeDirectories>..\include;..\ext\7z\src;..\ext\utfcpp\source</AdditionalIncludeDirectories>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||||
|
<PrecompiledHeaderFile>
|
||||||
|
</PrecompiledHeaderFile>
|
||||||
|
<PrecompiledHeaderOutputFile>
|
||||||
|
</PrecompiledHeaderOutputFile>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;SZIP_STATIC;VFS_STATIC;VFS_WITH_SLF;VFS_WITH_7ZIP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
<AdditionalIncludeDirectories>..\include;..\ext\7z\src;..\ext\utfcpp\source</AdditionalIncludeDirectories>
|
||||||
|
<PrecompiledHeaderFile>
|
||||||
|
</PrecompiledHeaderFile>
|
||||||
|
<PrecompiledHeaderOutputFile>
|
||||||
|
</PrecompiledHeaderOutputFile>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='MapEditor|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;SZIP_STATIC;VFS_STATIC;VFS_WITH_SLF;VFS_WITH_7ZIP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
<AdditionalIncludeDirectories>..\include;..\ext\7z\src;..\ext\utfcpp\source</AdditionalIncludeDirectories>
|
||||||
|
<PrecompiledHeaderFile>
|
||||||
|
</PrecompiledHeaderFile>
|
||||||
|
<PrecompiledHeaderOutputFile>
|
||||||
|
</PrecompiledHeaderOutputFile>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Relese_WithDebugInfo|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;SZIP_STATIC;VFS_STATIC;VFS_WITH_SLF;VFS_WITH_7ZIP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
<AdditionalIncludeDirectories>..\include;..\ext\7z\src;..\ext\utfcpp\source</AdditionalIncludeDirectories>
|
||||||
|
<PrecompiledHeaderFile>
|
||||||
|
</PrecompiledHeaderFile>
|
||||||
|
<PrecompiledHeaderOutputFile>
|
||||||
|
</PrecompiledHeaderOutputFile>
|
||||||
|
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,241 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<Filter Include="Aspects">
|
||||||
|
<UniqueIdentifier>{6c3b13e6-1de1-49b1-a220-9fd9490119ee}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Core">
|
||||||
|
<UniqueIdentifier>{e906ed36-fcb5-449d-9038-bd238d1583f3}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Ext">
|
||||||
|
<UniqueIdentifier>{275b4cf2-0a06-4627-b4cc-f5ce7d2d46a7}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Tools">
|
||||||
|
<UniqueIdentifier>{4831f68f-56bb-4e7e-8d77-ab21a1a8031f}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Core\File">
|
||||||
|
<UniqueIdentifier>{93770afd-298c-46b1-95fe-5884cb101700}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Core\Interface">
|
||||||
|
<UniqueIdentifier>{db5b3ae9-28da-4e02-a106-662f2cd0b483}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Core\Location">
|
||||||
|
<UniqueIdentifier>{1f6aa1a4-2764-46bf-83d0-de215f92b26a}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\include\vfs\vfs_config.h" />
|
||||||
|
<ClInclude Include="..\include\vfs\Tools\vfs_allocator.h">
|
||||||
|
<Filter>Tools</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\vfs\Tools\vfs_file_logger.h">
|
||||||
|
<Filter>Tools</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\vfs\Tools\vfs_hp_timer.h">
|
||||||
|
<Filter>Tools</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\vfs\Tools\vfs_log.h">
|
||||||
|
<Filter>Tools</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\vfs\Tools\vfs_parser_tools.h">
|
||||||
|
<Filter>Tools</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\vfs\Tools\vfs_profiler.h">
|
||||||
|
<Filter>Tools</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\vfs\Tools\vfs_property_container.h">
|
||||||
|
<Filter>Tools</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\vfs\Tools\vfs_tools.h">
|
||||||
|
<Filter>Tools</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\vfs\Ext\7z\vfs_7z_library.h">
|
||||||
|
<Filter>Ext</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\vfs\Ext\7z\vfs_create_7z_library.h">
|
||||||
|
<Filter>Ext</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\vfs\Ext\slf\vfs_slf_library.h">
|
||||||
|
<Filter>Ext</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\vfs\Aspects\vfs_logging.h">
|
||||||
|
<Filter>Aspects</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\vfs\Aspects\vfs_settings.h">
|
||||||
|
<Filter>Aspects</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\vfs\Aspects\vfs_synchronization.h">
|
||||||
|
<Filter>Aspects</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\vfs\Core\vfs.h">
|
||||||
|
<Filter>Core</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\vfs\Core\vfs_debug.h">
|
||||||
|
<Filter>Core</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\vfs\Core\vfs_file_raii.h">
|
||||||
|
<Filter>Core</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\vfs\Core\vfs_init.h">
|
||||||
|
<Filter>Core</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\vfs\Core\vfs_path.h">
|
||||||
|
<Filter>Core</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\vfs\Core\vfs_profile.h">
|
||||||
|
<Filter>Core</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\vfs\Core\vfs_string.h">
|
||||||
|
<Filter>Core</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\vfs\Core\vfs_types.h">
|
||||||
|
<Filter>Core</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\vfs\Core\vfs_vfile.h">
|
||||||
|
<Filter>Core</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\vfs\Core\vfs_vloc.h">
|
||||||
|
<Filter>Core</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\vfs\Core\File\vfs_dir_file.h">
|
||||||
|
<Filter>Core\File</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\vfs\Core\File\vfs_file.h">
|
||||||
|
<Filter>Core\File</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\vfs\Core\File\vfs_lib_file.h">
|
||||||
|
<Filter>Core\File</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\vfs\Core\Interface\vfs_directory_interface.h">
|
||||||
|
<Filter>Core\Interface</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\vfs\Core\Interface\vfs_file_interface.h">
|
||||||
|
<Filter>Core\Interface</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\vfs\Core\Interface\vfs_iterator_interface.h">
|
||||||
|
<Filter>Core\Interface</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\vfs\Core\Interface\vfs_library_interface.h">
|
||||||
|
<Filter>Core\Interface</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\vfs\Core\Interface\vfs_location_interface.h">
|
||||||
|
<Filter>Core\Interface</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\vfs\Core\Location\vfs_directory_tree.h">
|
||||||
|
<Filter>Core\Location</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\vfs\Core\Location\vfs_lib_dir.h">
|
||||||
|
<Filter>Core\Location</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\vfs\Core\Location\vfs_uncompressed_lib_base.h">
|
||||||
|
<Filter>Core\Location</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\vfs\Core\vfs_os_functions.h">
|
||||||
|
<Filter>Core</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\vfs\Core\File\vfs_buffer_file.h">
|
||||||
|
<Filter>Core\File</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\src\Tools\vfs_allocator.cpp">
|
||||||
|
<Filter>Tools</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\src\Tools\vfs_file_logger.cpp">
|
||||||
|
<Filter>Tools</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\src\Tools\vfs_hp_timer.cpp">
|
||||||
|
<Filter>Tools</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\src\Tools\vfs_log.cpp">
|
||||||
|
<Filter>Tools</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\src\Tools\vfs_parser_tools.cpp">
|
||||||
|
<Filter>Tools</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\src\Tools\vfs_profiler.cpp">
|
||||||
|
<Filter>Tools</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\src\Tools\vfs_property_container.cpp">
|
||||||
|
<Filter>Tools</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\src\Tools\vfs_tools.cpp">
|
||||||
|
<Filter>Tools</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\src\Ext\slf\vfs_slf_library.cpp">
|
||||||
|
<Filter>Ext</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\src\Ext\7z\vfs_7z_library.cpp">
|
||||||
|
<Filter>Ext</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\src\Ext\7z\vfs_create_7z_library.cpp">
|
||||||
|
<Filter>Ext</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\src\Aspects\vfs_logging.cpp">
|
||||||
|
<Filter>Aspects</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\src\Aspects\vfs_settings.cpp">
|
||||||
|
<Filter>Aspects</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\src\Aspects\vfs_synchronization.cpp">
|
||||||
|
<Filter>Aspects</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\src\Core\vfs.cpp">
|
||||||
|
<Filter>Core</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\src\Core\vfs_debug.cpp">
|
||||||
|
<Filter>Core</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\src\Core\vfs_file_raii.cpp">
|
||||||
|
<Filter>Core</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\src\Core\vfs_init.cpp">
|
||||||
|
<Filter>Core</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\src\Core\vfs_path.cpp">
|
||||||
|
<Filter>Core</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\src\Core\vfs_profile.cpp">
|
||||||
|
<Filter>Core</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\src\Core\vfs_string.cpp">
|
||||||
|
<Filter>Core</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\src\Core\vfs_types.cpp">
|
||||||
|
<Filter>Core</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\src\Core\vfs_vfile.cpp">
|
||||||
|
<Filter>Core</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\src\Core\vfs_vloc.cpp">
|
||||||
|
<Filter>Core</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\src\Core\Location\vfs_directory_tree.cpp">
|
||||||
|
<Filter>Core\Location</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\src\Core\Location\vfs_lib_dir.cpp">
|
||||||
|
<Filter>Core\Location</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\src\Core\Location\vfs_uncompressed_lib_base.cpp">
|
||||||
|
<Filter>Core\Location</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\src\Core\Interface\vfs_interface_members.cpp">
|
||||||
|
<Filter>Core\Interface</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\src\Core\File\vfs_dir_file.cpp">
|
||||||
|
<Filter>Core\File</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\src\Core\File\vfs_file.cpp">
|
||||||
|
<Filter>Core\File</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\src\Core\File\vfs_lib_file.cpp">
|
||||||
|
<Filter>Core\File</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\src\Core\vfs_os_functions.cpp">
|
||||||
|
<Filter>Core</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\src\Core\File\vfs_buffer_file.cpp">
|
||||||
|
<Filter>Core\File</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
|
||||||
|
## 7-zip
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
option(BFVFS_7ZIP_MT "multi-threading support" OFF)
|
||||||
|
mark_as_advanced(BFVFS_7ZIP_MT)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(INCLUDE_7z
|
||||||
|
src/7z.h
|
||||||
|
src/7zBuf.h
|
||||||
|
src/7zCrc.h
|
||||||
|
src/7zFile.h
|
||||||
|
src/7zVersion.h
|
||||||
|
src/Alloc.h
|
||||||
|
src/Bcj2.h
|
||||||
|
src/Bra.h
|
||||||
|
src/CpuArch.h
|
||||||
|
src/Delta.h
|
||||||
|
src/LzFind.h
|
||||||
|
src/LzHash.h
|
||||||
|
src/Lzma2Dec.h
|
||||||
|
src/Lzma2Enc.h
|
||||||
|
src/Lzma86.h
|
||||||
|
src/LzmaEnc.h
|
||||||
|
src/LzmaLib.h
|
||||||
|
src/Ppmd.h
|
||||||
|
src/Sha256.h
|
||||||
|
src/Types.h
|
||||||
|
# src/Xz.h
|
||||||
|
# src/XzEnc.h
|
||||||
|
src/7zAlloc.h
|
||||||
|
)
|
||||||
|
if(WIN32 AND BFVFS_7ZIP_MT)
|
||||||
|
set(INCLUDE_7z ${INCLUDE_7z}
|
||||||
|
src/LzFindMt.h
|
||||||
|
src/MtCoder.h
|
||||||
|
src/Threads.h
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(SOURCE_7z
|
||||||
|
src/7zBuf.c
|
||||||
|
src/7zBuf2.c
|
||||||
|
src/7zCrc.c
|
||||||
|
src/7zCrcOpt.c
|
||||||
|
src/7zDec.c
|
||||||
|
src/7zFile.c
|
||||||
|
src/7zIn.c
|
||||||
|
src/7zStream.c
|
||||||
|
src/Alloc.c
|
||||||
|
src/Bcj2.c
|
||||||
|
src/Bra.c
|
||||||
|
src/Bra86.c
|
||||||
|
src/CpuArch.c
|
||||||
|
src/Delta.c
|
||||||
|
src/LzFind.c
|
||||||
|
src/Lzma2Dec.c
|
||||||
|
src/Lzma86Dec.c
|
||||||
|
src/Lzma86Enc.c
|
||||||
|
src/LzmaDec.c
|
||||||
|
src/LzmaEnc.c
|
||||||
|
src/Sha256.c
|
||||||
|
# src/Xz.c
|
||||||
|
# src/XzDec.c
|
||||||
|
# src/XzEnc.c
|
||||||
|
# src/XzIn.c
|
||||||
|
src/7zAlloc.c
|
||||||
|
)
|
||||||
|
if(WIN32 AND BFVFS_7ZIP_MT)
|
||||||
|
set(SOURCE_7z ${SOURCE_7z}
|
||||||
|
src/LzFindMt.c
|
||||||
|
src/Lzma2Enc.c
|
||||||
|
src/MtCoder.c
|
||||||
|
src/Threads.c
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
source_group("" FILES ${INCLUDE_7z} ${SOURCE_7z})
|
||||||
|
|
||||||
|
####################################################
|
||||||
|
|
||||||
|
if(BUILD_BFVFS_7ZIP_SHARED)
|
||||||
|
set(BUILD_SHARED_LIBS ON)
|
||||||
|
add_definitions(-DSZIP_EXPORT)
|
||||||
|
set(DEFINITIONS ${DEFINITIONS} -DSZIP_IMPORT)
|
||||||
|
else()
|
||||||
|
set(BUILD_SHARED_LIBS OFF)
|
||||||
|
add_definitions(-DSZIP_STATIC)
|
||||||
|
set(DEFINITIONS ${DEFINITIONS} -DSZIP_STATIC)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT WIN32 OR NOT BFVFS_7ZIP_MT)
|
||||||
|
add_definitions(-D_7ZIP_ST)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(BFVFS_7ZIP_TARGET "7z" CACHE INTERNAL "")
|
||||||
|
|
||||||
|
add_library( ${BFVFS_7ZIP_TARGET} ${INCLUDE_7z} ${SOURCE_7z} )
|
||||||
|
|
||||||
|
set_property(
|
||||||
|
TARGET ${BFVFS_7ZIP_TARGET}
|
||||||
|
PROPERTY ARCHIVE_OUTPUT_DIRECTORY ${BFVFS_LIBRARY_DIRS}
|
||||||
|
)
|
||||||
|
set_property(
|
||||||
|
TARGET ${BFVFS_7ZIP_TARGET}
|
||||||
|
PROPERTY LIBRARY_OUTPUT_DIRECTORY ${BFVFS_LIBRARY_DIRS}
|
||||||
|
)
|
||||||
|
set_property(
|
||||||
|
TARGET ${BFVFS_7ZIP_TARGET}
|
||||||
|
PROPERTY RUNTIME_OUTPUT_DIRECTORY ${BFVFS_RUNTIME_DIRS}
|
||||||
|
)
|
||||||
|
####################################################
|
||||||
|
|
||||||
|
set(BFVFS_7ZIP_DEFINITIONS ${DEFINITIONS} CACHE INTERNAL "")
|
||||||
@@ -0,0 +1,194 @@
|
|||||||
|
7z ANSI-C Decoder 4.62
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
7z ANSI-C provides 7z/LZMA decoding.
|
||||||
|
7z ANSI-C version is simplified version ported from C++ code.
|
||||||
|
|
||||||
|
LZMA is default and general compression method of 7z format
|
||||||
|
in 7-Zip compression program (www.7-zip.org). LZMA provides high
|
||||||
|
compression ratio and very fast decompression.
|
||||||
|
|
||||||
|
|
||||||
|
LICENSE
|
||||||
|
-------
|
||||||
|
|
||||||
|
7z ANSI-C Decoder is part of the LZMA SDK.
|
||||||
|
LZMA SDK is written and placed in the public domain by Igor Pavlov.
|
||||||
|
|
||||||
|
Files
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
7zDecode.* - Low level 7z decoding
|
||||||
|
7zExtract.* - High level 7z decoding
|
||||||
|
7zHeader.* - .7z format constants
|
||||||
|
7zIn.* - .7z archive opening
|
||||||
|
7zItem.* - .7z structures
|
||||||
|
7zMain.c - Test application
|
||||||
|
|
||||||
|
|
||||||
|
How To Use
|
||||||
|
----------
|
||||||
|
|
||||||
|
You must download 7-Zip program from www.7-zip.org.
|
||||||
|
|
||||||
|
You can create .7z archive with 7z.exe or 7za.exe:
|
||||||
|
|
||||||
|
7za.exe a archive.7z *.htm -r -mx -m0fb=255
|
||||||
|
|
||||||
|
If you have big number of files in archive, and you need fast extracting,
|
||||||
|
you can use partly-solid archives:
|
||||||
|
|
||||||
|
7za.exe a archive.7z *.htm -ms=512K -r -mx -m0fb=255 -m0d=512K
|
||||||
|
|
||||||
|
In that example 7-Zip will use 512KB solid blocks. So it needs to decompress only
|
||||||
|
512KB for extracting one file from such archive.
|
||||||
|
|
||||||
|
|
||||||
|
Limitations of current version of 7z ANSI-C Decoder
|
||||||
|
---------------------------------------------------
|
||||||
|
|
||||||
|
- It reads only "FileName", "Size", "LastWriteTime" and "CRC" information for each file in archive.
|
||||||
|
- It supports only LZMA and Copy (no compression) methods with BCJ or BCJ2 filters.
|
||||||
|
- It converts original UTF-16 Unicode file names to UTF-8 Unicode file names.
|
||||||
|
|
||||||
|
These limitations will be fixed in future versions.
|
||||||
|
|
||||||
|
|
||||||
|
Using 7z ANSI-C Decoder Test application:
|
||||||
|
-----------------------------------------
|
||||||
|
|
||||||
|
Usage: 7zDec <command> <archive_name>
|
||||||
|
|
||||||
|
<Command>:
|
||||||
|
e: Extract files from archive
|
||||||
|
l: List contents of archive
|
||||||
|
t: Test integrity of archive
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
7zDec l archive.7z
|
||||||
|
|
||||||
|
lists contents of archive.7z
|
||||||
|
|
||||||
|
7zDec e archive.7z
|
||||||
|
|
||||||
|
extracts files from archive.7z to current folder.
|
||||||
|
|
||||||
|
|
||||||
|
How to use .7z Decoder
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
Memory allocation
|
||||||
|
~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
7z Decoder uses two memory pools:
|
||||||
|
1) Temporary pool
|
||||||
|
2) Main pool
|
||||||
|
Such scheme can allow you to avoid fragmentation of allocated blocks.
|
||||||
|
|
||||||
|
|
||||||
|
Steps for using 7z decoder
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
Use code at 7zMain.c as example.
|
||||||
|
|
||||||
|
1) Declare variables:
|
||||||
|
inStream /* implements ILookInStream interface */
|
||||||
|
CSzArEx db; /* 7z archive database structure */
|
||||||
|
ISzAlloc allocImp; /* memory functions for main pool */
|
||||||
|
ISzAlloc allocTempImp; /* memory functions for temporary pool */
|
||||||
|
|
||||||
|
2) call CrcGenerateTable(); function to initialize CRC structures.
|
||||||
|
|
||||||
|
3) call SzArEx_Init(&db); function to initialize db structures.
|
||||||
|
|
||||||
|
4) call SzArEx_Open(&db, inStream, &allocMain, &allocTemp) to open archive
|
||||||
|
|
||||||
|
This function opens archive "inStream" and reads headers to "db".
|
||||||
|
All items in "db" will be allocated with "allocMain" functions.
|
||||||
|
SzArEx_Open function allocates and frees temporary structures by "allocTemp" functions.
|
||||||
|
|
||||||
|
5) List items or Extract items
|
||||||
|
|
||||||
|
Listing code:
|
||||||
|
~~~~~~~~~~~~~
|
||||||
|
{
|
||||||
|
UInt32 i;
|
||||||
|
for (i = 0; i < db.db.NumFiles; i++)
|
||||||
|
{
|
||||||
|
CFileItem *f = db.db.Files + i;
|
||||||
|
printf("%10d %s\n", (int)f->Size, f->Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Extracting code:
|
||||||
|
~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
SZ_RESULT SzAr_Extract(
|
||||||
|
CArchiveDatabaseEx *db,
|
||||||
|
ILookInStream *inStream,
|
||||||
|
UInt32 fileIndex, /* index of file */
|
||||||
|
UInt32 *blockIndex, /* index of solid block */
|
||||||
|
Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */
|
||||||
|
size_t *outBufferSize, /* buffer size for output buffer */
|
||||||
|
size_t *offset, /* offset of stream for required file in *outBuffer */
|
||||||
|
size_t *outSizeProcessed, /* size of file in *outBuffer */
|
||||||
|
ISzAlloc *allocMain,
|
||||||
|
ISzAlloc *allocTemp);
|
||||||
|
|
||||||
|
If you need to decompress more than one file, you can send these values from previous call:
|
||||||
|
blockIndex,
|
||||||
|
outBuffer,
|
||||||
|
outBufferSize,
|
||||||
|
You can consider "outBuffer" as cache of solid block. If your archive is solid,
|
||||||
|
it will increase decompression speed.
|
||||||
|
|
||||||
|
After decompressing you must free "outBuffer":
|
||||||
|
allocImp.Free(outBuffer);
|
||||||
|
|
||||||
|
6) call SzArEx_Free(&db, allocImp.Free) to free allocated items in "db".
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Memory requirements for .7z decoding
|
||||||
|
------------------------------------
|
||||||
|
|
||||||
|
Memory usage for Archive opening:
|
||||||
|
- Temporary pool:
|
||||||
|
- Memory for uncompressed .7z headers
|
||||||
|
- some other temporary blocks
|
||||||
|
- Main pool:
|
||||||
|
- Memory for database:
|
||||||
|
Estimated size of one file structures in solid archive:
|
||||||
|
- Size (4 or 8 Bytes)
|
||||||
|
- CRC32 (4 bytes)
|
||||||
|
- LastWriteTime (8 bytes)
|
||||||
|
- Some file information (4 bytes)
|
||||||
|
- File Name (variable length) + pointer + allocation structures
|
||||||
|
|
||||||
|
Memory usage for archive Decompressing:
|
||||||
|
- Temporary pool:
|
||||||
|
- Memory for LZMA decompressing structures
|
||||||
|
- Main pool:
|
||||||
|
- Memory for decompressed solid block
|
||||||
|
- Memory for temprorary buffers, if BCJ2 fileter is used. Usually these
|
||||||
|
temprorary buffers can be about 15% of solid block size.
|
||||||
|
|
||||||
|
|
||||||
|
7z Decoder doesn't allocate memory for compressed blocks.
|
||||||
|
Instead of this, you must allocate buffer with desired
|
||||||
|
size before calling 7z Decoder. Use 7zMain.c as example.
|
||||||
|
|
||||||
|
|
||||||
|
Defines
|
||||||
|
-------
|
||||||
|
|
||||||
|
_SZ_ALLOC_DEBUG - define it if you want to debug alloc/free operations to stderr.
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
http://www.7-zip.org
|
||||||
|
http://www.7-zip.org/sdk.html
|
||||||
|
http://www.7-zip.org/support.html
|
||||||
@@ -0,0 +1,471 @@
|
|||||||
|
7z Format description (2.30 Beta 25)
|
||||||
|
-----------------------------------
|
||||||
|
|
||||||
|
This file contains description of 7z archive format.
|
||||||
|
7z archive can contain files compressed with any method.
|
||||||
|
See "Methods.txt" for description for defined compressing methods.
|
||||||
|
|
||||||
|
|
||||||
|
Format structure Overview
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
Some fields can be optional.
|
||||||
|
|
||||||
|
Archive structure
|
||||||
|
~~~~~~~~~~~~~~~~~
|
||||||
|
SignatureHeader
|
||||||
|
[PackedStreams]
|
||||||
|
[PackedStreamsForHeaders]
|
||||||
|
[
|
||||||
|
Header
|
||||||
|
or
|
||||||
|
{
|
||||||
|
Packed Header
|
||||||
|
HeaderInfo
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Header structure
|
||||||
|
~~~~~~~~~~~~~~~~
|
||||||
|
{
|
||||||
|
ArchiveProperties
|
||||||
|
AdditionalStreams
|
||||||
|
{
|
||||||
|
PackInfo
|
||||||
|
{
|
||||||
|
PackPos
|
||||||
|
NumPackStreams
|
||||||
|
Sizes[NumPackStreams]
|
||||||
|
CRCs[NumPackStreams]
|
||||||
|
}
|
||||||
|
CodersInfo
|
||||||
|
{
|
||||||
|
NumFolders
|
||||||
|
Folders[NumFolders]
|
||||||
|
{
|
||||||
|
NumCoders
|
||||||
|
CodersInfo[NumCoders]
|
||||||
|
{
|
||||||
|
ID
|
||||||
|
NumInStreams;
|
||||||
|
NumOutStreams;
|
||||||
|
PropertiesSize
|
||||||
|
Properties[PropertiesSize]
|
||||||
|
}
|
||||||
|
NumBindPairs
|
||||||
|
BindPairsInfo[NumBindPairs]
|
||||||
|
{
|
||||||
|
InIndex;
|
||||||
|
OutIndex;
|
||||||
|
}
|
||||||
|
PackedIndices
|
||||||
|
}
|
||||||
|
UnPackSize[Folders][Folders.NumOutstreams]
|
||||||
|
CRCs[NumFolders]
|
||||||
|
}
|
||||||
|
SubStreamsInfo
|
||||||
|
{
|
||||||
|
NumUnPackStreamsInFolders[NumFolders];
|
||||||
|
UnPackSizes[]
|
||||||
|
CRCs[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MainStreamsInfo
|
||||||
|
{
|
||||||
|
(Same as in AdditionalStreams)
|
||||||
|
}
|
||||||
|
FilesInfo
|
||||||
|
{
|
||||||
|
NumFiles
|
||||||
|
Properties[]
|
||||||
|
{
|
||||||
|
ID
|
||||||
|
Size
|
||||||
|
Data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HeaderInfo structure
|
||||||
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
|
{
|
||||||
|
(Same as in AdditionalStreams)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Notes about Notation and encoding
|
||||||
|
---------------------------------
|
||||||
|
|
||||||
|
7z uses little endian encoding.
|
||||||
|
|
||||||
|
7z archive format has optional headers that are marked as
|
||||||
|
[]
|
||||||
|
Header
|
||||||
|
[]
|
||||||
|
|
||||||
|
REAL_UINT64 means real UINT64.
|
||||||
|
|
||||||
|
UINT64 means real UINT64 encoded with the following scheme:
|
||||||
|
|
||||||
|
Size of encoding sequence depends from first byte:
|
||||||
|
First_Byte Extra_Bytes Value
|
||||||
|
(binary)
|
||||||
|
0xxxxxxx : ( xxxxxxx )
|
||||||
|
10xxxxxx BYTE y[1] : ( xxxxxx << (8 * 1)) + y
|
||||||
|
110xxxxx BYTE y[2] : ( xxxxx << (8 * 2)) + y
|
||||||
|
...
|
||||||
|
1111110x BYTE y[6] : ( x << (8 * 6)) + y
|
||||||
|
11111110 BYTE y[7] : y
|
||||||
|
11111111 BYTE y[8] : y
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Property IDs
|
||||||
|
------------
|
||||||
|
|
||||||
|
0x00 = kEnd,
|
||||||
|
|
||||||
|
0x01 = kHeader,
|
||||||
|
|
||||||
|
0x02 = kArchiveProperties,
|
||||||
|
|
||||||
|
0x03 = kAdditionalStreamsInfo,
|
||||||
|
0x04 = kMainStreamsInfo,
|
||||||
|
0x05 = kFilesInfo,
|
||||||
|
|
||||||
|
0x06 = kPackInfo,
|
||||||
|
0x07 = kUnPackInfo,
|
||||||
|
0x08 = kSubStreamsInfo,
|
||||||
|
|
||||||
|
0x09 = kSize,
|
||||||
|
0x0A = kCRC,
|
||||||
|
|
||||||
|
0x0B = kFolder,
|
||||||
|
|
||||||
|
0x0C = kCodersUnPackSize,
|
||||||
|
0x0D = kNumUnPackStream,
|
||||||
|
|
||||||
|
0x0E = kEmptyStream,
|
||||||
|
0x0F = kEmptyFile,
|
||||||
|
0x10 = kAnti,
|
||||||
|
|
||||||
|
0x11 = kName,
|
||||||
|
0x12 = kCreationTime,
|
||||||
|
0x13 = kLastAccessTime,
|
||||||
|
0x14 = kLastWriteTime,
|
||||||
|
0x15 = kWinAttributes,
|
||||||
|
0x16 = kComment,
|
||||||
|
|
||||||
|
0x17 = kEncodedHeader,
|
||||||
|
|
||||||
|
|
||||||
|
7z format headers
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
SignatureHeader
|
||||||
|
~~~~~~~~~~~~~~~
|
||||||
|
BYTE kSignature[6] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
|
||||||
|
|
||||||
|
ArchiveVersion
|
||||||
|
{
|
||||||
|
BYTE Major; // now = 0
|
||||||
|
BYTE Minor; // now = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
UINT32 StartHeaderCRC;
|
||||||
|
|
||||||
|
StartHeader
|
||||||
|
{
|
||||||
|
REAL_UINT64 NextHeaderOffset
|
||||||
|
REAL_UINT64 NextHeaderSize
|
||||||
|
UINT32 NextHeaderCRC
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
...........................
|
||||||
|
|
||||||
|
|
||||||
|
ArchiveProperties
|
||||||
|
~~~~~~~~~~~~~~~~~
|
||||||
|
BYTE NID::kArchiveProperties (0x02)
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
BYTE PropertyType;
|
||||||
|
if (aType == 0)
|
||||||
|
break;
|
||||||
|
UINT64 PropertySize;
|
||||||
|
BYTE PropertyData[PropertySize];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Digests (NumStreams)
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
BYTE AllAreDefined
|
||||||
|
if (AllAreDefined == 0)
|
||||||
|
{
|
||||||
|
for(NumStreams)
|
||||||
|
BIT Defined
|
||||||
|
}
|
||||||
|
UINT32 CRCs[NumDefined]
|
||||||
|
|
||||||
|
|
||||||
|
PackInfo
|
||||||
|
~~~~~~~~~~~~
|
||||||
|
BYTE NID::kPackInfo (0x06)
|
||||||
|
UINT64 PackPos
|
||||||
|
UINT64 NumPackStreams
|
||||||
|
|
||||||
|
[]
|
||||||
|
BYTE NID::kSize (0x09)
|
||||||
|
UINT64 PackSizes[NumPackStreams]
|
||||||
|
[]
|
||||||
|
|
||||||
|
[]
|
||||||
|
BYTE NID::kCRC (0x0A)
|
||||||
|
PackStreamDigests[NumPackStreams]
|
||||||
|
[]
|
||||||
|
|
||||||
|
BYTE NID::kEnd
|
||||||
|
|
||||||
|
|
||||||
|
Folder
|
||||||
|
~~~~~~
|
||||||
|
UINT64 NumCoders;
|
||||||
|
for (NumCoders)
|
||||||
|
{
|
||||||
|
BYTE
|
||||||
|
{
|
||||||
|
0:3 DecompressionMethod.IDSize
|
||||||
|
4:
|
||||||
|
0 - IsSimple
|
||||||
|
1 - Is not simple
|
||||||
|
5:
|
||||||
|
0 - No Attributes
|
||||||
|
1 - There Are Attributes
|
||||||
|
7:
|
||||||
|
0 - Last Method in Alternative_Method_List
|
||||||
|
1 - There are more alternative methods
|
||||||
|
}
|
||||||
|
BYTE DecompressionMethod.ID[DecompressionMethod.IDSize]
|
||||||
|
if (!IsSimple)
|
||||||
|
{
|
||||||
|
UINT64 NumInStreams;
|
||||||
|
UINT64 NumOutStreams;
|
||||||
|
}
|
||||||
|
if (DecompressionMethod[0] != 0)
|
||||||
|
{
|
||||||
|
UINT64 PropertiesSize
|
||||||
|
BYTE Properties[PropertiesSize]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NumBindPairs = NumOutStreamsTotal - 1;
|
||||||
|
|
||||||
|
for (NumBindPairs)
|
||||||
|
{
|
||||||
|
UINT64 InIndex;
|
||||||
|
UINT64 OutIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
NumPackedStreams = NumInStreamsTotal - NumBindPairs;
|
||||||
|
if (NumPackedStreams > 1)
|
||||||
|
for(NumPackedStreams)
|
||||||
|
{
|
||||||
|
UINT64 Index;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Coders Info
|
||||||
|
~~~~~~~~~~~
|
||||||
|
|
||||||
|
BYTE NID::kUnPackInfo (0x07)
|
||||||
|
|
||||||
|
|
||||||
|
BYTE NID::kFolder (0x0B)
|
||||||
|
UINT64 NumFolders
|
||||||
|
BYTE External
|
||||||
|
switch(External)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
Folders[NumFolders]
|
||||||
|
case 1:
|
||||||
|
UINT64 DataStreamIndex
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BYTE ID::kCodersUnPackSize (0x0C)
|
||||||
|
for(Folders)
|
||||||
|
for(Folder.NumOutStreams)
|
||||||
|
UINT64 UnPackSize;
|
||||||
|
|
||||||
|
|
||||||
|
[]
|
||||||
|
BYTE NID::kCRC (0x0A)
|
||||||
|
UnPackDigests[NumFolders]
|
||||||
|
[]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
BYTE NID::kEnd
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
SubStreams Info
|
||||||
|
~~~~~~~~~~~~~~
|
||||||
|
BYTE NID::kSubStreamsInfo; (0x08)
|
||||||
|
|
||||||
|
[]
|
||||||
|
BYTE NID::kNumUnPackStream; (0x0D)
|
||||||
|
UINT64 NumUnPackStreamsInFolders[NumFolders];
|
||||||
|
[]
|
||||||
|
|
||||||
|
|
||||||
|
[]
|
||||||
|
BYTE NID::kSize (0x09)
|
||||||
|
UINT64 UnPackSizes[]
|
||||||
|
[]
|
||||||
|
|
||||||
|
|
||||||
|
[]
|
||||||
|
BYTE NID::kCRC (0x0A)
|
||||||
|
Digests[Number of streams with unknown CRC]
|
||||||
|
[]
|
||||||
|
|
||||||
|
|
||||||
|
BYTE NID::kEnd
|
||||||
|
|
||||||
|
|
||||||
|
Streams Info
|
||||||
|
~~~~~~~~~~~~
|
||||||
|
|
||||||
|
[]
|
||||||
|
PackInfo
|
||||||
|
[]
|
||||||
|
|
||||||
|
|
||||||
|
[]
|
||||||
|
CodersInfo
|
||||||
|
[]
|
||||||
|
|
||||||
|
|
||||||
|
[]
|
||||||
|
SubStreamsInfo
|
||||||
|
[]
|
||||||
|
|
||||||
|
BYTE NID::kEnd
|
||||||
|
|
||||||
|
|
||||||
|
FilesInfo
|
||||||
|
~~~~~~~~~
|
||||||
|
BYTE NID::kFilesInfo; (0x05)
|
||||||
|
UINT64 NumFiles
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
BYTE PropertyType;
|
||||||
|
if (aType == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
UINT64 Size;
|
||||||
|
|
||||||
|
switch(PropertyType)
|
||||||
|
{
|
||||||
|
kEmptyStream: (0x0E)
|
||||||
|
for(NumFiles)
|
||||||
|
BIT IsEmptyStream
|
||||||
|
|
||||||
|
kEmptyFile: (0x0F)
|
||||||
|
for(EmptyStreams)
|
||||||
|
BIT IsEmptyFile
|
||||||
|
|
||||||
|
kAnti: (0x10)
|
||||||
|
for(EmptyStreams)
|
||||||
|
BIT IsAntiFile
|
||||||
|
|
||||||
|
case kCreationTime: (0x12)
|
||||||
|
case kLastAccessTime: (0x13)
|
||||||
|
case kLastWriteTime: (0x14)
|
||||||
|
BYTE AllAreDefined
|
||||||
|
if (AllAreDefined == 0)
|
||||||
|
{
|
||||||
|
for(NumFiles)
|
||||||
|
BIT TimeDefined
|
||||||
|
}
|
||||||
|
BYTE External;
|
||||||
|
if(External != 0)
|
||||||
|
UINT64 DataIndex
|
||||||
|
[]
|
||||||
|
for(Definded Items)
|
||||||
|
UINT32 Time
|
||||||
|
[]
|
||||||
|
|
||||||
|
kNames: (0x11)
|
||||||
|
BYTE External;
|
||||||
|
if(External != 0)
|
||||||
|
UINT64 DataIndex
|
||||||
|
[]
|
||||||
|
for(Files)
|
||||||
|
{
|
||||||
|
wchar_t Names[NameSize];
|
||||||
|
wchar_t 0;
|
||||||
|
}
|
||||||
|
[]
|
||||||
|
|
||||||
|
kAttributes: (0x15)
|
||||||
|
BYTE AllAreDefined
|
||||||
|
if (AllAreDefined == 0)
|
||||||
|
{
|
||||||
|
for(NumFiles)
|
||||||
|
BIT AttributesAreDefined
|
||||||
|
}
|
||||||
|
BYTE External;
|
||||||
|
if(External != 0)
|
||||||
|
UINT64 DataIndex
|
||||||
|
[]
|
||||||
|
for(Definded Attributes)
|
||||||
|
UINT32 Attributes
|
||||||
|
[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Header
|
||||||
|
~~~~~~
|
||||||
|
BYTE NID::kHeader (0x01)
|
||||||
|
|
||||||
|
[]
|
||||||
|
ArchiveProperties
|
||||||
|
[]
|
||||||
|
|
||||||
|
[]
|
||||||
|
BYTE NID::kAdditionalStreamsInfo; (0x03)
|
||||||
|
StreamsInfo
|
||||||
|
[]
|
||||||
|
|
||||||
|
[]
|
||||||
|
BYTE NID::kMainStreamsInfo; (0x04)
|
||||||
|
StreamsInfo
|
||||||
|
[]
|
||||||
|
|
||||||
|
[]
|
||||||
|
FilesInfo
|
||||||
|
[]
|
||||||
|
|
||||||
|
BYTE NID::kEnd
|
||||||
|
|
||||||
|
|
||||||
|
HeaderInfo
|
||||||
|
~~~~~~~~~~
|
||||||
|
[]
|
||||||
|
BYTE NID::kEncodedHeader; (0x17)
|
||||||
|
StreamsInfo for Encoded Header
|
||||||
|
[]
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
End of document
|
||||||
@@ -0,0 +1,146 @@
|
|||||||
|
7-Zip method IDs (9.04)
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
Each compression or crypto method in 7z has unique binary value (ID).
|
||||||
|
The length of ID in bytes is arbitrary but it can not exceed 63 bits (8 bytes).
|
||||||
|
|
||||||
|
If you want to add some new ID, you have two ways:
|
||||||
|
1) Write request for allocating IDs to 7-zip developers.
|
||||||
|
2) Generate 8-bytes ID:
|
||||||
|
|
||||||
|
3F ZZ ZZ ZZ ZZ ZZ MM MM
|
||||||
|
|
||||||
|
3F - Prefix for random IDs (1 byte)
|
||||||
|
ZZ ZZ ZZ ZZ ZZ - Developer ID (5 bytes). Use real random bytes.
|
||||||
|
|
||||||
|
MM MM - Method ID (2 bytes)
|
||||||
|
|
||||||
|
You can notify 7-Zip developers about your Developer ID / Method ID.
|
||||||
|
|
||||||
|
Note: Use new ID only if old codec can not decode data encoded with new version.
|
||||||
|
|
||||||
|
|
||||||
|
List of defined IDs
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
00 - Copy
|
||||||
|
|
||||||
|
03 - Delta
|
||||||
|
04 - x86 (BCJ)
|
||||||
|
05 - PPC (Big Endian)
|
||||||
|
06 - IA64
|
||||||
|
07 - ARM (little endian)
|
||||||
|
08 - ARM Thumb (little endian)
|
||||||
|
09 - SPARC
|
||||||
|
21 - LZMA2
|
||||||
|
|
||||||
|
02.. - Common
|
||||||
|
03 Swap
|
||||||
|
- 2 Swap2
|
||||||
|
- 4 Swap4
|
||||||
|
|
||||||
|
03.. - 7z
|
||||||
|
01 - LZMA
|
||||||
|
01 - Version
|
||||||
|
|
||||||
|
03 - Branch
|
||||||
|
01 - x86
|
||||||
|
03 - BCJ
|
||||||
|
1B - BCJ2
|
||||||
|
02 - PPC
|
||||||
|
05 - PPC (Big Endian)
|
||||||
|
03 - Alpha
|
||||||
|
01 - Alpha
|
||||||
|
04 - IA64
|
||||||
|
01 - IA64
|
||||||
|
05 - ARM
|
||||||
|
01 - ARM
|
||||||
|
06 - M68
|
||||||
|
05 - M68 (Big Endian)
|
||||||
|
07 - ARM Thumb
|
||||||
|
01 - ARMT
|
||||||
|
08 - SPARC
|
||||||
|
05 - SPARC
|
||||||
|
|
||||||
|
04 - PPMD
|
||||||
|
01 - Version
|
||||||
|
|
||||||
|
7F -
|
||||||
|
01 - experimental methods.
|
||||||
|
|
||||||
|
|
||||||
|
04.. - Misc
|
||||||
|
00 - Reserved
|
||||||
|
01 - Zip
|
||||||
|
00 - Copy (not used). Use {00} instead
|
||||||
|
01 - Shrink
|
||||||
|
06 - Implode
|
||||||
|
08 - Deflate
|
||||||
|
09 - Deflate64
|
||||||
|
12 - BZip2 (not used). Use {04 02 02} instead
|
||||||
|
02 - BZip
|
||||||
|
02 - BZip2
|
||||||
|
03 - Rar
|
||||||
|
01 - Rar15
|
||||||
|
02 - Rar20
|
||||||
|
03 - Rar29
|
||||||
|
04 - Arj
|
||||||
|
01 - Arj (1,2,3)
|
||||||
|
02 - Arj 4
|
||||||
|
05 - Z
|
||||||
|
06 - Lzh
|
||||||
|
07 - Reserved for 7z
|
||||||
|
08 - Cab
|
||||||
|
09 - NSIS
|
||||||
|
01 - DeflateNSIS
|
||||||
|
02 - BZip2NSIS
|
||||||
|
|
||||||
|
|
||||||
|
06.. - Crypto
|
||||||
|
00 -
|
||||||
|
01 - AES
|
||||||
|
0x - AES-128
|
||||||
|
4x - AES-192
|
||||||
|
8x - AES-256
|
||||||
|
Cx - AES
|
||||||
|
|
||||||
|
x0 - ECB
|
||||||
|
x1 - CBC
|
||||||
|
x2 - CFB
|
||||||
|
x3 - OFB
|
||||||
|
|
||||||
|
07 - Reserved
|
||||||
|
0F - Reserved
|
||||||
|
|
||||||
|
F0 - Misc Ciphers (Real Ciphers without hashing algo)
|
||||||
|
|
||||||
|
F1 - Misc Ciphers (Combine)
|
||||||
|
01 - Zip
|
||||||
|
01 - Main Zip crypto algo
|
||||||
|
03 - RAR
|
||||||
|
02 -
|
||||||
|
03 - Rar29 AES-128 + (modified SHA-1)
|
||||||
|
07 - 7z
|
||||||
|
01 - AES-256 + SHA-256
|
||||||
|
|
||||||
|
07.. - Hash (subject to change)
|
||||||
|
00 -
|
||||||
|
01 - CRC
|
||||||
|
02 - SHA-1
|
||||||
|
03 - SHA-256
|
||||||
|
04 - SHA-384
|
||||||
|
05 - SHA-512
|
||||||
|
|
||||||
|
F0 - Misc Hash
|
||||||
|
|
||||||
|
F1 - Misc
|
||||||
|
03 - RAR
|
||||||
|
03 - Rar29 Password Hashing (modified SHA1)
|
||||||
|
07 - 7z
|
||||||
|
01 - SHA-256 Password Hashing
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
End of document
|
||||||
@@ -0,0 +1,266 @@
|
|||||||
|
HISTORY of the LZMA SDK
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
9.12 beta 2010-03-24
|
||||||
|
-------------------------
|
||||||
|
- The BUG in LZMA SDK 9.* was fixed: LZMA2 codec didn't work,
|
||||||
|
if more than 10 threads were used (or more than 20 threads in some modes).
|
||||||
|
|
||||||
|
|
||||||
|
9.11 beta 2010-03-15
|
||||||
|
-------------------------
|
||||||
|
- PPMd compression method support
|
||||||
|
|
||||||
|
|
||||||
|
9.09 2009-12-12
|
||||||
|
-------------------------
|
||||||
|
- The bug was fixed:
|
||||||
|
Utf16_To_Utf8 funstions in UTFConvert.cpp and 7zMain.c
|
||||||
|
incorrectly converted surrogate characters (the code >= 0x10000) to UTF-8.
|
||||||
|
- Some bugs were fixed
|
||||||
|
|
||||||
|
|
||||||
|
9.06 2009-08-17
|
||||||
|
-------------------------
|
||||||
|
- Some changes in ANSI-C 7z Decoder interfaces.
|
||||||
|
|
||||||
|
|
||||||
|
9.04 2009-05-30
|
||||||
|
-------------------------
|
||||||
|
- LZMA2 compression method support
|
||||||
|
- xz format support
|
||||||
|
|
||||||
|
|
||||||
|
4.65 2009-02-03
|
||||||
|
-------------------------
|
||||||
|
- Some minor fixes
|
||||||
|
|
||||||
|
|
||||||
|
4.63 2008-12-31
|
||||||
|
-------------------------
|
||||||
|
- Some minor fixes
|
||||||
|
|
||||||
|
|
||||||
|
4.61 beta 2008-11-23
|
||||||
|
-------------------------
|
||||||
|
- The bug in ANSI-C LZMA Decoder was fixed:
|
||||||
|
If encoded stream was corrupted, decoder could access memory
|
||||||
|
outside of allocated range.
|
||||||
|
- Some changes in ANSI-C 7z Decoder interfaces.
|
||||||
|
- LZMA SDK is placed in the public domain.
|
||||||
|
|
||||||
|
|
||||||
|
4.60 beta 2008-08-19
|
||||||
|
-------------------------
|
||||||
|
- Some minor fixes.
|
||||||
|
|
||||||
|
|
||||||
|
4.59 beta 2008-08-13
|
||||||
|
-------------------------
|
||||||
|
- The bug was fixed:
|
||||||
|
LZMA Encoder in fast compression mode could access memory outside of
|
||||||
|
allocated range in some rare cases.
|
||||||
|
|
||||||
|
|
||||||
|
4.58 beta 2008-05-05
|
||||||
|
-------------------------
|
||||||
|
- ANSI-C LZMA Decoder was rewritten for speed optimizations.
|
||||||
|
- ANSI-C LZMA Encoder was included to LZMA SDK.
|
||||||
|
- C++ LZMA code now is just wrapper over ANSI-C code.
|
||||||
|
|
||||||
|
|
||||||
|
4.57 2007-12-12
|
||||||
|
-------------------------
|
||||||
|
- Speed optimizations in Ñ++ LZMA Decoder.
|
||||||
|
- Small changes for more compatibility with some C/C++ compilers.
|
||||||
|
|
||||||
|
|
||||||
|
4.49 beta 2007-07-05
|
||||||
|
-------------------------
|
||||||
|
- .7z ANSI-C Decoder:
|
||||||
|
- now it supports BCJ and BCJ2 filters
|
||||||
|
- now it supports files larger than 4 GB.
|
||||||
|
- now it supports "Last Write Time" field for files.
|
||||||
|
- C++ code for .7z archives compressing/decompressing from 7-zip
|
||||||
|
was included to LZMA SDK.
|
||||||
|
|
||||||
|
|
||||||
|
4.43 2006-06-04
|
||||||
|
-------------------------
|
||||||
|
- Small changes for more compatibility with some C/C++ compilers.
|
||||||
|
|
||||||
|
|
||||||
|
4.42 2006-05-15
|
||||||
|
-------------------------
|
||||||
|
- Small changes in .h files in ANSI-C version.
|
||||||
|
|
||||||
|
|
||||||
|
4.39 beta 2006-04-14
|
||||||
|
-------------------------
|
||||||
|
- The bug in versions 4.33b:4.38b was fixed:
|
||||||
|
C++ version of LZMA encoder could not correctly compress
|
||||||
|
files larger than 2 GB with HC4 match finder (-mfhc4).
|
||||||
|
|
||||||
|
|
||||||
|
4.37 beta 2005-04-06
|
||||||
|
-------------------------
|
||||||
|
- Fixes in C++ code: code could no be compiled if _NO_EXCEPTIONS was defined.
|
||||||
|
|
||||||
|
|
||||||
|
4.35 beta 2005-03-02
|
||||||
|
-------------------------
|
||||||
|
- The bug was fixed in C++ version of LZMA Decoder:
|
||||||
|
If encoded stream was corrupted, decoder could access memory
|
||||||
|
outside of allocated range.
|
||||||
|
|
||||||
|
|
||||||
|
4.34 beta 2006-02-27
|
||||||
|
-------------------------
|
||||||
|
- Compressing speed and memory requirements for compressing were increased
|
||||||
|
- LZMA now can use only these match finders: HC4, BT2, BT3, BT4
|
||||||
|
|
||||||
|
|
||||||
|
4.32 2005-12-09
|
||||||
|
-------------------------
|
||||||
|
- Java version of LZMA SDK was included
|
||||||
|
|
||||||
|
|
||||||
|
4.30 2005-11-20
|
||||||
|
-------------------------
|
||||||
|
- Compression ratio was improved in -a2 mode
|
||||||
|
- Speed optimizations for compressing in -a2 mode
|
||||||
|
- -fb switch now supports values up to 273
|
||||||
|
- The bug in 7z_C (7zIn.c) was fixed:
|
||||||
|
It used Alloc/Free functions from different memory pools.
|
||||||
|
So if program used two memory pools, it worked incorrectly.
|
||||||
|
- 7z_C: .7z format supporting was improved
|
||||||
|
- LZMA# SDK (C#.NET version) was included
|
||||||
|
|
||||||
|
|
||||||
|
4.27 (Updated) 2005-09-21
|
||||||
|
-------------------------
|
||||||
|
- Some GUIDs/interfaces in C++ were changed.
|
||||||
|
IStream.h:
|
||||||
|
ISequentialInStream::Read now works as old ReadPart
|
||||||
|
ISequentialOutStream::Write now works as old WritePart
|
||||||
|
|
||||||
|
|
||||||
|
4.27 2005-08-07
|
||||||
|
-------------------------
|
||||||
|
- The bug in LzmaDecodeSize.c was fixed:
|
||||||
|
if _LZMA_IN_CB and _LZMA_OUT_READ were defined,
|
||||||
|
decompressing worked incorrectly.
|
||||||
|
|
||||||
|
|
||||||
|
4.26 2005-08-05
|
||||||
|
-------------------------
|
||||||
|
- Fixes in 7z_C code and LzmaTest.c:
|
||||||
|
previous versions could work incorrectly,
|
||||||
|
if malloc(0) returns 0
|
||||||
|
|
||||||
|
|
||||||
|
4.23 2005-06-29
|
||||||
|
-------------------------
|
||||||
|
- Small fixes in C++ code
|
||||||
|
|
||||||
|
|
||||||
|
4.22 2005-06-10
|
||||||
|
-------------------------
|
||||||
|
- Small fixes
|
||||||
|
|
||||||
|
|
||||||
|
4.21 2005-06-08
|
||||||
|
-------------------------
|
||||||
|
- Interfaces for ANSI-C LZMA Decoder (LzmaDecode.c) were changed
|
||||||
|
- New additional version of ANSI-C LZMA Decoder with zlib-like interface:
|
||||||
|
- LzmaStateDecode.h
|
||||||
|
- LzmaStateDecode.c
|
||||||
|
- LzmaStateTest.c
|
||||||
|
- ANSI-C LZMA Decoder now can decompress files larger than 4 GB
|
||||||
|
|
||||||
|
|
||||||
|
4.17 2005-04-18
|
||||||
|
-------------------------
|
||||||
|
- New example for RAM->RAM compressing/decompressing:
|
||||||
|
LZMA + BCJ (filter for x86 code):
|
||||||
|
- LzmaRam.h
|
||||||
|
- LzmaRam.cpp
|
||||||
|
- LzmaRamDecode.h
|
||||||
|
- LzmaRamDecode.c
|
||||||
|
- -f86 switch for lzma.exe
|
||||||
|
|
||||||
|
|
||||||
|
4.16 2005-03-29
|
||||||
|
-------------------------
|
||||||
|
- The bug was fixed in LzmaDecode.c (ANSI-C LZMA Decoder):
|
||||||
|
If _LZMA_OUT_READ was defined, and if encoded stream was corrupted,
|
||||||
|
decoder could access memory outside of allocated range.
|
||||||
|
- Speed optimization of ANSI-C LZMA Decoder (now it's about 20% faster).
|
||||||
|
Old version of LZMA Decoder now is in file LzmaDecodeSize.c.
|
||||||
|
LzmaDecodeSize.c can provide slightly smaller code than LzmaDecode.c
|
||||||
|
- Small speed optimization in LZMA C++ code
|
||||||
|
- filter for SPARC's code was added
|
||||||
|
- Simplified version of .7z ANSI-C Decoder was included
|
||||||
|
|
||||||
|
|
||||||
|
4.06 2004-09-05
|
||||||
|
-------------------------
|
||||||
|
- The bug in v4.05 was fixed:
|
||||||
|
LZMA-Encoder didn't release output stream in some cases.
|
||||||
|
|
||||||
|
|
||||||
|
4.05 2004-08-25
|
||||||
|
-------------------------
|
||||||
|
- Source code of filters for x86, IA-64, ARM, ARM-Thumb
|
||||||
|
and PowerPC code was included to SDK
|
||||||
|
- Some internal minor changes
|
||||||
|
|
||||||
|
|
||||||
|
4.04 2004-07-28
|
||||||
|
-------------------------
|
||||||
|
- More compatibility with some C++ compilers
|
||||||
|
|
||||||
|
|
||||||
|
4.03 2004-06-18
|
||||||
|
-------------------------
|
||||||
|
- "Benchmark" command was added. It measures compressing
|
||||||
|
and decompressing speed and shows rating values.
|
||||||
|
Also it checks hardware errors.
|
||||||
|
|
||||||
|
|
||||||
|
4.02 2004-06-10
|
||||||
|
-------------------------
|
||||||
|
- C++ LZMA Encoder/Decoder code now is more portable
|
||||||
|
and it can be compiled by GCC on Linux.
|
||||||
|
|
||||||
|
|
||||||
|
4.01 2004-02-15
|
||||||
|
-------------------------
|
||||||
|
- Some detection of data corruption was enabled.
|
||||||
|
LzmaDecode.c / RangeDecoderReadByte
|
||||||
|
.....
|
||||||
|
{
|
||||||
|
rd->ExtraBytes = 1;
|
||||||
|
return 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
4.00 2004-02-13
|
||||||
|
-------------------------
|
||||||
|
- Original version of LZMA SDK
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
HISTORY of the LZMA
|
||||||
|
-------------------
|
||||||
|
2001-2008: Improvements to LZMA compressing/decompressing code,
|
||||||
|
keeping compatibility with original LZMA format
|
||||||
|
1996-2001: Development of LZMA compression format
|
||||||
|
|
||||||
|
Some milestones:
|
||||||
|
|
||||||
|
2001-08-30: LZMA compression was added to 7-Zip
|
||||||
|
1999-01-02: First version of 7-Zip was released
|
||||||
|
|
||||||
|
|
||||||
|
End of document
|
||||||
@@ -0,0 +1,599 @@
|
|||||||
|
LZMA SDK 9.12
|
||||||
|
-------------
|
||||||
|
|
||||||
|
LZMA SDK provides the documentation, samples, header files, libraries,
|
||||||
|
and tools you need to develop applications that use LZMA compression.
|
||||||
|
|
||||||
|
LZMA is default and general compression method of 7z format
|
||||||
|
in 7-Zip compression program (www.7-zip.org). LZMA provides high
|
||||||
|
compression ratio and very fast decompression.
|
||||||
|
|
||||||
|
LZMA is an improved version of famous LZ77 compression algorithm.
|
||||||
|
It was improved in way of maximum increasing of compression ratio,
|
||||||
|
keeping high decompression speed and low memory requirements for
|
||||||
|
decompressing.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
LICENSE
|
||||||
|
-------
|
||||||
|
|
||||||
|
LZMA SDK is written and placed in the public domain by Igor Pavlov.
|
||||||
|
|
||||||
|
Some code in LZMA is based on public domain code from another developers:
|
||||||
|
1) PPMd var.H (2001): Dmitry Shkarin
|
||||||
|
2) SHA-256: Wei Dai (Crypto++ library)
|
||||||
|
|
||||||
|
|
||||||
|
LZMA SDK Contents
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
LZMA SDK includes:
|
||||||
|
|
||||||
|
- ANSI-C/C++/C#/Java source code for LZMA compressing and decompressing
|
||||||
|
- Compiled file->file LZMA compressing/decompressing program for Windows system
|
||||||
|
|
||||||
|
|
||||||
|
UNIX/Linux version
|
||||||
|
------------------
|
||||||
|
To compile C++ version of file->file LZMA encoding, go to directory
|
||||||
|
C++/7zip/Compress/LZMA_Alone
|
||||||
|
and call make to recompile it:
|
||||||
|
make -f makefile.gcc clean all
|
||||||
|
|
||||||
|
In some UNIX/Linux versions you must compile LZMA with static libraries.
|
||||||
|
To compile with static libraries, you can use
|
||||||
|
LIB = -lm -static
|
||||||
|
|
||||||
|
|
||||||
|
Files
|
||||||
|
---------------------
|
||||||
|
lzma.txt - LZMA SDK description (this file)
|
||||||
|
7zFormat.txt - 7z Format description
|
||||||
|
7zC.txt - 7z ANSI-C Decoder description
|
||||||
|
methods.txt - Compression method IDs for .7z
|
||||||
|
lzma.exe - Compiled file->file LZMA encoder/decoder for Windows
|
||||||
|
7zr.exe - 7-Zip with 7z/lzma/xz support.
|
||||||
|
history.txt - history of the LZMA SDK
|
||||||
|
|
||||||
|
|
||||||
|
Source code structure
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
C/ - C files
|
||||||
|
7zCrc*.* - CRC code
|
||||||
|
Alloc.* - Memory allocation functions
|
||||||
|
Bra*.* - Filters for x86, IA-64, ARM, ARM-Thumb, PowerPC and SPARC code
|
||||||
|
LzFind.* - Match finder for LZ (LZMA) encoders
|
||||||
|
LzFindMt.* - Match finder for LZ (LZMA) encoders for multithreading encoding
|
||||||
|
LzHash.h - Additional file for LZ match finder
|
||||||
|
LzmaDec.* - LZMA decoding
|
||||||
|
LzmaEnc.* - LZMA encoding
|
||||||
|
LzmaLib.* - LZMA Library for DLL calling
|
||||||
|
Types.h - Basic types for another .c files
|
||||||
|
Threads.* - The code for multithreading.
|
||||||
|
|
||||||
|
LzmaLib - LZMA Library (.DLL for Windows)
|
||||||
|
|
||||||
|
LzmaUtil - LZMA Utility (file->file LZMA encoder/decoder).
|
||||||
|
|
||||||
|
Archive - files related to archiving
|
||||||
|
7z - 7z ANSI-C Decoder
|
||||||
|
|
||||||
|
CPP/ -- CPP files
|
||||||
|
|
||||||
|
Common - common files for C++ projects
|
||||||
|
Windows - common files for Windows related code
|
||||||
|
|
||||||
|
7zip - files related to 7-Zip Project
|
||||||
|
|
||||||
|
Common - common files for 7-Zip
|
||||||
|
|
||||||
|
Compress - files related to compression/decompression
|
||||||
|
|
||||||
|
LZMA_Alone - file->file LZMA compression/decompression
|
||||||
|
|
||||||
|
Archive - files related to archiving
|
||||||
|
|
||||||
|
Common - common files for archive handling
|
||||||
|
7z - 7z C++ Encoder/Decoder
|
||||||
|
|
||||||
|
Bundles - Modules that are bundles of other modules
|
||||||
|
|
||||||
|
Alone7z - 7zr.exe: Standalone version of 7z.exe that supports only 7z/LZMA/BCJ/BCJ2
|
||||||
|
Format7zR - 7zr.dll: Reduced version of 7za.dll: extracting/compressing to 7z/LZMA/BCJ/BCJ2
|
||||||
|
Format7zExtractR - 7zxr.dll: Reduced version of 7zxa.dll: extracting from 7z/LZMA/BCJ/BCJ2.
|
||||||
|
|
||||||
|
UI - User Interface files
|
||||||
|
|
||||||
|
Client7z - Test application for 7za.dll, 7zr.dll, 7zxr.dll
|
||||||
|
Common - Common UI files
|
||||||
|
Console - Code for console archiver
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
CS/ - C# files
|
||||||
|
7zip
|
||||||
|
Common - some common files for 7-Zip
|
||||||
|
Compress - files related to compression/decompression
|
||||||
|
LZ - files related to LZ (Lempel-Ziv) compression algorithm
|
||||||
|
LZMA - LZMA compression/decompression
|
||||||
|
LzmaAlone - file->file LZMA compression/decompression
|
||||||
|
RangeCoder - Range Coder (special code of compression/decompression)
|
||||||
|
|
||||||
|
Java/ - Java files
|
||||||
|
SevenZip
|
||||||
|
Compression - files related to compression/decompression
|
||||||
|
LZ - files related to LZ (Lempel-Ziv) compression algorithm
|
||||||
|
LZMA - LZMA compression/decompression
|
||||||
|
RangeCoder - Range Coder (special code of compression/decompression)
|
||||||
|
|
||||||
|
|
||||||
|
C/C++ source code of LZMA SDK is part of 7-Zip project.
|
||||||
|
7-Zip source code can be downloaded from 7-Zip's SourceForge page:
|
||||||
|
|
||||||
|
http://sourceforge.net/projects/sevenzip/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
LZMA features
|
||||||
|
-------------
|
||||||
|
- Variable dictionary size (up to 1 GB)
|
||||||
|
- Estimated compressing speed: about 2 MB/s on 2 GHz CPU
|
||||||
|
- Estimated decompressing speed:
|
||||||
|
- 20-30 MB/s on 2 GHz Core 2 or AMD Athlon 64
|
||||||
|
- 1-2 MB/s on 200 MHz ARM, MIPS, PowerPC or other simple RISC
|
||||||
|
- Small memory requirements for decompressing (16 KB + DictionarySize)
|
||||||
|
- Small code size for decompressing: 5-8 KB
|
||||||
|
|
||||||
|
LZMA decoder uses only integer operations and can be
|
||||||
|
implemented in any modern 32-bit CPU (or on 16-bit CPU with some conditions).
|
||||||
|
|
||||||
|
Some critical operations that affect the speed of LZMA decompression:
|
||||||
|
1) 32*16 bit integer multiply
|
||||||
|
2) Misspredicted branches (penalty mostly depends from pipeline length)
|
||||||
|
3) 32-bit shift and arithmetic operations
|
||||||
|
|
||||||
|
The speed of LZMA decompressing mostly depends from CPU speed.
|
||||||
|
Memory speed has no big meaning. But if your CPU has small data cache,
|
||||||
|
overall weight of memory speed will slightly increase.
|
||||||
|
|
||||||
|
|
||||||
|
How To Use
|
||||||
|
----------
|
||||||
|
|
||||||
|
Using LZMA encoder/decoder executable
|
||||||
|
--------------------------------------
|
||||||
|
|
||||||
|
Usage: LZMA <e|d> inputFile outputFile [<switches>...]
|
||||||
|
|
||||||
|
e: encode file
|
||||||
|
|
||||||
|
d: decode file
|
||||||
|
|
||||||
|
b: Benchmark. There are two tests: compressing and decompressing
|
||||||
|
with LZMA method. Benchmark shows rating in MIPS (million
|
||||||
|
instructions per second). Rating value is calculated from
|
||||||
|
measured speed and it is normalized with Intel's Core 2 results.
|
||||||
|
Also Benchmark checks possible hardware errors (RAM
|
||||||
|
errors in most cases). Benchmark uses these settings:
|
||||||
|
(-a1, -d21, -fb32, -mfbt4). You can change only -d parameter.
|
||||||
|
Also you can change the number of iterations. Example for 30 iterations:
|
||||||
|
LZMA b 30
|
||||||
|
Default number of iterations is 10.
|
||||||
|
|
||||||
|
<Switches>
|
||||||
|
|
||||||
|
|
||||||
|
-a{N}: set compression mode 0 = fast, 1 = normal
|
||||||
|
default: 1 (normal)
|
||||||
|
|
||||||
|
d{N}: Sets Dictionary size - [0, 30], default: 23 (8MB)
|
||||||
|
The maximum value for dictionary size is 1 GB = 2^30 bytes.
|
||||||
|
Dictionary size is calculated as DictionarySize = 2^N bytes.
|
||||||
|
For decompressing file compressed by LZMA method with dictionary
|
||||||
|
size D = 2^N you need about D bytes of memory (RAM).
|
||||||
|
|
||||||
|
-fb{N}: set number of fast bytes - [5, 273], default: 128
|
||||||
|
Usually big number gives a little bit better compression ratio
|
||||||
|
and slower compression process.
|
||||||
|
|
||||||
|
-lc{N}: set number of literal context bits - [0, 8], default: 3
|
||||||
|
Sometimes lc=4 gives gain for big files.
|
||||||
|
|
||||||
|
-lp{N}: set number of literal pos bits - [0, 4], default: 0
|
||||||
|
lp switch is intended for periodical data when period is
|
||||||
|
equal 2^N. For example, for 32-bit (4 bytes)
|
||||||
|
periodical data you can use lp=2. Often it's better to set lc0,
|
||||||
|
if you change lp switch.
|
||||||
|
|
||||||
|
-pb{N}: set number of pos bits - [0, 4], default: 2
|
||||||
|
pb switch is intended for periodical data
|
||||||
|
when period is equal 2^N.
|
||||||
|
|
||||||
|
-mf{MF_ID}: set Match Finder. Default: bt4.
|
||||||
|
Algorithms from hc* group doesn't provide good compression
|
||||||
|
ratio, but they often works pretty fast in combination with
|
||||||
|
fast mode (-a0).
|
||||||
|
|
||||||
|
Memory requirements depend from dictionary size
|
||||||
|
(parameter "d" in table below).
|
||||||
|
|
||||||
|
MF_ID Memory Description
|
||||||
|
|
||||||
|
bt2 d * 9.5 + 4MB Binary Tree with 2 bytes hashing.
|
||||||
|
bt3 d * 11.5 + 4MB Binary Tree with 3 bytes hashing.
|
||||||
|
bt4 d * 11.5 + 4MB Binary Tree with 4 bytes hashing.
|
||||||
|
hc4 d * 7.5 + 4MB Hash Chain with 4 bytes hashing.
|
||||||
|
|
||||||
|
-eos: write End Of Stream marker. By default LZMA doesn't write
|
||||||
|
eos marker, since LZMA decoder knows uncompressed size
|
||||||
|
stored in .lzma file header.
|
||||||
|
|
||||||
|
-si: Read data from stdin (it will write End Of Stream marker).
|
||||||
|
-so: Write data to stdout
|
||||||
|
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
1) LZMA e file.bin file.lzma -d16 -lc0
|
||||||
|
|
||||||
|
compresses file.bin to file.lzma with 64 KB dictionary (2^16=64K)
|
||||||
|
and 0 literal context bits. -lc0 allows to reduce memory requirements
|
||||||
|
for decompression.
|
||||||
|
|
||||||
|
|
||||||
|
2) LZMA e file.bin file.lzma -lc0 -lp2
|
||||||
|
|
||||||
|
compresses file.bin to file.lzma with settings suitable
|
||||||
|
for 32-bit periodical data (for example, ARM or MIPS code).
|
||||||
|
|
||||||
|
3) LZMA d file.lzma file.bin
|
||||||
|
|
||||||
|
decompresses file.lzma to file.bin.
|
||||||
|
|
||||||
|
|
||||||
|
Compression ratio hints
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
Recommendations
|
||||||
|
---------------
|
||||||
|
|
||||||
|
To increase the compression ratio for LZMA compressing it's desirable
|
||||||
|
to have aligned data (if it's possible) and also it's desirable to locate
|
||||||
|
data in such order, where code is grouped in one place and data is
|
||||||
|
grouped in other place (it's better than such mixing: code, data, code,
|
||||||
|
data, ...).
|
||||||
|
|
||||||
|
|
||||||
|
Filters
|
||||||
|
-------
|
||||||
|
You can increase the compression ratio for some data types, using
|
||||||
|
special filters before compressing. For example, it's possible to
|
||||||
|
increase the compression ratio on 5-10% for code for those CPU ISAs:
|
||||||
|
x86, IA-64, ARM, ARM-Thumb, PowerPC, SPARC.
|
||||||
|
|
||||||
|
You can find C source code of such filters in C/Bra*.* files
|
||||||
|
|
||||||
|
You can check the compression ratio gain of these filters with such
|
||||||
|
7-Zip commands (example for ARM code):
|
||||||
|
No filter:
|
||||||
|
7z a a1.7z a.bin -m0=lzma
|
||||||
|
|
||||||
|
With filter for little-endian ARM code:
|
||||||
|
7z a a2.7z a.bin -m0=arm -m1=lzma
|
||||||
|
|
||||||
|
It works in such manner:
|
||||||
|
Compressing = Filter_encoding + LZMA_encoding
|
||||||
|
Decompressing = LZMA_decoding + Filter_decoding
|
||||||
|
|
||||||
|
Compressing and decompressing speed of such filters is very high,
|
||||||
|
so it will not increase decompressing time too much.
|
||||||
|
Moreover, it reduces decompression time for LZMA_decoding,
|
||||||
|
since compression ratio with filtering is higher.
|
||||||
|
|
||||||
|
These filters convert CALL (calling procedure) instructions
|
||||||
|
from relative offsets to absolute addresses, so such data becomes more
|
||||||
|
compressible.
|
||||||
|
|
||||||
|
For some ISAs (for example, for MIPS) it's impossible to get gain from such filter.
|
||||||
|
|
||||||
|
|
||||||
|
LZMA compressed file format
|
||||||
|
---------------------------
|
||||||
|
Offset Size Description
|
||||||
|
0 1 Special LZMA properties (lc,lp, pb in encoded form)
|
||||||
|
1 4 Dictionary size (little endian)
|
||||||
|
5 8 Uncompressed size (little endian). -1 means unknown size
|
||||||
|
13 Compressed data
|
||||||
|
|
||||||
|
|
||||||
|
ANSI-C LZMA Decoder
|
||||||
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Please note that interfaces for ANSI-C code were changed in LZMA SDK 4.58.
|
||||||
|
If you want to use old interfaces you can download previous version of LZMA SDK
|
||||||
|
from sourceforge.net site.
|
||||||
|
|
||||||
|
To use ANSI-C LZMA Decoder you need the following files:
|
||||||
|
1) LzmaDec.h + LzmaDec.c + Types.h
|
||||||
|
LzmaUtil/LzmaUtil.c is example application that uses these files.
|
||||||
|
|
||||||
|
|
||||||
|
Memory requirements for LZMA decoding
|
||||||
|
-------------------------------------
|
||||||
|
|
||||||
|
Stack usage of LZMA decoding function for local variables is not
|
||||||
|
larger than 200-400 bytes.
|
||||||
|
|
||||||
|
LZMA Decoder uses dictionary buffer and internal state structure.
|
||||||
|
Internal state structure consumes
|
||||||
|
state_size = (4 + (1.5 << (lc + lp))) KB
|
||||||
|
by default (lc=3, lp=0), state_size = 16 KB.
|
||||||
|
|
||||||
|
|
||||||
|
How To decompress data
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
LZMA Decoder (ANSI-C version) now supports 2 interfaces:
|
||||||
|
1) Single-call Decompressing
|
||||||
|
2) Multi-call State Decompressing (zlib-like interface)
|
||||||
|
|
||||||
|
You must use external allocator:
|
||||||
|
Example:
|
||||||
|
void *SzAlloc(void *p, size_t size) { p = p; return malloc(size); }
|
||||||
|
void SzFree(void *p, void *address) { p = p; free(address); }
|
||||||
|
ISzAlloc alloc = { SzAlloc, SzFree };
|
||||||
|
|
||||||
|
You can use p = p; operator to disable compiler warnings.
|
||||||
|
|
||||||
|
|
||||||
|
Single-call Decompressing
|
||||||
|
-------------------------
|
||||||
|
When to use: RAM->RAM decompressing
|
||||||
|
Compile files: LzmaDec.h + LzmaDec.c + Types.h
|
||||||
|
Compile defines: no defines
|
||||||
|
Memory Requirements:
|
||||||
|
- Input buffer: compressed size
|
||||||
|
- Output buffer: uncompressed size
|
||||||
|
- LZMA Internal Structures: state_size (16 KB for default settings)
|
||||||
|
|
||||||
|
Interface:
|
||||||
|
int LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
||||||
|
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
|
||||||
|
ELzmaStatus *status, ISzAlloc *alloc);
|
||||||
|
In:
|
||||||
|
dest - output data
|
||||||
|
destLen - output data size
|
||||||
|
src - input data
|
||||||
|
srcLen - input data size
|
||||||
|
propData - LZMA properties (5 bytes)
|
||||||
|
propSize - size of propData buffer (5 bytes)
|
||||||
|
finishMode - It has meaning only if the decoding reaches output limit (*destLen).
|
||||||
|
LZMA_FINISH_ANY - Decode just destLen bytes.
|
||||||
|
LZMA_FINISH_END - Stream must be finished after (*destLen).
|
||||||
|
You can use LZMA_FINISH_END, when you know that
|
||||||
|
current output buffer covers last bytes of stream.
|
||||||
|
alloc - Memory allocator.
|
||||||
|
|
||||||
|
Out:
|
||||||
|
destLen - processed output size
|
||||||
|
srcLen - processed input size
|
||||||
|
|
||||||
|
Output:
|
||||||
|
SZ_OK
|
||||||
|
status:
|
||||||
|
LZMA_STATUS_FINISHED_WITH_MARK
|
||||||
|
LZMA_STATUS_NOT_FINISHED
|
||||||
|
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
|
||||||
|
SZ_ERROR_DATA - Data error
|
||||||
|
SZ_ERROR_MEM - Memory allocation error
|
||||||
|
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
||||||
|
SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
|
||||||
|
|
||||||
|
If LZMA decoder sees end_marker before reaching output limit, it returns OK result,
|
||||||
|
and output value of destLen will be less than output buffer size limit.
|
||||||
|
|
||||||
|
You can use multiple checks to test data integrity after full decompression:
|
||||||
|
1) Check Result and "status" variable.
|
||||||
|
2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
|
||||||
|
3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
|
||||||
|
You must use correct finish mode in that case. */
|
||||||
|
|
||||||
|
|
||||||
|
Multi-call State Decompressing (zlib-like interface)
|
||||||
|
----------------------------------------------------
|
||||||
|
|
||||||
|
When to use: file->file decompressing
|
||||||
|
Compile files: LzmaDec.h + LzmaDec.c + Types.h
|
||||||
|
|
||||||
|
Memory Requirements:
|
||||||
|
- Buffer for input stream: any size (for example, 16 KB)
|
||||||
|
- Buffer for output stream: any size (for example, 16 KB)
|
||||||
|
- LZMA Internal Structures: state_size (16 KB for default settings)
|
||||||
|
- LZMA dictionary (dictionary size is encoded in LZMA properties header)
|
||||||
|
|
||||||
|
1) read LZMA properties (5 bytes) and uncompressed size (8 bytes, little-endian) to header:
|
||||||
|
unsigned char header[LZMA_PROPS_SIZE + 8];
|
||||||
|
ReadFile(inFile, header, sizeof(header)
|
||||||
|
|
||||||
|
2) Allocate CLzmaDec structures (state + dictionary) using LZMA properties
|
||||||
|
|
||||||
|
CLzmaDec state;
|
||||||
|
LzmaDec_Constr(&state);
|
||||||
|
res = LzmaDec_Allocate(&state, header, LZMA_PROPS_SIZE, &g_Alloc);
|
||||||
|
if (res != SZ_OK)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
3) Init LzmaDec structure before any new LZMA stream. And call LzmaDec_DecodeToBuf in loop
|
||||||
|
|
||||||
|
LzmaDec_Init(&state);
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
...
|
||||||
|
int res = LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
|
||||||
|
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode);
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
4) Free all allocated structures
|
||||||
|
LzmaDec_Free(&state, &g_Alloc);
|
||||||
|
|
||||||
|
For full code example, look at C/LzmaUtil/LzmaUtil.c code.
|
||||||
|
|
||||||
|
|
||||||
|
How To compress data
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
Compile files: LzmaEnc.h + LzmaEnc.c + Types.h +
|
||||||
|
LzFind.c + LzFind.h + LzFindMt.c + LzFindMt.h + LzHash.h
|
||||||
|
|
||||||
|
Memory Requirements:
|
||||||
|
- (dictSize * 11.5 + 6 MB) + state_size
|
||||||
|
|
||||||
|
Lzma Encoder can use two memory allocators:
|
||||||
|
1) alloc - for small arrays.
|
||||||
|
2) allocBig - for big arrays.
|
||||||
|
|
||||||
|
For example, you can use Large RAM Pages (2 MB) in allocBig allocator for
|
||||||
|
better compression speed. Note that Windows has bad implementation for
|
||||||
|
Large RAM Pages.
|
||||||
|
It's OK to use same allocator for alloc and allocBig.
|
||||||
|
|
||||||
|
|
||||||
|
Single-call Compression with callbacks
|
||||||
|
--------------------------------------
|
||||||
|
|
||||||
|
Check C/LzmaUtil/LzmaUtil.c as example,
|
||||||
|
|
||||||
|
When to use: file->file decompressing
|
||||||
|
|
||||||
|
1) you must implement callback structures for interfaces:
|
||||||
|
ISeqInStream
|
||||||
|
ISeqOutStream
|
||||||
|
ICompressProgress
|
||||||
|
ISzAlloc
|
||||||
|
|
||||||
|
static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }
|
||||||
|
static void SzFree(void *p, void *address) { p = p; MyFree(address); }
|
||||||
|
static ISzAlloc g_Alloc = { SzAlloc, SzFree };
|
||||||
|
|
||||||
|
CFileSeqInStream inStream;
|
||||||
|
CFileSeqOutStream outStream;
|
||||||
|
|
||||||
|
inStream.funcTable.Read = MyRead;
|
||||||
|
inStream.file = inFile;
|
||||||
|
outStream.funcTable.Write = MyWrite;
|
||||||
|
outStream.file = outFile;
|
||||||
|
|
||||||
|
|
||||||
|
2) Create CLzmaEncHandle object;
|
||||||
|
|
||||||
|
CLzmaEncHandle enc;
|
||||||
|
|
||||||
|
enc = LzmaEnc_Create(&g_Alloc);
|
||||||
|
if (enc == 0)
|
||||||
|
return SZ_ERROR_MEM;
|
||||||
|
|
||||||
|
|
||||||
|
3) initialize CLzmaEncProps properties;
|
||||||
|
|
||||||
|
LzmaEncProps_Init(&props);
|
||||||
|
|
||||||
|
Then you can change some properties in that structure.
|
||||||
|
|
||||||
|
4) Send LZMA properties to LZMA Encoder
|
||||||
|
|
||||||
|
res = LzmaEnc_SetProps(enc, &props);
|
||||||
|
|
||||||
|
5) Write encoded properties to header
|
||||||
|
|
||||||
|
Byte header[LZMA_PROPS_SIZE + 8];
|
||||||
|
size_t headerSize = LZMA_PROPS_SIZE;
|
||||||
|
UInt64 fileSize;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
res = LzmaEnc_WriteProperties(enc, header, &headerSize);
|
||||||
|
fileSize = MyGetFileLength(inFile);
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
header[headerSize++] = (Byte)(fileSize >> (8 * i));
|
||||||
|
MyWriteFileAndCheck(outFile, header, headerSize)
|
||||||
|
|
||||||
|
6) Call encoding function:
|
||||||
|
res = LzmaEnc_Encode(enc, &outStream.funcTable, &inStream.funcTable,
|
||||||
|
NULL, &g_Alloc, &g_Alloc);
|
||||||
|
|
||||||
|
7) Destroy LZMA Encoder Object
|
||||||
|
LzmaEnc_Destroy(enc, &g_Alloc, &g_Alloc);
|
||||||
|
|
||||||
|
|
||||||
|
If callback function return some error code, LzmaEnc_Encode also returns that code
|
||||||
|
or it can return the code like SZ_ERROR_READ, SZ_ERROR_WRITE or SZ_ERROR_PROGRESS.
|
||||||
|
|
||||||
|
|
||||||
|
Single-call RAM->RAM Compression
|
||||||
|
--------------------------------
|
||||||
|
|
||||||
|
Single-call RAM->RAM Compression is similar to Compression with callbacks,
|
||||||
|
but you provide pointers to buffers instead of pointers to stream callbacks:
|
||||||
|
|
||||||
|
HRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
|
||||||
|
CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
|
||||||
|
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
|
||||||
|
|
||||||
|
Return code:
|
||||||
|
SZ_OK - OK
|
||||||
|
SZ_ERROR_MEM - Memory allocation error
|
||||||
|
SZ_ERROR_PARAM - Incorrect paramater
|
||||||
|
SZ_ERROR_OUTPUT_EOF - output buffer overflow
|
||||||
|
SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Defines
|
||||||
|
-------
|
||||||
|
|
||||||
|
_LZMA_SIZE_OPT - Enable some optimizations in LZMA Decoder to get smaller executable code.
|
||||||
|
|
||||||
|
_LZMA_PROB32 - It can increase the speed on some 32-bit CPUs, but memory usage for
|
||||||
|
some structures will be doubled in that case.
|
||||||
|
|
||||||
|
_LZMA_UINT32_IS_ULONG - Define it if int is 16-bit on your compiler and long is 32-bit.
|
||||||
|
|
||||||
|
_LZMA_NO_SYSTEM_SIZE_T - Define it if you don't want to use size_t type.
|
||||||
|
|
||||||
|
|
||||||
|
_7ZIP_PPMD_SUPPPORT - Define it if you don't want to support PPMD method in AMSI-C .7z decoder.
|
||||||
|
|
||||||
|
|
||||||
|
C++ LZMA Encoder/Decoder
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
C++ LZMA code use COM-like interfaces. So if you want to use it,
|
||||||
|
you can study basics of COM/OLE.
|
||||||
|
C++ LZMA code is just wrapper over ANSI-C code.
|
||||||
|
|
||||||
|
|
||||||
|
C++ Notes
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
If you use some C++ code folders in 7-Zip (for example, C++ code for .7z handling),
|
||||||
|
you must check that you correctly work with "new" operator.
|
||||||
|
7-Zip can be compiled with MSVC 6.0 that doesn't throw "exception" from "new" operator.
|
||||||
|
So 7-Zip uses "CPP\Common\NewHandler.cpp" that redefines "new" operator:
|
||||||
|
operator new(size_t size)
|
||||||
|
{
|
||||||
|
void *p = ::malloc(size);
|
||||||
|
if (p == 0)
|
||||||
|
throw CNewException();
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
If you use MSCV that throws exception for "new" operator, you can compile without
|
||||||
|
"NewHandler.cpp". So standard exception will be used. Actually some code of
|
||||||
|
7-Zip catches any exception in internal code and converts it to HRESULT code.
|
||||||
|
So you don't need to catch CNewException, if you call COM interfaces of 7-Zip.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
http://www.7-zip.org
|
||||||
|
http://www.7-zip.org/sdk.html
|
||||||
|
http://www.7-zip.org/support.html
|
||||||
@@ -0,0 +1,203 @@
|
|||||||
|
/* 7z.h -- 7z interface
|
||||||
|
2010-03-11 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#ifndef __7Z_H
|
||||||
|
#define __7Z_H
|
||||||
|
|
||||||
|
#include "7zBuf.h"
|
||||||
|
|
||||||
|
EXTERN_C_BEGIN
|
||||||
|
|
||||||
|
#define k7zStartHeaderSize 0x20
|
||||||
|
#define k7zSignatureSize 6
|
||||||
|
SZIP_API extern Byte k7zSignature[k7zSignatureSize];
|
||||||
|
#define k7zMajorVersion 0
|
||||||
|
|
||||||
|
enum EIdEnum
|
||||||
|
{
|
||||||
|
k7zIdEnd,
|
||||||
|
k7zIdHeader,
|
||||||
|
k7zIdArchiveProperties,
|
||||||
|
k7zIdAdditionalStreamsInfo,
|
||||||
|
k7zIdMainStreamsInfo,
|
||||||
|
k7zIdFilesInfo,
|
||||||
|
k7zIdPackInfo,
|
||||||
|
k7zIdUnpackInfo,
|
||||||
|
k7zIdSubStreamsInfo,
|
||||||
|
k7zIdSize,
|
||||||
|
k7zIdCRC,
|
||||||
|
k7zIdFolder,
|
||||||
|
k7zIdCodersUnpackSize,
|
||||||
|
k7zIdNumUnpackStream,
|
||||||
|
k7zIdEmptyStream,
|
||||||
|
k7zIdEmptyFile,
|
||||||
|
k7zIdAnti,
|
||||||
|
k7zIdName,
|
||||||
|
k7zIdCTime,
|
||||||
|
k7zIdATime,
|
||||||
|
k7zIdMTime,
|
||||||
|
k7zIdWinAttributes,
|
||||||
|
k7zIdComment,
|
||||||
|
k7zIdEncodedHeader,
|
||||||
|
k7zIdStartPos,
|
||||||
|
k7zIdDummy
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
UInt32 NumInStreams;
|
||||||
|
UInt32 NumOutStreams;
|
||||||
|
UInt64 MethodID;
|
||||||
|
CBuf Props;
|
||||||
|
} CSzCoderInfo;
|
||||||
|
|
||||||
|
void SzCoderInfo_Init(CSzCoderInfo *p);
|
||||||
|
void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc);
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
UInt32 InIndex;
|
||||||
|
UInt32 OutIndex;
|
||||||
|
} CSzBindPair;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
CSzCoderInfo *Coders;
|
||||||
|
CSzBindPair *BindPairs;
|
||||||
|
UInt32 *PackStreams;
|
||||||
|
UInt64 *UnpackSizes;
|
||||||
|
UInt32 NumCoders;
|
||||||
|
UInt32 NumBindPairs;
|
||||||
|
UInt32 NumPackStreams;
|
||||||
|
int UnpackCRCDefined;
|
||||||
|
UInt32 UnpackCRC;
|
||||||
|
|
||||||
|
UInt32 NumUnpackStreams;
|
||||||
|
} CSzFolder;
|
||||||
|
|
||||||
|
void SzFolder_Init(CSzFolder *p);
|
||||||
|
SZIP_API UInt64 SzFolder_GetUnpackSize(CSzFolder *p);
|
||||||
|
int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex);
|
||||||
|
SZIP_API UInt32 SzFolder_GetNumOutStreams(CSzFolder *p);
|
||||||
|
SZIP_API UInt64 SzFolder_GetUnpackSize(CSzFolder *p);
|
||||||
|
|
||||||
|
SRes SzFolder_Decode(const CSzFolder *folder, const UInt64 *packSizes,
|
||||||
|
ILookInStream *stream, UInt64 startPos,
|
||||||
|
Byte *outBuffer, size_t outSize, ISzAlloc *allocMain);
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
UInt32 Low;
|
||||||
|
UInt32 High;
|
||||||
|
} CNtfsFileTime;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
CNtfsFileTime MTime;
|
||||||
|
UInt64 Size;
|
||||||
|
UInt32 Crc;
|
||||||
|
UInt32 Attrib;
|
||||||
|
Byte HasStream;
|
||||||
|
Byte IsDir;
|
||||||
|
Byte IsAnti;
|
||||||
|
Byte CrcDefined;
|
||||||
|
Byte MTimeDefined;
|
||||||
|
Byte AttribDefined;
|
||||||
|
} CSzFileItem;
|
||||||
|
|
||||||
|
void SzFile_Init(CSzFileItem *p);
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
UInt64 *PackSizes;
|
||||||
|
Byte *PackCRCsDefined;
|
||||||
|
UInt32 *PackCRCs;
|
||||||
|
CSzFolder *Folders;
|
||||||
|
CSzFileItem *Files;
|
||||||
|
UInt32 NumPackStreams;
|
||||||
|
UInt32 NumFolders;
|
||||||
|
UInt32 NumFiles;
|
||||||
|
} CSzAr;
|
||||||
|
|
||||||
|
void SzAr_Init(CSzAr *p);
|
||||||
|
void SzAr_Free(CSzAr *p, ISzAlloc *alloc);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
SzExtract extracts file from archive
|
||||||
|
|
||||||
|
*outBuffer must be 0 before first call for each new archive.
|
||||||
|
|
||||||
|
Extracting cache:
|
||||||
|
If you need to decompress more than one file, you can send
|
||||||
|
these values from previous call:
|
||||||
|
*blockIndex,
|
||||||
|
*outBuffer,
|
||||||
|
*outBufferSize
|
||||||
|
You can consider "*outBuffer" as cache of solid block. If your archive is solid,
|
||||||
|
it will increase decompression speed.
|
||||||
|
|
||||||
|
If you use external function, you can declare these 3 cache variables
|
||||||
|
(blockIndex, outBuffer, outBufferSize) as static in that external function.
|
||||||
|
|
||||||
|
Free *outBuffer and set *outBuffer to 0, if you want to flush cache.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
CSzAr db;
|
||||||
|
|
||||||
|
UInt64 startPosAfterHeader;
|
||||||
|
UInt64 dataPos;
|
||||||
|
|
||||||
|
UInt32 *FolderStartPackStreamIndex;
|
||||||
|
UInt64 *PackStreamStartPositions;
|
||||||
|
UInt32 *FolderStartFileIndex;
|
||||||
|
UInt32 *FileIndexToFolderIndexMap;
|
||||||
|
|
||||||
|
size_t *FileNameOffsets; /* in 2-byte steps */
|
||||||
|
CBuf FileNames; /* UTF-16-LE */
|
||||||
|
} CSzArEx;
|
||||||
|
|
||||||
|
SZIP_API void SzArEx_Init(CSzArEx *p);
|
||||||
|
void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc);
|
||||||
|
SZIP_API UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder);
|
||||||
|
int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize);
|
||||||
|
|
||||||
|
/*
|
||||||
|
if dest == NULL, the return value specifies the required size of the buffer,
|
||||||
|
in 16-bit characters, including the null-terminating character.
|
||||||
|
if dest != NULL, the return value specifies the number of 16-bit characters that
|
||||||
|
are written to the dest, including the null-terminating character. */
|
||||||
|
|
||||||
|
SZIP_API size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest);
|
||||||
|
|
||||||
|
SRes SzArEx_Extract(
|
||||||
|
const CSzArEx *db,
|
||||||
|
ILookInStream *inStream,
|
||||||
|
UInt32 fileIndex, /* index of file */
|
||||||
|
UInt32 *blockIndex, /* index of solid block */
|
||||||
|
Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */
|
||||||
|
size_t *outBufferSize, /* buffer size for output buffer */
|
||||||
|
size_t *offset, /* offset of stream for required file in *outBuffer */
|
||||||
|
size_t *outSizeProcessed, /* size of file in *outBuffer */
|
||||||
|
ISzAlloc *allocMain,
|
||||||
|
ISzAlloc *allocTemp);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
SzArEx_Open Errors:
|
||||||
|
SZ_ERROR_NO_ARCHIVE
|
||||||
|
SZ_ERROR_ARCHIVE
|
||||||
|
SZ_ERROR_UNSUPPORTED
|
||||||
|
SZ_ERROR_MEM
|
||||||
|
SZ_ERROR_CRC
|
||||||
|
SZ_ERROR_INPUT_EOF
|
||||||
|
SZ_ERROR_FAIL
|
||||||
|
*/
|
||||||
|
|
||||||
|
SZIP_API SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp);
|
||||||
|
|
||||||
|
EXTERN_C_END
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
/* 7zAlloc.c -- Allocation functions
|
||||||
|
2008-10-04 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "7zAlloc.h"
|
||||||
|
|
||||||
|
/* #define _SZ_ALLOC_DEBUG */
|
||||||
|
/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */
|
||||||
|
|
||||||
|
#ifdef _SZ_ALLOC_DEBUG
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
int g_allocCount = 0;
|
||||||
|
int g_allocCountTemp = 0;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void *SzAlloc(void *p, size_t size)
|
||||||
|
{
|
||||||
|
p = p;
|
||||||
|
if (size == 0)
|
||||||
|
return 0;
|
||||||
|
#ifdef _SZ_ALLOC_DEBUG
|
||||||
|
fprintf(stderr, "\nAlloc %10d bytes; count = %10d", size, g_allocCount);
|
||||||
|
g_allocCount++;
|
||||||
|
#endif
|
||||||
|
return malloc(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SzFree(void *p, void *address)
|
||||||
|
{
|
||||||
|
p = p;
|
||||||
|
#ifdef _SZ_ALLOC_DEBUG
|
||||||
|
if (address != 0)
|
||||||
|
{
|
||||||
|
g_allocCount--;
|
||||||
|
fprintf(stderr, "\nFree; count = %10d", g_allocCount);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
free(address);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *SzAllocTemp(void *p, size_t size)
|
||||||
|
{
|
||||||
|
p = p;
|
||||||
|
if (size == 0)
|
||||||
|
return 0;
|
||||||
|
#ifdef _SZ_ALLOC_DEBUG
|
||||||
|
fprintf(stderr, "\nAlloc_temp %10d bytes; count = %10d", size, g_allocCountTemp);
|
||||||
|
g_allocCountTemp++;
|
||||||
|
#ifdef _WIN32
|
||||||
|
return HeapAlloc(GetProcessHeap(), 0, size);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
return malloc(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SzFreeTemp(void *p, void *address)
|
||||||
|
{
|
||||||
|
p = p;
|
||||||
|
#ifdef _SZ_ALLOC_DEBUG
|
||||||
|
if (address != 0)
|
||||||
|
{
|
||||||
|
g_allocCountTemp--;
|
||||||
|
fprintf(stderr, "\nFree_temp; count = %10d", g_allocCountTemp);
|
||||||
|
}
|
||||||
|
#ifdef _WIN32
|
||||||
|
HeapFree(GetProcessHeap(), 0, address);
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
free(address);
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
/* 7zAlloc.h -- Allocation functions
|
||||||
|
2009-02-07 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#ifndef __7Z_ALLOC_H
|
||||||
|
#define __7Z_ALLOC_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include "Types.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SZIP_API void *SzAlloc(void *p, size_t size);
|
||||||
|
SZIP_API void SzFree(void *p, void *address);
|
||||||
|
|
||||||
|
SZIP_API void *SzAllocTemp(void *p, size_t size);
|
||||||
|
SZIP_API void SzFreeTemp(void *p, void *address);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
/* 7zBuf.c -- Byte Buffer
|
||||||
|
2008-03-28
|
||||||
|
Igor Pavlov
|
||||||
|
Public domain */
|
||||||
|
|
||||||
|
#include "7zBuf.h"
|
||||||
|
|
||||||
|
void Buf_Init(CBuf *p)
|
||||||
|
{
|
||||||
|
p->data = 0;
|
||||||
|
p->size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
p->size = 0;
|
||||||
|
if (size == 0)
|
||||||
|
{
|
||||||
|
p->data = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
p->data = (Byte *)alloc->Alloc(alloc, size);
|
||||||
|
if (p->data != 0)
|
||||||
|
{
|
||||||
|
p->size = size;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Buf_Free(CBuf *p, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
alloc->Free(alloc, p->data);
|
||||||
|
p->data = 0;
|
||||||
|
p->size = 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/* 7zBuf.h -- Byte Buffer
|
||||||
|
2009-02-07 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#ifndef __7Z_BUF_H
|
||||||
|
#define __7Z_BUF_H
|
||||||
|
|
||||||
|
#include "Types.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
Byte *data;
|
||||||
|
size_t size;
|
||||||
|
} CBuf;
|
||||||
|
|
||||||
|
void Buf_Init(CBuf *p);
|
||||||
|
int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc);
|
||||||
|
void Buf_Free(CBuf *p, ISzAlloc *alloc);
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
Byte *data;
|
||||||
|
size_t size;
|
||||||
|
size_t pos;
|
||||||
|
} CDynBuf;
|
||||||
|
|
||||||
|
void DynBuf_Construct(CDynBuf *p);
|
||||||
|
void DynBuf_SeekToBeg(CDynBuf *p);
|
||||||
|
int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc);
|
||||||
|
void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
/* 7zBuf2.c -- Byte Buffer
|
||||||
|
2008-10-04 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include "7zBuf.h"
|
||||||
|
|
||||||
|
void DynBuf_Construct(CDynBuf *p)
|
||||||
|
{
|
||||||
|
p->data = 0;
|
||||||
|
p->size = 0;
|
||||||
|
p->pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DynBuf_SeekToBeg(CDynBuf *p)
|
||||||
|
{
|
||||||
|
p->pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
if (size > p->size - p->pos)
|
||||||
|
{
|
||||||
|
size_t newSize = p->pos + size;
|
||||||
|
Byte *data;
|
||||||
|
newSize += newSize / 4;
|
||||||
|
data = (Byte *)alloc->Alloc(alloc, newSize);
|
||||||
|
if (data == 0)
|
||||||
|
return 0;
|
||||||
|
p->size = newSize;
|
||||||
|
memcpy(data, p->data, p->pos);
|
||||||
|
alloc->Free(alloc, p->data);
|
||||||
|
p->data = data;
|
||||||
|
}
|
||||||
|
memcpy(p->data + p->pos, buf, size);
|
||||||
|
p->pos += size;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
alloc->Free(alloc, p->data);
|
||||||
|
p->data = 0;
|
||||||
|
p->size = 0;
|
||||||
|
p->pos = 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
/* 7zCrc.c -- CRC32 calculation
|
||||||
|
2009-11-23 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#include "7zCrc.h"
|
||||||
|
#include "CpuArch.h"
|
||||||
|
|
||||||
|
#define kCrcPoly 0xEDB88320
|
||||||
|
|
||||||
|
#ifdef MY_CPU_LE
|
||||||
|
#define CRC_NUM_TABLES 8
|
||||||
|
#else
|
||||||
|
#define CRC_NUM_TABLES 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table);
|
||||||
|
|
||||||
|
static CRC_FUNC g_CrcUpdate;
|
||||||
|
UInt32 g_CrcTable[256 * CRC_NUM_TABLES];
|
||||||
|
|
||||||
|
#if CRC_NUM_TABLES == 1
|
||||||
|
|
||||||
|
#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
|
||||||
|
|
||||||
|
static UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table)
|
||||||
|
{
|
||||||
|
const Byte *p = (const Byte *)data;
|
||||||
|
for (; size > 0; size--, p++)
|
||||||
|
v = CRC_UPDATE_BYTE_2(v, *p);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table);
|
||||||
|
UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size)
|
||||||
|
{
|
||||||
|
return g_CrcUpdate(v, data, size, g_CrcTable);
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size)
|
||||||
|
{
|
||||||
|
return g_CrcUpdate(CRC_INIT_VAL, data, size, g_CrcTable) ^ CRC_INIT_VAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MY_FAST_CALL CrcGenerateTable()
|
||||||
|
{
|
||||||
|
UInt32 i;
|
||||||
|
for (i = 0; i < 256; i++)
|
||||||
|
{
|
||||||
|
UInt32 r = i;
|
||||||
|
unsigned j;
|
||||||
|
for (j = 0; j < 8; j++)
|
||||||
|
r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
|
||||||
|
g_CrcTable[i] = r;
|
||||||
|
}
|
||||||
|
#if CRC_NUM_TABLES == 1
|
||||||
|
g_CrcUpdate = CrcUpdateT1;
|
||||||
|
#else
|
||||||
|
for (; i < 256 * CRC_NUM_TABLES; i++)
|
||||||
|
{
|
||||||
|
UInt32 r = g_CrcTable[i - 256];
|
||||||
|
g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8);
|
||||||
|
}
|
||||||
|
g_CrcUpdate = CrcUpdateT4;
|
||||||
|
#ifdef MY_CPU_X86_OR_AMD64
|
||||||
|
if (!CPU_Is_InOrder())
|
||||||
|
g_CrcUpdate = CrcUpdateT8;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
/* 7zCrc.h -- CRC32 calculation
|
||||||
|
2009-11-21 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#ifndef __7Z_CRC_H
|
||||||
|
#define __7Z_CRC_H
|
||||||
|
|
||||||
|
#include "Types.h"
|
||||||
|
|
||||||
|
EXTERN_C_BEGIN
|
||||||
|
|
||||||
|
extern UInt32 g_CrcTable[];
|
||||||
|
|
||||||
|
/* Call CrcGenerateTable one time before other CRC functions */
|
||||||
|
SZIP_API void MY_FAST_CALL CrcGenerateTable(void);
|
||||||
|
|
||||||
|
#define CRC_INIT_VAL 0xFFFFFFFF
|
||||||
|
#define CRC_GET_DIGEST(crc) ((crc) ^ CRC_INIT_VAL)
|
||||||
|
#define CRC_UPDATE_BYTE(crc, b) (g_CrcTable[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
|
||||||
|
|
||||||
|
UInt32 MY_FAST_CALL CrcUpdate(UInt32 crc, const void *data, size_t size);
|
||||||
|
SZIP_API UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size);
|
||||||
|
|
||||||
|
EXTERN_C_END
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
/* 7zCrcOpt.c -- CRC32 calculation : optimized version
|
||||||
|
2009-11-23 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#include "CpuArch.h"
|
||||||
|
|
||||||
|
#ifdef MY_CPU_LE
|
||||||
|
|
||||||
|
#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
|
||||||
|
|
||||||
|
UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table)
|
||||||
|
{
|
||||||
|
const Byte *p = (const Byte *)data;
|
||||||
|
for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++)
|
||||||
|
v = CRC_UPDATE_BYTE_2(v, *p);
|
||||||
|
for (; size >= 4; size -= 4, p += 4)
|
||||||
|
{
|
||||||
|
v ^= *(const UInt32 *)p;
|
||||||
|
v =
|
||||||
|
table[0x300 + (v & 0xFF)] ^
|
||||||
|
table[0x200 + ((v >> 8) & 0xFF)] ^
|
||||||
|
table[0x100 + ((v >> 16) & 0xFF)] ^
|
||||||
|
table[0x000 + ((v >> 24))];
|
||||||
|
}
|
||||||
|
for (; size > 0; size--, p++)
|
||||||
|
v = CRC_UPDATE_BYTE_2(v, *p);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table)
|
||||||
|
{
|
||||||
|
return CrcUpdateT4(v, data, size, table);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,444 @@
|
|||||||
|
/* 7zDec.c -- Decoding from 7z folder
|
||||||
|
2010-03-15 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/* #define _7ZIP_PPMD_SUPPPORT */
|
||||||
|
|
||||||
|
#include "7z.h"
|
||||||
|
|
||||||
|
#include "Bcj2.h"
|
||||||
|
#include "Bra.h"
|
||||||
|
#include "CpuArch.h"
|
||||||
|
#include "LzmaDec.h"
|
||||||
|
#include "Lzma2Dec.h"
|
||||||
|
#ifdef _7ZIP_PPMD_SUPPPORT
|
||||||
|
#include "Ppmd7.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define k_Copy 0
|
||||||
|
#define k_LZMA2 0x21
|
||||||
|
#define k_LZMA 0x30101
|
||||||
|
#define k_BCJ 0x03030103
|
||||||
|
#define k_BCJ2 0x0303011B
|
||||||
|
|
||||||
|
#ifdef _7ZIP_PPMD_SUPPPORT
|
||||||
|
|
||||||
|
#define k_PPMD 0x30401
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
IByteIn p;
|
||||||
|
const Byte *cur;
|
||||||
|
const Byte *end;
|
||||||
|
const Byte *begin;
|
||||||
|
UInt64 processed;
|
||||||
|
Bool extra;
|
||||||
|
SRes res;
|
||||||
|
ILookInStream *inStream;
|
||||||
|
} CByteInToLook;
|
||||||
|
|
||||||
|
static Byte ReadByte(void *pp)
|
||||||
|
{
|
||||||
|
CByteInToLook *p = (CByteInToLook *)pp;
|
||||||
|
if (p->cur != p->end)
|
||||||
|
return *p->cur++;
|
||||||
|
if (p->res == SZ_OK)
|
||||||
|
{
|
||||||
|
size_t size = p->cur - p->begin;
|
||||||
|
p->processed += size;
|
||||||
|
p->res = p->inStream->Skip(p->inStream, size);
|
||||||
|
size = (1 << 25);
|
||||||
|
p->res = p->inStream->Look(p->inStream, (const void **)&p->begin, &size);
|
||||||
|
p->cur = p->begin;
|
||||||
|
p->end = p->begin + size;
|
||||||
|
if (size != 0)
|
||||||
|
return *p->cur++;;
|
||||||
|
}
|
||||||
|
p->extra = True;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SRes SzDecodePpmd(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream,
|
||||||
|
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
|
||||||
|
{
|
||||||
|
CPpmd7 ppmd;
|
||||||
|
CByteInToLook s;
|
||||||
|
SRes res = SZ_OK;
|
||||||
|
|
||||||
|
s.p.Read = ReadByte;
|
||||||
|
s.inStream = inStream;
|
||||||
|
s.begin = s.end = s.cur = NULL;
|
||||||
|
s.extra = False;
|
||||||
|
s.res = SZ_OK;
|
||||||
|
s.processed = 0;
|
||||||
|
|
||||||
|
if (coder->Props.size != 5)
|
||||||
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
|
|
||||||
|
{
|
||||||
|
unsigned order = coder->Props.data[0];
|
||||||
|
UInt32 memSize = GetUi32(coder->Props.data + 1);
|
||||||
|
if (order < PPMD7_MIN_ORDER ||
|
||||||
|
order > PPMD7_MAX_ORDER ||
|
||||||
|
memSize < PPMD7_MIN_MEM_SIZE ||
|
||||||
|
memSize > PPMD7_MAX_MEM_SIZE)
|
||||||
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
|
Ppmd7_Construct(&ppmd);
|
||||||
|
if (!Ppmd7_Alloc(&ppmd, memSize, allocMain))
|
||||||
|
return SZ_ERROR_MEM;
|
||||||
|
Ppmd7_Init(&ppmd, order);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
CPpmd7z_RangeDec rc;
|
||||||
|
Ppmd7z_RangeDec_CreateVTable(&rc);
|
||||||
|
rc.Stream = &s.p;
|
||||||
|
if (!Ppmd7z_RangeDec_Init(&rc))
|
||||||
|
res = SZ_ERROR_DATA;
|
||||||
|
else if (s.extra)
|
||||||
|
res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SizeT i;
|
||||||
|
for (i = 0; i < outSize; i++)
|
||||||
|
{
|
||||||
|
int sym = Ppmd7_DecodeSymbol(&ppmd, &rc.p);
|
||||||
|
if (s.extra || sym < 0)
|
||||||
|
break;
|
||||||
|
outBuffer[i] = (Byte)sym;
|
||||||
|
}
|
||||||
|
if (i != outSize)
|
||||||
|
res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA);
|
||||||
|
else if (s.processed + (s.cur - s.begin) != inSize || !Ppmd7z_RangeDec_IsFinishedOK(&rc))
|
||||||
|
res = SZ_ERROR_DATA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ppmd7_Free(&ppmd, allocMain);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static SRes SzDecodeLzma(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream,
|
||||||
|
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
|
||||||
|
{
|
||||||
|
CLzmaDec state;
|
||||||
|
SRes res = SZ_OK;
|
||||||
|
|
||||||
|
LzmaDec_Construct(&state);
|
||||||
|
RINOK(LzmaDec_AllocateProbs(&state, coder->Props.data, (unsigned)coder->Props.size, allocMain));
|
||||||
|
state.dic = outBuffer;
|
||||||
|
state.dicBufSize = outSize;
|
||||||
|
LzmaDec_Init(&state);
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
Byte *inBuf = NULL;
|
||||||
|
size_t lookahead = (1 << 18);
|
||||||
|
if (lookahead > inSize)
|
||||||
|
lookahead = (size_t)inSize;
|
||||||
|
res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead);
|
||||||
|
if (res != SZ_OK)
|
||||||
|
break;
|
||||||
|
|
||||||
|
{
|
||||||
|
SizeT inProcessed = (SizeT)lookahead, dicPos = state.dicPos;
|
||||||
|
ELzmaStatus status;
|
||||||
|
res = LzmaDec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status);
|
||||||
|
lookahead -= inProcessed;
|
||||||
|
inSize -= inProcessed;
|
||||||
|
if (res != SZ_OK)
|
||||||
|
break;
|
||||||
|
if (state.dicPos == state.dicBufSize || (inProcessed == 0 && dicPos == state.dicPos))
|
||||||
|
{
|
||||||
|
if (state.dicBufSize != outSize || lookahead != 0 ||
|
||||||
|
(status != LZMA_STATUS_FINISHED_WITH_MARK &&
|
||||||
|
status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK))
|
||||||
|
res = SZ_ERROR_DATA;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
res = inStream->Skip((void *)inStream, inProcessed);
|
||||||
|
if (res != SZ_OK)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LzmaDec_FreeProbs(&state, allocMain);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SRes SzDecodeLzma2(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream,
|
||||||
|
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
|
||||||
|
{
|
||||||
|
CLzma2Dec state;
|
||||||
|
SRes res = SZ_OK;
|
||||||
|
|
||||||
|
Lzma2Dec_Construct(&state);
|
||||||
|
if (coder->Props.size != 1)
|
||||||
|
return SZ_ERROR_DATA;
|
||||||
|
RINOK(Lzma2Dec_AllocateProbs(&state, coder->Props.data[0], allocMain));
|
||||||
|
state.decoder.dic = outBuffer;
|
||||||
|
state.decoder.dicBufSize = outSize;
|
||||||
|
Lzma2Dec_Init(&state);
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
Byte *inBuf = NULL;
|
||||||
|
size_t lookahead = (1 << 18);
|
||||||
|
if (lookahead > inSize)
|
||||||
|
lookahead = (size_t)inSize;
|
||||||
|
res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead);
|
||||||
|
if (res != SZ_OK)
|
||||||
|
break;
|
||||||
|
|
||||||
|
{
|
||||||
|
SizeT inProcessed = (SizeT)lookahead, dicPos = state.decoder.dicPos;
|
||||||
|
ELzmaStatus status;
|
||||||
|
res = Lzma2Dec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status);
|
||||||
|
lookahead -= inProcessed;
|
||||||
|
inSize -= inProcessed;
|
||||||
|
if (res != SZ_OK)
|
||||||
|
break;
|
||||||
|
if (state.decoder.dicPos == state.decoder.dicBufSize || (inProcessed == 0 && dicPos == state.decoder.dicPos))
|
||||||
|
{
|
||||||
|
if (state.decoder.dicBufSize != outSize || lookahead != 0 ||
|
||||||
|
(status != LZMA_STATUS_FINISHED_WITH_MARK))
|
||||||
|
res = SZ_ERROR_DATA;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
res = inStream->Skip((void *)inStream, inProcessed);
|
||||||
|
if (res != SZ_OK)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Lzma2Dec_FreeProbs(&state, allocMain);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer)
|
||||||
|
{
|
||||||
|
while (inSize > 0)
|
||||||
|
{
|
||||||
|
void *inBuf;
|
||||||
|
size_t curSize = (1 << 18);
|
||||||
|
if (curSize > inSize)
|
||||||
|
curSize = (size_t)inSize;
|
||||||
|
RINOK(inStream->Look((void *)inStream, (const void **)&inBuf, &curSize));
|
||||||
|
if (curSize == 0)
|
||||||
|
return SZ_ERROR_INPUT_EOF;
|
||||||
|
memcpy(outBuffer, inBuf, curSize);
|
||||||
|
outBuffer += curSize;
|
||||||
|
inSize -= curSize;
|
||||||
|
RINOK(inStream->Skip((void *)inStream, curSize));
|
||||||
|
}
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Bool IS_MAIN_METHOD(UInt32 m)
|
||||||
|
{
|
||||||
|
switch(m)
|
||||||
|
{
|
||||||
|
case k_Copy:
|
||||||
|
case k_LZMA:
|
||||||
|
case k_LZMA2:
|
||||||
|
#ifdef _7ZIP_PPMD_SUPPPORT
|
||||||
|
case k_PPMD:
|
||||||
|
#endif
|
||||||
|
return True;
|
||||||
|
}
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Bool IS_SUPPORTED_CODER(const CSzCoderInfo *c)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
c->NumInStreams == 1 &&
|
||||||
|
c->NumOutStreams == 1 &&
|
||||||
|
c->MethodID <= (UInt32)0xFFFFFFFF &&
|
||||||
|
IS_MAIN_METHOD((UInt32)c->MethodID);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define IS_BCJ(c) ((c)->MethodID == k_BCJ && (c)->NumInStreams == 1 && (c)->NumOutStreams == 1)
|
||||||
|
#define IS_BCJ2(c) ((c)->MethodID == k_BCJ2 && (c)->NumInStreams == 4 && (c)->NumOutStreams == 1)
|
||||||
|
|
||||||
|
static SRes CheckSupportedFolder(const CSzFolder *f)
|
||||||
|
{
|
||||||
|
if (f->NumCoders < 1 || f->NumCoders > 4)
|
||||||
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
|
if (!IS_SUPPORTED_CODER(&f->Coders[0]))
|
||||||
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
|
if (f->NumCoders == 1)
|
||||||
|
{
|
||||||
|
if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBindPairs != 0)
|
||||||
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
if (f->NumCoders == 2)
|
||||||
|
{
|
||||||
|
if (!IS_BCJ(&f->Coders[1]) ||
|
||||||
|
f->NumPackStreams != 1 || f->PackStreams[0] != 0 ||
|
||||||
|
f->NumBindPairs != 1 ||
|
||||||
|
f->BindPairs[0].InIndex != 1 || f->BindPairs[0].OutIndex != 0)
|
||||||
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
if (f->NumCoders == 4)
|
||||||
|
{
|
||||||
|
if (!IS_SUPPORTED_CODER(&f->Coders[1]) ||
|
||||||
|
!IS_SUPPORTED_CODER(&f->Coders[2]) ||
|
||||||
|
!IS_BCJ2(&f->Coders[3]))
|
||||||
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
|
if (f->NumPackStreams != 4 ||
|
||||||
|
f->PackStreams[0] != 2 ||
|
||||||
|
f->PackStreams[1] != 6 ||
|
||||||
|
f->PackStreams[2] != 1 ||
|
||||||
|
f->PackStreams[3] != 0 ||
|
||||||
|
f->NumBindPairs != 3 ||
|
||||||
|
f->BindPairs[0].InIndex != 5 || f->BindPairs[0].OutIndex != 0 ||
|
||||||
|
f->BindPairs[1].InIndex != 4 || f->BindPairs[1].OutIndex != 1 ||
|
||||||
|
f->BindPairs[2].InIndex != 3 || f->BindPairs[2].OutIndex != 2)
|
||||||
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UInt64 GetSum(const UInt64 *values, UInt32 index)
|
||||||
|
{
|
||||||
|
UInt64 sum = 0;
|
||||||
|
UInt32 i;
|
||||||
|
for (i = 0; i < index; i++)
|
||||||
|
sum += values[i];
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes,
|
||||||
|
ILookInStream *inStream, UInt64 startPos,
|
||||||
|
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain,
|
||||||
|
Byte *tempBuf[])
|
||||||
|
{
|
||||||
|
UInt32 ci;
|
||||||
|
SizeT tempSizes[3] = { 0, 0, 0};
|
||||||
|
SizeT tempSize3 = 0;
|
||||||
|
Byte *tempBuf3 = 0;
|
||||||
|
|
||||||
|
RINOK(CheckSupportedFolder(folder));
|
||||||
|
|
||||||
|
for (ci = 0; ci < folder->NumCoders; ci++)
|
||||||
|
{
|
||||||
|
CSzCoderInfo *coder = &folder->Coders[ci];
|
||||||
|
|
||||||
|
if (IS_MAIN_METHOD((UInt32)coder->MethodID))
|
||||||
|
{
|
||||||
|
UInt32 si = 0;
|
||||||
|
UInt64 offset;
|
||||||
|
UInt64 inSize;
|
||||||
|
Byte *outBufCur = outBuffer;
|
||||||
|
SizeT outSizeCur = outSize;
|
||||||
|
if (folder->NumCoders == 4)
|
||||||
|
{
|
||||||
|
UInt32 indices[] = { 3, 2, 0 };
|
||||||
|
UInt64 unpackSize = folder->UnpackSizes[ci];
|
||||||
|
si = indices[ci];
|
||||||
|
if (ci < 2)
|
||||||
|
{
|
||||||
|
Byte *temp;
|
||||||
|
outSizeCur = (SizeT)unpackSize;
|
||||||
|
if (outSizeCur != unpackSize)
|
||||||
|
return SZ_ERROR_MEM;
|
||||||
|
temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur);
|
||||||
|
if (temp == 0 && outSizeCur != 0)
|
||||||
|
return SZ_ERROR_MEM;
|
||||||
|
outBufCur = tempBuf[1 - ci] = temp;
|
||||||
|
tempSizes[1 - ci] = outSizeCur;
|
||||||
|
}
|
||||||
|
else if (ci == 2)
|
||||||
|
{
|
||||||
|
if (unpackSize > outSize) /* check it */
|
||||||
|
return SZ_ERROR_PARAM;
|
||||||
|
tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize);
|
||||||
|
tempSize3 = outSizeCur = (SizeT)unpackSize;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
offset = GetSum(packSizes, si);
|
||||||
|
inSize = packSizes[si];
|
||||||
|
RINOK(LookInStream_SeekTo(inStream, startPos + offset));
|
||||||
|
|
||||||
|
if (coder->MethodID == k_Copy)
|
||||||
|
{
|
||||||
|
if (inSize != outSizeCur) /* check it */
|
||||||
|
return SZ_ERROR_DATA;
|
||||||
|
RINOK(SzDecodeCopy(inSize, inStream, outBufCur));
|
||||||
|
}
|
||||||
|
else if (coder->MethodID == k_LZMA)
|
||||||
|
{
|
||||||
|
RINOK(SzDecodeLzma(coder, inSize, inStream, outBufCur, outSizeCur, allocMain));
|
||||||
|
}
|
||||||
|
else if (coder->MethodID == k_LZMA2)
|
||||||
|
{
|
||||||
|
RINOK(SzDecodeLzma2(coder, inSize, inStream, outBufCur, outSizeCur, allocMain));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef _7ZIP_PPMD_SUPPPORT
|
||||||
|
RINOK(SzDecodePpmd(coder, inSize, inStream, outBufCur, outSizeCur, allocMain));
|
||||||
|
#else
|
||||||
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (coder->MethodID == k_BCJ)
|
||||||
|
{
|
||||||
|
UInt32 state;
|
||||||
|
if (ci != 1)
|
||||||
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
|
x86_Convert_Init(state);
|
||||||
|
x86_Convert(outBuffer, outSize, 0, &state, 0);
|
||||||
|
}
|
||||||
|
else if (coder->MethodID == k_BCJ2)
|
||||||
|
{
|
||||||
|
UInt64 offset = GetSum(packSizes, 1);
|
||||||
|
UInt64 s3Size = packSizes[1];
|
||||||
|
SRes res;
|
||||||
|
if (ci != 3)
|
||||||
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
|
RINOK(LookInStream_SeekTo(inStream, startPos + offset));
|
||||||
|
tempSizes[2] = (SizeT)s3Size;
|
||||||
|
if (tempSizes[2] != s3Size)
|
||||||
|
return SZ_ERROR_MEM;
|
||||||
|
tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]);
|
||||||
|
if (tempBuf[2] == 0 && tempSizes[2] != 0)
|
||||||
|
return SZ_ERROR_MEM;
|
||||||
|
res = SzDecodeCopy(s3Size, inStream, tempBuf[2]);
|
||||||
|
RINOK(res)
|
||||||
|
|
||||||
|
res = Bcj2_Decode(
|
||||||
|
tempBuf3, tempSize3,
|
||||||
|
tempBuf[0], tempSizes[0],
|
||||||
|
tempBuf[1], tempSizes[1],
|
||||||
|
tempBuf[2], tempSizes[2],
|
||||||
|
outBuffer, outSize);
|
||||||
|
RINOK(res)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
SRes SzFolder_Decode(const CSzFolder *folder, const UInt64 *packSizes,
|
||||||
|
ILookInStream *inStream, UInt64 startPos,
|
||||||
|
Byte *outBuffer, size_t outSize, ISzAlloc *allocMain)
|
||||||
|
{
|
||||||
|
Byte *tempBuf[3] = { 0, 0, 0};
|
||||||
|
int i;
|
||||||
|
SRes res = SzFolder_Decode2(folder, packSizes, inStream, startPos,
|
||||||
|
outBuffer, (SizeT)outSize, allocMain, tempBuf);
|
||||||
|
for (i = 0; i < 3; i++)
|
||||||
|
IAlloc_Free(allocMain, tempBuf[i]);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
@@ -0,0 +1,284 @@
|
|||||||
|
/* 7zFile.c -- File IO
|
||||||
|
2009-11-24 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#include "7zFile.h"
|
||||||
|
|
||||||
|
#ifndef USE_WINDOWS_FILE
|
||||||
|
|
||||||
|
#ifndef UNDER_CE
|
||||||
|
#include <errno.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/*
|
||||||
|
ReadFile and WriteFile functions in Windows have BUG:
|
||||||
|
If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1)
|
||||||
|
from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES
|
||||||
|
(Insufficient system resources exist to complete the requested service).
|
||||||
|
Probably in some version of Windows there are problems with other sizes:
|
||||||
|
for 32 MB (maybe also for 16 MB).
|
||||||
|
And message can be "Network connection was lost"
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define kChunkSizeMax (1 << 22)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void File_Construct(CSzFile *p)
|
||||||
|
{
|
||||||
|
#ifdef USE_WINDOWS_FILE
|
||||||
|
p->handle = INVALID_HANDLE_VALUE;
|
||||||
|
#else
|
||||||
|
p->file = NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE)
|
||||||
|
static WRes File_Open(CSzFile *p, const char *name, int writeMode)
|
||||||
|
{
|
||||||
|
#ifdef USE_WINDOWS_FILE
|
||||||
|
p->handle = CreateFileA(name,
|
||||||
|
writeMode ? GENERIC_WRITE : GENERIC_READ,
|
||||||
|
FILE_SHARE_READ, NULL,
|
||||||
|
writeMode ? CREATE_ALWAYS : OPEN_EXISTING,
|
||||||
|
FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError();
|
||||||
|
#else
|
||||||
|
p->file = fopen(name, writeMode ? "wb+" : "rb");
|
||||||
|
return (p->file != 0) ? 0 :
|
||||||
|
#ifdef UNDER_CE
|
||||||
|
2; /* ENOENT */
|
||||||
|
#else
|
||||||
|
errno;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
WRes InFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 0); }
|
||||||
|
WRes OutFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 1); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_WINDOWS_FILE
|
||||||
|
static WRes File_OpenW(CSzFile *p, const WCHAR *name, int writeMode)
|
||||||
|
{
|
||||||
|
p->handle = CreateFileW(name,
|
||||||
|
writeMode ? GENERIC_WRITE : GENERIC_READ,
|
||||||
|
FILE_SHARE_READ, NULL,
|
||||||
|
writeMode ? CREATE_ALWAYS : OPEN_EXISTING,
|
||||||
|
FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError();
|
||||||
|
}
|
||||||
|
WRes InFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 0); }
|
||||||
|
WRes OutFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 1); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
WRes File_Close(CSzFile *p)
|
||||||
|
{
|
||||||
|
#ifdef USE_WINDOWS_FILE
|
||||||
|
if (p->handle != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
if (!CloseHandle(p->handle))
|
||||||
|
return GetLastError();
|
||||||
|
p->handle = INVALID_HANDLE_VALUE;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (p->file != NULL)
|
||||||
|
{
|
||||||
|
int res = fclose(p->file);
|
||||||
|
if (res != 0)
|
||||||
|
return res;
|
||||||
|
p->file = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
WRes File_Read(CSzFile *p, void *data, size_t *size)
|
||||||
|
{
|
||||||
|
size_t originalSize = *size;
|
||||||
|
if (originalSize == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
#ifdef USE_WINDOWS_FILE
|
||||||
|
|
||||||
|
*size = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize;
|
||||||
|
DWORD processed = 0;
|
||||||
|
BOOL res = ReadFile(p->handle, data, curSize, &processed, NULL);
|
||||||
|
data = (void *)((Byte *)data + processed);
|
||||||
|
originalSize -= processed;
|
||||||
|
*size += processed;
|
||||||
|
if (!res)
|
||||||
|
return GetLastError();
|
||||||
|
if (processed == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
while (originalSize > 0);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
*size = fread(data, 1, originalSize, p->file);
|
||||||
|
if (*size == originalSize)
|
||||||
|
return 0;
|
||||||
|
return ferror(p->file);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
WRes File_Write(CSzFile *p, const void *data, size_t *size)
|
||||||
|
{
|
||||||
|
size_t originalSize = *size;
|
||||||
|
if (originalSize == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
#ifdef USE_WINDOWS_FILE
|
||||||
|
|
||||||
|
*size = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize;
|
||||||
|
DWORD processed = 0;
|
||||||
|
BOOL res = WriteFile(p->handle, data, curSize, &processed, NULL);
|
||||||
|
data = (void *)((Byte *)data + processed);
|
||||||
|
originalSize -= processed;
|
||||||
|
*size += processed;
|
||||||
|
if (!res)
|
||||||
|
return GetLastError();
|
||||||
|
if (processed == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
while (originalSize > 0);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
*size = fwrite(data, 1, originalSize, p->file);
|
||||||
|
if (*size == originalSize)
|
||||||
|
return 0;
|
||||||
|
return ferror(p->file);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin)
|
||||||
|
{
|
||||||
|
#ifdef USE_WINDOWS_FILE
|
||||||
|
|
||||||
|
LARGE_INTEGER value;
|
||||||
|
DWORD moveMethod;
|
||||||
|
value.LowPart = (DWORD)*pos;
|
||||||
|
value.HighPart = (LONG)((UInt64)*pos >> 16 >> 16); /* for case when UInt64 is 32-bit only */
|
||||||
|
switch (origin)
|
||||||
|
{
|
||||||
|
case SZ_SEEK_SET: moveMethod = FILE_BEGIN; break;
|
||||||
|
case SZ_SEEK_CUR: moveMethod = FILE_CURRENT; break;
|
||||||
|
case SZ_SEEK_END: moveMethod = FILE_END; break;
|
||||||
|
default: return ERROR_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
value.LowPart = SetFilePointer(p->handle, value.LowPart, &value.HighPart, moveMethod);
|
||||||
|
if (value.LowPart == 0xFFFFFFFF)
|
||||||
|
{
|
||||||
|
WRes res = GetLastError();
|
||||||
|
if (res != NO_ERROR)
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
*pos = ((Int64)value.HighPart << 32) | value.LowPart;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
int moveMethod;
|
||||||
|
int res;
|
||||||
|
switch (origin)
|
||||||
|
{
|
||||||
|
case SZ_SEEK_SET: moveMethod = SEEK_SET; break;
|
||||||
|
case SZ_SEEK_CUR: moveMethod = SEEK_CUR; break;
|
||||||
|
case SZ_SEEK_END: moveMethod = SEEK_END; break;
|
||||||
|
default: return 1;
|
||||||
|
}
|
||||||
|
res = fseek(p->file, (long)*pos, moveMethod);
|
||||||
|
*pos = ftell(p->file);
|
||||||
|
return res;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
WRes File_GetLength(CSzFile *p, UInt64 *length)
|
||||||
|
{
|
||||||
|
#ifdef USE_WINDOWS_FILE
|
||||||
|
|
||||||
|
DWORD sizeHigh;
|
||||||
|
DWORD sizeLow = GetFileSize(p->handle, &sizeHigh);
|
||||||
|
if (sizeLow == 0xFFFFFFFF)
|
||||||
|
{
|
||||||
|
DWORD res = GetLastError();
|
||||||
|
if (res != NO_ERROR)
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
*length = (((UInt64)sizeHigh) << 32) + sizeLow;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
long pos = ftell(p->file);
|
||||||
|
int res = fseek(p->file, 0, SEEK_END);
|
||||||
|
*length = ftell(p->file);
|
||||||
|
fseek(p->file, pos, SEEK_SET);
|
||||||
|
return res;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- FileSeqInStream ---------- */
|
||||||
|
|
||||||
|
static SRes FileSeqInStream_Read(void *pp, void *buf, size_t *size)
|
||||||
|
{
|
||||||
|
CFileSeqInStream *p = (CFileSeqInStream *)pp;
|
||||||
|
return File_Read(&p->file, buf, size) == 0 ? SZ_OK : SZ_ERROR_READ;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileSeqInStream_CreateVTable(CFileSeqInStream *p)
|
||||||
|
{
|
||||||
|
p->s.Read = FileSeqInStream_Read;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- FileInStream ---------- */
|
||||||
|
|
||||||
|
static SRes FileInStream_Read(void *pp, void *buf, size_t *size)
|
||||||
|
{
|
||||||
|
CFileInStream *p = (CFileInStream *)pp;
|
||||||
|
return (File_Read(&p->file, buf, size) == 0) ? SZ_OK : SZ_ERROR_READ;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SRes FileInStream_Seek(void *pp, Int64 *pos, ESzSeek origin)
|
||||||
|
{
|
||||||
|
CFileInStream *p = (CFileInStream *)pp;
|
||||||
|
return File_Seek(&p->file, pos, origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileInStream_CreateVTable(CFileInStream *p)
|
||||||
|
{
|
||||||
|
p->s.Read = FileInStream_Read;
|
||||||
|
p->s.Seek = FileInStream_Seek;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- FileOutStream ---------- */
|
||||||
|
|
||||||
|
static size_t FileOutStream_Write(void *pp, const void *data, size_t size)
|
||||||
|
{
|
||||||
|
CFileOutStream *p = (CFileOutStream *)pp;
|
||||||
|
File_Write(&p->file, data, &size);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileOutStream_CreateVTable(CFileOutStream *p)
|
||||||
|
{
|
||||||
|
p->s.Write = FileOutStream_Write;
|
||||||
|
}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
/* 7zFile.h -- File IO
|
||||||
|
2009-11-24 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#ifndef __7Z_FILE_H
|
||||||
|
#define __7Z_FILE_H
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define USE_WINDOWS_FILE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_WINDOWS_FILE
|
||||||
|
#include <windows.h>
|
||||||
|
#else
|
||||||
|
#include <stdio.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "Types.h"
|
||||||
|
|
||||||
|
EXTERN_C_BEGIN
|
||||||
|
|
||||||
|
/* ---------- File ---------- */
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
#ifdef USE_WINDOWS_FILE
|
||||||
|
HANDLE handle;
|
||||||
|
#else
|
||||||
|
FILE *file;
|
||||||
|
#endif
|
||||||
|
} CSzFile;
|
||||||
|
|
||||||
|
void File_Construct(CSzFile *p);
|
||||||
|
#if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE)
|
||||||
|
WRes InFile_Open(CSzFile *p, const char *name);
|
||||||
|
WRes OutFile_Open(CSzFile *p, const char *name);
|
||||||
|
#endif
|
||||||
|
#ifdef USE_WINDOWS_FILE
|
||||||
|
WRes InFile_OpenW(CSzFile *p, const WCHAR *name);
|
||||||
|
WRes OutFile_OpenW(CSzFile *p, const WCHAR *name);
|
||||||
|
#endif
|
||||||
|
WRes File_Close(CSzFile *p);
|
||||||
|
|
||||||
|
/* reads max(*size, remain file's size) bytes */
|
||||||
|
WRes File_Read(CSzFile *p, void *data, size_t *size);
|
||||||
|
|
||||||
|
/* writes *size bytes */
|
||||||
|
WRes File_Write(CSzFile *p, const void *data, size_t *size);
|
||||||
|
|
||||||
|
WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin);
|
||||||
|
WRes File_GetLength(CSzFile *p, UInt64 *length);
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- FileInStream ---------- */
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ISeqInStream s;
|
||||||
|
CSzFile file;
|
||||||
|
} CFileSeqInStream;
|
||||||
|
|
||||||
|
void FileSeqInStream_CreateVTable(CFileSeqInStream *p);
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ISeekInStream s;
|
||||||
|
CSzFile file;
|
||||||
|
} CFileInStream;
|
||||||
|
|
||||||
|
void FileInStream_CreateVTable(CFileInStream *p);
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ISeqOutStream s;
|
||||||
|
CSzFile file;
|
||||||
|
} CFileOutStream;
|
||||||
|
|
||||||
|
void FileOutStream_CreateVTable(CFileOutStream *p);
|
||||||
|
|
||||||
|
EXTERN_C_END
|
||||||
|
|
||||||
|
#endif
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,169 @@
|
|||||||
|
/* 7zStream.c -- 7z Stream functions
|
||||||
|
2010-03-11 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "Types.h"
|
||||||
|
|
||||||
|
SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType)
|
||||||
|
{
|
||||||
|
while (size != 0)
|
||||||
|
{
|
||||||
|
size_t processed = size;
|
||||||
|
RINOK(stream->Read(stream, buf, &processed));
|
||||||
|
if (processed == 0)
|
||||||
|
return errorType;
|
||||||
|
buf = (void *)((Byte *)buf + processed);
|
||||||
|
size -= processed;
|
||||||
|
}
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size)
|
||||||
|
{
|
||||||
|
return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
|
||||||
|
}
|
||||||
|
|
||||||
|
SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf)
|
||||||
|
{
|
||||||
|
size_t processed = 1;
|
||||||
|
RINOK(stream->Read(stream, buf, &processed));
|
||||||
|
return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset)
|
||||||
|
{
|
||||||
|
Int64 t = offset;
|
||||||
|
return stream->Seek(stream, &t, SZ_SEEK_SET);
|
||||||
|
}
|
||||||
|
|
||||||
|
SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size)
|
||||||
|
{
|
||||||
|
const void *lookBuf;
|
||||||
|
if (*size == 0)
|
||||||
|
return SZ_OK;
|
||||||
|
RINOK(stream->Look(stream, &lookBuf, size));
|
||||||
|
memcpy(buf, lookBuf, *size);
|
||||||
|
return stream->Skip(stream, *size);
|
||||||
|
}
|
||||||
|
|
||||||
|
SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType)
|
||||||
|
{
|
||||||
|
while (size != 0)
|
||||||
|
{
|
||||||
|
size_t processed = size;
|
||||||
|
RINOK(stream->Read(stream, buf, &processed));
|
||||||
|
if (processed == 0)
|
||||||
|
return errorType;
|
||||||
|
buf = (void *)((Byte *)buf + processed);
|
||||||
|
size -= processed;
|
||||||
|
}
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size)
|
||||||
|
{
|
||||||
|
return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
|
||||||
|
}
|
||||||
|
|
||||||
|
static SRes LookToRead_Look_Lookahead(void *pp, const void **buf, size_t *size)
|
||||||
|
{
|
||||||
|
SRes res = SZ_OK;
|
||||||
|
CLookToRead *p = (CLookToRead *)pp;
|
||||||
|
size_t size2 = p->size - p->pos;
|
||||||
|
if (size2 == 0 && *size > 0)
|
||||||
|
{
|
||||||
|
p->pos = 0;
|
||||||
|
size2 = LookToRead_BUF_SIZE;
|
||||||
|
res = p->realStream->Read(p->realStream, p->buf, &size2);
|
||||||
|
p->size = size2;
|
||||||
|
}
|
||||||
|
if (size2 < *size)
|
||||||
|
*size = size2;
|
||||||
|
*buf = p->buf + p->pos;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SRes LookToRead_Look_Exact(void *pp, const void **buf, size_t *size)
|
||||||
|
{
|
||||||
|
SRes res = SZ_OK;
|
||||||
|
CLookToRead *p = (CLookToRead *)pp;
|
||||||
|
size_t size2 = p->size - p->pos;
|
||||||
|
if (size2 == 0 && *size > 0)
|
||||||
|
{
|
||||||
|
p->pos = 0;
|
||||||
|
if (*size > LookToRead_BUF_SIZE)
|
||||||
|
*size = LookToRead_BUF_SIZE;
|
||||||
|
res = p->realStream->Read(p->realStream, p->buf, size);
|
||||||
|
size2 = p->size = *size;
|
||||||
|
}
|
||||||
|
if (size2 < *size)
|
||||||
|
*size = size2;
|
||||||
|
*buf = p->buf + p->pos;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SRes LookToRead_Skip(void *pp, size_t offset)
|
||||||
|
{
|
||||||
|
CLookToRead *p = (CLookToRead *)pp;
|
||||||
|
p->pos += offset;
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SRes LookToRead_Read(void *pp, void *buf, size_t *size)
|
||||||
|
{
|
||||||
|
CLookToRead *p = (CLookToRead *)pp;
|
||||||
|
size_t rem = p->size - p->pos;
|
||||||
|
if (rem == 0)
|
||||||
|
return p->realStream->Read(p->realStream, buf, size);
|
||||||
|
if (rem > *size)
|
||||||
|
rem = *size;
|
||||||
|
memcpy(buf, p->buf + p->pos, rem);
|
||||||
|
p->pos += rem;
|
||||||
|
*size = rem;
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SRes LookToRead_Seek(void *pp, Int64 *pos, ESzSeek origin)
|
||||||
|
{
|
||||||
|
CLookToRead *p = (CLookToRead *)pp;
|
||||||
|
p->pos = p->size = 0;
|
||||||
|
return p->realStream->Seek(p->realStream, pos, origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LookToRead_CreateVTable(CLookToRead *p, int lookahead)
|
||||||
|
{
|
||||||
|
p->s.Look = lookahead ?
|
||||||
|
LookToRead_Look_Lookahead :
|
||||||
|
LookToRead_Look_Exact;
|
||||||
|
p->s.Skip = LookToRead_Skip;
|
||||||
|
p->s.Read = LookToRead_Read;
|
||||||
|
p->s.Seek = LookToRead_Seek;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LookToRead_Init(CLookToRead *p)
|
||||||
|
{
|
||||||
|
p->pos = p->size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SRes SecToLook_Read(void *pp, void *buf, size_t *size)
|
||||||
|
{
|
||||||
|
CSecToLook *p = (CSecToLook *)pp;
|
||||||
|
return LookInStream_LookRead(p->realStream, buf, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SecToLook_CreateVTable(CSecToLook *p)
|
||||||
|
{
|
||||||
|
p->s.Read = SecToLook_Read;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SRes SecToRead_Read(void *pp, void *buf, size_t *size)
|
||||||
|
{
|
||||||
|
CSecToRead *p = (CSecToRead *)pp;
|
||||||
|
return p->realStream->Read(p->realStream, buf, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SecToRead_CreateVTable(CSecToRead *p)
|
||||||
|
{
|
||||||
|
p->s.Read = SecToRead_Read;
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
#define MY_VER_MAJOR 9
|
||||||
|
#define MY_VER_MINOR 12
|
||||||
|
#define MY_VER_BUILD 0
|
||||||
|
#define MY_VERSION "9.12 beta"
|
||||||
|
#define MY_DATE "2010-03-24"
|
||||||
|
#define MY_COPYRIGHT ": Igor Pavlov : Public domain"
|
||||||
|
#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE
|
||||||
@@ -0,0 +1,127 @@
|
|||||||
|
/* Alloc.c -- Memory allocation functions
|
||||||
|
2008-09-24
|
||||||
|
Igor Pavlov
|
||||||
|
Public domain */
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "Alloc.h"
|
||||||
|
|
||||||
|
/* #define _SZ_ALLOC_DEBUG */
|
||||||
|
|
||||||
|
/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */
|
||||||
|
#ifdef _SZ_ALLOC_DEBUG
|
||||||
|
#include <stdio.h>
|
||||||
|
int g_allocCount = 0;
|
||||||
|
int g_allocCountMid = 0;
|
||||||
|
int g_allocCountBig = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void *MyAlloc(size_t size)
|
||||||
|
{
|
||||||
|
if (size == 0)
|
||||||
|
return 0;
|
||||||
|
#ifdef _SZ_ALLOC_DEBUG
|
||||||
|
{
|
||||||
|
void *p = malloc(size);
|
||||||
|
fprintf(stderr, "\nAlloc %10d bytes, count = %10d, addr = %8X", size, g_allocCount++, (unsigned)p);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
return malloc(size);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyFree(void *address)
|
||||||
|
{
|
||||||
|
#ifdef _SZ_ALLOC_DEBUG
|
||||||
|
if (address != 0)
|
||||||
|
fprintf(stderr, "\nFree; count = %10d, addr = %8X", --g_allocCount, (unsigned)address);
|
||||||
|
#endif
|
||||||
|
free(address);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
void *MidAlloc(size_t size)
|
||||||
|
{
|
||||||
|
if (size == 0)
|
||||||
|
return 0;
|
||||||
|
#ifdef _SZ_ALLOC_DEBUG
|
||||||
|
fprintf(stderr, "\nAlloc_Mid %10d bytes; count = %10d", size, g_allocCountMid++);
|
||||||
|
#endif
|
||||||
|
return VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MidFree(void *address)
|
||||||
|
{
|
||||||
|
#ifdef _SZ_ALLOC_DEBUG
|
||||||
|
if (address != 0)
|
||||||
|
fprintf(stderr, "\nFree_Mid; count = %10d", --g_allocCountMid);
|
||||||
|
#endif
|
||||||
|
if (address == 0)
|
||||||
|
return;
|
||||||
|
VirtualFree(address, 0, MEM_RELEASE);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef MEM_LARGE_PAGES
|
||||||
|
#undef _7ZIP_LARGE_PAGES
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _7ZIP_LARGE_PAGES
|
||||||
|
SIZE_T g_LargePageSize = 0;
|
||||||
|
typedef SIZE_T (WINAPI *GetLargePageMinimumP)();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void SetLargePageSize()
|
||||||
|
{
|
||||||
|
#ifdef _7ZIP_LARGE_PAGES
|
||||||
|
SIZE_T size = 0;
|
||||||
|
GetLargePageMinimumP largePageMinimum = (GetLargePageMinimumP)
|
||||||
|
GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetLargePageMinimum");
|
||||||
|
if (largePageMinimum == 0)
|
||||||
|
return;
|
||||||
|
size = largePageMinimum();
|
||||||
|
if (size == 0 || (size & (size - 1)) != 0)
|
||||||
|
return;
|
||||||
|
g_LargePageSize = size;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void *BigAlloc(size_t size)
|
||||||
|
{
|
||||||
|
if (size == 0)
|
||||||
|
return 0;
|
||||||
|
#ifdef _SZ_ALLOC_DEBUG
|
||||||
|
fprintf(stderr, "\nAlloc_Big %10d bytes; count = %10d", size, g_allocCountBig++);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _7ZIP_LARGE_PAGES
|
||||||
|
if (g_LargePageSize != 0 && g_LargePageSize <= (1 << 30) && size >= (1 << 18))
|
||||||
|
{
|
||||||
|
void *res = VirtualAlloc(0, (size + g_LargePageSize - 1) & (~(g_LargePageSize - 1)),
|
||||||
|
MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE);
|
||||||
|
if (res != 0)
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BigFree(void *address)
|
||||||
|
{
|
||||||
|
#ifdef _SZ_ALLOC_DEBUG
|
||||||
|
if (address != 0)
|
||||||
|
fprintf(stderr, "\nFree_Big; count = %10d", --g_allocCountBig);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (address == 0)
|
||||||
|
return;
|
||||||
|
VirtualFree(address, 0, MEM_RELEASE);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/* Alloc.h -- Memory allocation functions
|
||||||
|
2009-02-07 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#ifndef __COMMON_ALLOC_H
|
||||||
|
#define __COMMON_ALLOC_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void *MyAlloc(size_t size);
|
||||||
|
void MyFree(void *address);
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
void SetLargePageSize();
|
||||||
|
|
||||||
|
void *MidAlloc(size_t size);
|
||||||
|
void MidFree(void *address);
|
||||||
|
void *BigAlloc(size_t size);
|
||||||
|
void BigFree(void *address);
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define MidAlloc(size) MyAlloc(size)
|
||||||
|
#define MidFree(address) MyFree(address)
|
||||||
|
#define BigAlloc(size) MyAlloc(size)
|
||||||
|
#define BigFree(address) MyFree(address)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,132 @@
|
|||||||
|
/* Bcj2.c -- Converter for x86 code (BCJ2)
|
||||||
|
2008-10-04 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#include "Bcj2.h"
|
||||||
|
|
||||||
|
#ifdef _LZMA_PROB32
|
||||||
|
#define CProb UInt32
|
||||||
|
#else
|
||||||
|
#define CProb UInt16
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define IsJcc(b0, b1) ((b0) == 0x0F && ((b1) & 0xF0) == 0x80)
|
||||||
|
#define IsJ(b0, b1) ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1))
|
||||||
|
|
||||||
|
#define kNumTopBits 24
|
||||||
|
#define kTopValue ((UInt32)1 << kNumTopBits)
|
||||||
|
|
||||||
|
#define kNumBitModelTotalBits 11
|
||||||
|
#define kBitModelTotal (1 << kNumBitModelTotalBits)
|
||||||
|
#define kNumMoveBits 5
|
||||||
|
|
||||||
|
#define RC_READ_BYTE (*buffer++)
|
||||||
|
#define RC_TEST { if (buffer == bufferLim) return SZ_ERROR_DATA; }
|
||||||
|
#define RC_INIT2 code = 0; range = 0xFFFFFFFF; \
|
||||||
|
{ int i; for (i = 0; i < 5; i++) { RC_TEST; code = (code << 8) | RC_READ_BYTE; }}
|
||||||
|
|
||||||
|
#define NORMALIZE if (range < kTopValue) { RC_TEST; range <<= 8; code = (code << 8) | RC_READ_BYTE; }
|
||||||
|
|
||||||
|
#define IF_BIT_0(p) ttt = *(p); bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
|
||||||
|
#define UPDATE_0(p) range = bound; *(p) = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); NORMALIZE;
|
||||||
|
#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CProb)(ttt - (ttt >> kNumMoveBits)); NORMALIZE;
|
||||||
|
|
||||||
|
int Bcj2_Decode(
|
||||||
|
const Byte *buf0, SizeT size0,
|
||||||
|
const Byte *buf1, SizeT size1,
|
||||||
|
const Byte *buf2, SizeT size2,
|
||||||
|
const Byte *buf3, SizeT size3,
|
||||||
|
Byte *outBuf, SizeT outSize)
|
||||||
|
{
|
||||||
|
CProb p[256 + 2];
|
||||||
|
SizeT inPos = 0, outPos = 0;
|
||||||
|
|
||||||
|
const Byte *buffer, *bufferLim;
|
||||||
|
UInt32 range, code;
|
||||||
|
Byte prevByte = 0;
|
||||||
|
|
||||||
|
unsigned int i;
|
||||||
|
for (i = 0; i < sizeof(p) / sizeof(p[0]); i++)
|
||||||
|
p[i] = kBitModelTotal >> 1;
|
||||||
|
|
||||||
|
buffer = buf3;
|
||||||
|
bufferLim = buffer + size3;
|
||||||
|
RC_INIT2
|
||||||
|
|
||||||
|
if (outSize == 0)
|
||||||
|
return SZ_OK;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
Byte b;
|
||||||
|
CProb *prob;
|
||||||
|
UInt32 bound;
|
||||||
|
UInt32 ttt;
|
||||||
|
|
||||||
|
SizeT limit = size0 - inPos;
|
||||||
|
if (outSize - outPos < limit)
|
||||||
|
limit = outSize - outPos;
|
||||||
|
while (limit != 0)
|
||||||
|
{
|
||||||
|
Byte b = buf0[inPos];
|
||||||
|
outBuf[outPos++] = b;
|
||||||
|
if (IsJ(prevByte, b))
|
||||||
|
break;
|
||||||
|
inPos++;
|
||||||
|
prevByte = b;
|
||||||
|
limit--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (limit == 0 || outPos == outSize)
|
||||||
|
break;
|
||||||
|
|
||||||
|
b = buf0[inPos++];
|
||||||
|
|
||||||
|
if (b == 0xE8)
|
||||||
|
prob = p + prevByte;
|
||||||
|
else if (b == 0xE9)
|
||||||
|
prob = p + 256;
|
||||||
|
else
|
||||||
|
prob = p + 257;
|
||||||
|
|
||||||
|
IF_BIT_0(prob)
|
||||||
|
{
|
||||||
|
UPDATE_0(prob)
|
||||||
|
prevByte = b;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UInt32 dest;
|
||||||
|
const Byte *v;
|
||||||
|
UPDATE_1(prob)
|
||||||
|
if (b == 0xE8)
|
||||||
|
{
|
||||||
|
v = buf1;
|
||||||
|
if (size1 < 4)
|
||||||
|
return SZ_ERROR_DATA;
|
||||||
|
buf1 += 4;
|
||||||
|
size1 -= 4;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
v = buf2;
|
||||||
|
if (size2 < 4)
|
||||||
|
return SZ_ERROR_DATA;
|
||||||
|
buf2 += 4;
|
||||||
|
size2 -= 4;
|
||||||
|
}
|
||||||
|
dest = (((UInt32)v[0] << 24) | ((UInt32)v[1] << 16) |
|
||||||
|
((UInt32)v[2] << 8) | ((UInt32)v[3])) - ((UInt32)outPos + 4);
|
||||||
|
outBuf[outPos++] = (Byte)dest;
|
||||||
|
if (outPos == outSize)
|
||||||
|
break;
|
||||||
|
outBuf[outPos++] = (Byte)(dest >> 8);
|
||||||
|
if (outPos == outSize)
|
||||||
|
break;
|
||||||
|
outBuf[outPos++] = (Byte)(dest >> 16);
|
||||||
|
if (outPos == outSize)
|
||||||
|
break;
|
||||||
|
outBuf[outPos++] = prevByte = (Byte)(dest >> 24);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (outPos == outSize) ? SZ_OK : SZ_ERROR_DATA;
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/* Bcj2.h -- Converter for x86 code (BCJ2)
|
||||||
|
2009-02-07 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#ifndef __BCJ2_H
|
||||||
|
#define __BCJ2_H
|
||||||
|
|
||||||
|
#include "Types.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
Conditions:
|
||||||
|
outSize <= FullOutputSize,
|
||||||
|
where FullOutputSize is full size of output stream of x86_2 filter.
|
||||||
|
|
||||||
|
If buf0 overlaps outBuf, there are two required conditions:
|
||||||
|
1) (buf0 >= outBuf)
|
||||||
|
2) (buf0 + size0 >= outBuf + FullOutputSize).
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
SZ_OK
|
||||||
|
SZ_ERROR_DATA - Data error
|
||||||
|
*/
|
||||||
|
|
||||||
|
int Bcj2_Decode(
|
||||||
|
const Byte *buf0, SizeT size0,
|
||||||
|
const Byte *buf1, SizeT size1,
|
||||||
|
const Byte *buf2, SizeT size2,
|
||||||
|
const Byte *buf3, SizeT size3,
|
||||||
|
Byte *outBuf, SizeT outSize);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,133 @@
|
|||||||
|
/* Bra.c -- Converters for RISC code
|
||||||
|
2008-10-04 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#include "Bra.h"
|
||||||
|
|
||||||
|
SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
||||||
|
{
|
||||||
|
SizeT i;
|
||||||
|
if (size < 4)
|
||||||
|
return 0;
|
||||||
|
size -= 4;
|
||||||
|
ip += 8;
|
||||||
|
for (i = 0; i <= size; i += 4)
|
||||||
|
{
|
||||||
|
if (data[i + 3] == 0xEB)
|
||||||
|
{
|
||||||
|
UInt32 dest;
|
||||||
|
UInt32 src = ((UInt32)data[i + 2] << 16) | ((UInt32)data[i + 1] << 8) | (data[i + 0]);
|
||||||
|
src <<= 2;
|
||||||
|
if (encoding)
|
||||||
|
dest = ip + (UInt32)i + src;
|
||||||
|
else
|
||||||
|
dest = src - (ip + (UInt32)i);
|
||||||
|
dest >>= 2;
|
||||||
|
data[i + 2] = (Byte)(dest >> 16);
|
||||||
|
data[i + 1] = (Byte)(dest >> 8);
|
||||||
|
data[i + 0] = (Byte)dest;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
||||||
|
{
|
||||||
|
SizeT i;
|
||||||
|
if (size < 4)
|
||||||
|
return 0;
|
||||||
|
size -= 4;
|
||||||
|
ip += 4;
|
||||||
|
for (i = 0; i <= size; i += 2)
|
||||||
|
{
|
||||||
|
if ((data[i + 1] & 0xF8) == 0xF0 &&
|
||||||
|
(data[i + 3] & 0xF8) == 0xF8)
|
||||||
|
{
|
||||||
|
UInt32 dest;
|
||||||
|
UInt32 src =
|
||||||
|
(((UInt32)data[i + 1] & 0x7) << 19) |
|
||||||
|
((UInt32)data[i + 0] << 11) |
|
||||||
|
(((UInt32)data[i + 3] & 0x7) << 8) |
|
||||||
|
(data[i + 2]);
|
||||||
|
|
||||||
|
src <<= 1;
|
||||||
|
if (encoding)
|
||||||
|
dest = ip + (UInt32)i + src;
|
||||||
|
else
|
||||||
|
dest = src - (ip + (UInt32)i);
|
||||||
|
dest >>= 1;
|
||||||
|
|
||||||
|
data[i + 1] = (Byte)(0xF0 | ((dest >> 19) & 0x7));
|
||||||
|
data[i + 0] = (Byte)(dest >> 11);
|
||||||
|
data[i + 3] = (Byte)(0xF8 | ((dest >> 8) & 0x7));
|
||||||
|
data[i + 2] = (Byte)dest;
|
||||||
|
i += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
||||||
|
{
|
||||||
|
SizeT i;
|
||||||
|
if (size < 4)
|
||||||
|
return 0;
|
||||||
|
size -= 4;
|
||||||
|
for (i = 0; i <= size; i += 4)
|
||||||
|
{
|
||||||
|
if ((data[i] >> 2) == 0x12 && (data[i + 3] & 3) == 1)
|
||||||
|
{
|
||||||
|
UInt32 src = ((UInt32)(data[i + 0] & 3) << 24) |
|
||||||
|
((UInt32)data[i + 1] << 16) |
|
||||||
|
((UInt32)data[i + 2] << 8) |
|
||||||
|
((UInt32)data[i + 3] & (~3));
|
||||||
|
|
||||||
|
UInt32 dest;
|
||||||
|
if (encoding)
|
||||||
|
dest = ip + (UInt32)i + src;
|
||||||
|
else
|
||||||
|
dest = src - (ip + (UInt32)i);
|
||||||
|
data[i + 0] = (Byte)(0x48 | ((dest >> 24) & 0x3));
|
||||||
|
data[i + 1] = (Byte)(dest >> 16);
|
||||||
|
data[i + 2] = (Byte)(dest >> 8);
|
||||||
|
data[i + 3] &= 0x3;
|
||||||
|
data[i + 3] |= dest;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
||||||
|
{
|
||||||
|
UInt32 i;
|
||||||
|
if (size < 4)
|
||||||
|
return 0;
|
||||||
|
size -= 4;
|
||||||
|
for (i = 0; i <= size; i += 4)
|
||||||
|
{
|
||||||
|
if (data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00 ||
|
||||||
|
data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0)
|
||||||
|
{
|
||||||
|
UInt32 src =
|
||||||
|
((UInt32)data[i + 0] << 24) |
|
||||||
|
((UInt32)data[i + 1] << 16) |
|
||||||
|
((UInt32)data[i + 2] << 8) |
|
||||||
|
((UInt32)data[i + 3]);
|
||||||
|
UInt32 dest;
|
||||||
|
|
||||||
|
src <<= 2;
|
||||||
|
if (encoding)
|
||||||
|
dest = ip + i + src;
|
||||||
|
else
|
||||||
|
dest = src - (ip + i);
|
||||||
|
dest >>= 2;
|
||||||
|
|
||||||
|
dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) | 0x40000000;
|
||||||
|
|
||||||
|
data[i + 0] = (Byte)(dest >> 24);
|
||||||
|
data[i + 1] = (Byte)(dest >> 16);
|
||||||
|
data[i + 2] = (Byte)(dest >> 8);
|
||||||
|
data[i + 3] = (Byte)dest;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
/* Bra.h -- Branch converters for executables
|
||||||
|
2009-02-07 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#ifndef __BRA_H
|
||||||
|
#define __BRA_H
|
||||||
|
|
||||||
|
#include "Types.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
These functions convert relative addresses to absolute addresses
|
||||||
|
in CALL instructions to increase the compression ratio.
|
||||||
|
|
||||||
|
In:
|
||||||
|
data - data buffer
|
||||||
|
size - size of data
|
||||||
|
ip - current virtual Instruction Pinter (IP) value
|
||||||
|
state - state variable for x86 converter
|
||||||
|
encoding - 0 (for decoding), 1 (for encoding)
|
||||||
|
|
||||||
|
Out:
|
||||||
|
state - state variable for x86 converter
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The number of processed bytes. If you call these functions with multiple calls,
|
||||||
|
you must start next call with first byte after block of processed bytes.
|
||||||
|
|
||||||
|
Type Endian Alignment LookAhead
|
||||||
|
|
||||||
|
x86 little 1 4
|
||||||
|
ARMT little 2 2
|
||||||
|
ARM little 4 0
|
||||||
|
PPC big 4 0
|
||||||
|
SPARC big 4 0
|
||||||
|
IA64 little 16 0
|
||||||
|
|
||||||
|
size must be >= Alignment + LookAhead, if it's not last block.
|
||||||
|
If (size < Alignment + LookAhead), converter returns 0.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
UInt32 ip = 0;
|
||||||
|
for ()
|
||||||
|
{
|
||||||
|
; size must be >= Alignment + LookAhead, if it's not last block
|
||||||
|
SizeT processed = Convert(data, size, ip, 1);
|
||||||
|
data += processed;
|
||||||
|
size -= processed;
|
||||||
|
ip += processed;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define x86_Convert_Init(state) { state = 0; }
|
||||||
|
SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding);
|
||||||
|
SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
||||||
|
SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
||||||
|
SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
||||||
|
SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
||||||
|
SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
/* Bra86.c -- Converter for x86 code (BCJ)
|
||||||
|
2008-10-04 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#include "Bra.h"
|
||||||
|
|
||||||
|
#define Test86MSByte(b) ((b) == 0 || (b) == 0xFF)
|
||||||
|
|
||||||
|
const Byte kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0};
|
||||||
|
const Byte kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3};
|
||||||
|
|
||||||
|
SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding)
|
||||||
|
{
|
||||||
|
SizeT bufferPos = 0, prevPosT;
|
||||||
|
UInt32 prevMask = *state & 0x7;
|
||||||
|
if (size < 5)
|
||||||
|
return 0;
|
||||||
|
ip += 5;
|
||||||
|
prevPosT = (SizeT)0 - 1;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
Byte *p = data + bufferPos;
|
||||||
|
Byte *limit = data + size - 4;
|
||||||
|
for (; p < limit; p++)
|
||||||
|
if ((*p & 0xFE) == 0xE8)
|
||||||
|
break;
|
||||||
|
bufferPos = (SizeT)(p - data);
|
||||||
|
if (p >= limit)
|
||||||
|
break;
|
||||||
|
prevPosT = bufferPos - prevPosT;
|
||||||
|
if (prevPosT > 3)
|
||||||
|
prevMask = 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7;
|
||||||
|
if (prevMask != 0)
|
||||||
|
{
|
||||||
|
Byte b = p[4 - kMaskToBitNumber[prevMask]];
|
||||||
|
if (!kMaskToAllowedStatus[prevMask] || Test86MSByte(b))
|
||||||
|
{
|
||||||
|
prevPosT = bufferPos;
|
||||||
|
prevMask = ((prevMask << 1) & 0x7) | 1;
|
||||||
|
bufferPos++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prevPosT = bufferPos;
|
||||||
|
|
||||||
|
if (Test86MSByte(p[4]))
|
||||||
|
{
|
||||||
|
UInt32 src = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]);
|
||||||
|
UInt32 dest;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
Byte b;
|
||||||
|
int index;
|
||||||
|
if (encoding)
|
||||||
|
dest = (ip + (UInt32)bufferPos) + src;
|
||||||
|
else
|
||||||
|
dest = src - (ip + (UInt32)bufferPos);
|
||||||
|
if (prevMask == 0)
|
||||||
|
break;
|
||||||
|
index = kMaskToBitNumber[prevMask] * 8;
|
||||||
|
b = (Byte)(dest >> (24 - index));
|
||||||
|
if (!Test86MSByte(b))
|
||||||
|
break;
|
||||||
|
src = dest ^ ((1 << (32 - index)) - 1);
|
||||||
|
}
|
||||||
|
p[4] = (Byte)(~(((dest >> 24) & 1) - 1));
|
||||||
|
p[3] = (Byte)(dest >> 16);
|
||||||
|
p[2] = (Byte)(dest >> 8);
|
||||||
|
p[1] = (Byte)dest;
|
||||||
|
bufferPos += 5;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
prevMask = ((prevMask << 1) & 0x7) | 1;
|
||||||
|
bufferPos++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prevPosT = bufferPos - prevPosT;
|
||||||
|
*state = ((prevPosT > 3) ? 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7));
|
||||||
|
return bufferPos;
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
/* BraIA64.c -- Converter for IA-64 code
|
||||||
|
2008-10-04 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#include "Bra.h"
|
||||||
|
|
||||||
|
static const Byte kBranchTable[32] =
|
||||||
|
{
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
4, 4, 6, 6, 0, 0, 7, 7,
|
||||||
|
4, 4, 0, 0, 4, 4, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
||||||
|
{
|
||||||
|
SizeT i;
|
||||||
|
if (size < 16)
|
||||||
|
return 0;
|
||||||
|
size -= 16;
|
||||||
|
for (i = 0; i <= size; i += 16)
|
||||||
|
{
|
||||||
|
UInt32 instrTemplate = data[i] & 0x1F;
|
||||||
|
UInt32 mask = kBranchTable[instrTemplate];
|
||||||
|
UInt32 bitPos = 5;
|
||||||
|
int slot;
|
||||||
|
for (slot = 0; slot < 3; slot++, bitPos += 41)
|
||||||
|
{
|
||||||
|
UInt32 bytePos, bitRes;
|
||||||
|
UInt64 instruction, instNorm;
|
||||||
|
int j;
|
||||||
|
if (((mask >> slot) & 1) == 0)
|
||||||
|
continue;
|
||||||
|
bytePos = (bitPos >> 3);
|
||||||
|
bitRes = bitPos & 0x7;
|
||||||
|
instruction = 0;
|
||||||
|
for (j = 0; j < 6; j++)
|
||||||
|
instruction += (UInt64)data[i + j + bytePos] << (8 * j);
|
||||||
|
|
||||||
|
instNorm = instruction >> bitRes;
|
||||||
|
if (((instNorm >> 37) & 0xF) == 0x5 && ((instNorm >> 9) & 0x7) == 0)
|
||||||
|
{
|
||||||
|
UInt32 src = (UInt32)((instNorm >> 13) & 0xFFFFF);
|
||||||
|
UInt32 dest;
|
||||||
|
src |= ((UInt32)(instNorm >> 36) & 1) << 20;
|
||||||
|
|
||||||
|
src <<= 4;
|
||||||
|
|
||||||
|
if (encoding)
|
||||||
|
dest = ip + (UInt32)i + src;
|
||||||
|
else
|
||||||
|
dest = src - (ip + (UInt32)i);
|
||||||
|
|
||||||
|
dest >>= 4;
|
||||||
|
|
||||||
|
instNorm &= ~((UInt64)(0x8FFFFF) << 13);
|
||||||
|
instNorm |= ((UInt64)(dest & 0xFFFFF) << 13);
|
||||||
|
instNorm |= ((UInt64)(dest & 0x100000) << (36 - 20));
|
||||||
|
|
||||||
|
instruction &= (1 << bitRes) - 1;
|
||||||
|
instruction |= (instNorm << bitRes);
|
||||||
|
for (j = 0; j < 6; j++)
|
||||||
|
data[i + j + bytePos] = (Byte)(instruction >> (8 * j));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
@@ -0,0 +1,182 @@
|
|||||||
|
/* CpuArch.c -- CPU specific code
|
||||||
|
2009-12-12: Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#include "CpuArch.h"
|
||||||
|
|
||||||
|
#ifdef MY_CPU_X86_OR_AMD64
|
||||||
|
|
||||||
|
#if (defined(_MSC_VER) && !defined(MY_CPU_AMD64)) || defined(__GNUC__)
|
||||||
|
#define USE_ASM
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(USE_ASM) && !defined(MY_CPU_AMD64)
|
||||||
|
static UInt32 CheckFlag(UInt32 flag)
|
||||||
|
{
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
__asm pushfd;
|
||||||
|
__asm pop EAX;
|
||||||
|
__asm mov EDX, EAX;
|
||||||
|
__asm xor EAX, flag;
|
||||||
|
__asm push EAX;
|
||||||
|
__asm popfd;
|
||||||
|
__asm pushfd;
|
||||||
|
__asm pop EAX;
|
||||||
|
__asm xor EAX, EDX;
|
||||||
|
__asm push EDX;
|
||||||
|
__asm popfd;
|
||||||
|
__asm and flag, EAX;
|
||||||
|
#else
|
||||||
|
__asm__ __volatile__ (
|
||||||
|
"pushf\n\t"
|
||||||
|
"pop %%EAX\n\t"
|
||||||
|
"movl %%EAX,%%EDX\n\t"
|
||||||
|
"xorl %0,%%EAX\n\t"
|
||||||
|
"push %%EAX\n\t"
|
||||||
|
"popf\n\t"
|
||||||
|
"pushf\n\t"
|
||||||
|
"pop %%EAX\n\t"
|
||||||
|
"xorl %%EDX,%%EAX\n\t"
|
||||||
|
"push %%EDX\n\t"
|
||||||
|
"popf\n\t"
|
||||||
|
"andl %%EAX, %0\n\t":
|
||||||
|
"=c" (flag) : "c" (flag));
|
||||||
|
#endif
|
||||||
|
return flag;
|
||||||
|
}
|
||||||
|
#define CHECK_CPUID_IS_SUPPORTED if (CheckFlag(1 << 18) == 0 || CheckFlag(1 << 21) == 0) return False;
|
||||||
|
#else
|
||||||
|
#define CHECK_CPUID_IS_SUPPORTED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
|
||||||
|
{
|
||||||
|
#ifdef USE_ASM
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
|
||||||
|
UInt32 a2, b2, c2, d2;
|
||||||
|
__asm xor EBX, EBX;
|
||||||
|
__asm xor ECX, ECX;
|
||||||
|
__asm xor EDX, EDX;
|
||||||
|
__asm mov EAX, function;
|
||||||
|
__asm cpuid;
|
||||||
|
__asm mov a2, EAX;
|
||||||
|
__asm mov b2, EBX;
|
||||||
|
__asm mov c2, ECX;
|
||||||
|
__asm mov d2, EDX;
|
||||||
|
|
||||||
|
*a = a2;
|
||||||
|
*b = b2;
|
||||||
|
*c = c2;
|
||||||
|
*d = d2;
|
||||||
|
|
||||||
|
#else
|
||||||
|
#ifdef ORIGINAL_7ZIP
|
||||||
|
__asm__ __volatile__ (
|
||||||
|
"cpuid"
|
||||||
|
: "=a" (*a) ,
|
||||||
|
"=b" (*b) ,
|
||||||
|
"=c" (*c) ,
|
||||||
|
"=d" (*d)
|
||||||
|
: "0" (function)) ;
|
||||||
|
#else
|
||||||
|
//
|
||||||
|
// Original code doesn't compile on linux for a shared library build
|
||||||
|
// Use proposed fix from the 7-Zip forum on SourceForge
|
||||||
|
// http://sourceforge.net/projects/sevenzip/forums/forum/45797/topic/3768042
|
||||||
|
//
|
||||||
|
__asm__ __volatile__("pushl %%ebx \n\t" /* save %ebx */
|
||||||
|
"cpuid \n\t"
|
||||||
|
"movl %%ebx, %1 \n\t" /* save what cpuid just put in %ebx */
|
||||||
|
"popl %%ebx \n\t" /* restore the old %ebx */
|
||||||
|
: "=a"(*a), "=r"(*b), "=c"(*c), "=d"(*d)
|
||||||
|
: "a"(function)
|
||||||
|
: "cc");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
int CPUInfo[4];
|
||||||
|
__cpuid(CPUInfo, function);
|
||||||
|
*a = CPUInfo[0];
|
||||||
|
*b = CPUInfo[1];
|
||||||
|
*c = CPUInfo[2];
|
||||||
|
*d = CPUInfo[3];
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
Bool x86cpuid_CheckAndRead(Cx86cpuid *p)
|
||||||
|
{
|
||||||
|
CHECK_CPUID_IS_SUPPORTED
|
||||||
|
MyCPUID(0, &p->maxFunc, &p->vendor[0], &p->vendor[2], &p->vendor[1]);
|
||||||
|
MyCPUID(1, &p->ver, &p->b, &p->c, &p->d);
|
||||||
|
return True;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UInt32 kVendors[][3] =
|
||||||
|
{
|
||||||
|
{ 0x756E6547, 0x49656E69, 0x6C65746E},
|
||||||
|
{ 0x68747541, 0x69746E65, 0x444D4163},
|
||||||
|
{ 0x746E6543, 0x48727561, 0x736C7561}
|
||||||
|
};
|
||||||
|
|
||||||
|
int x86cpuid_GetFirm(const Cx86cpuid *p)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; i < sizeof(kVendors) / sizeof(kVendors[i]); i++)
|
||||||
|
{
|
||||||
|
const UInt32 *v = kVendors[i];
|
||||||
|
if (v[0] == p->vendor[0] &&
|
||||||
|
v[1] == p->vendor[1] &&
|
||||||
|
v[2] == p->vendor[2])
|
||||||
|
return (int)i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bool CPU_Is_InOrder()
|
||||||
|
{
|
||||||
|
Cx86cpuid p;
|
||||||
|
int firm;
|
||||||
|
UInt32 family, model;
|
||||||
|
if (!x86cpuid_CheckAndRead(&p))
|
||||||
|
return True;
|
||||||
|
family = x86cpuid_GetFamily(&p);
|
||||||
|
model = x86cpuid_GetModel(&p);
|
||||||
|
firm = x86cpuid_GetFirm(&p);
|
||||||
|
switch (firm)
|
||||||
|
{
|
||||||
|
case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && model == 0x100C));
|
||||||
|
case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || model == 0xA)));
|
||||||
|
case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF));
|
||||||
|
}
|
||||||
|
return True;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(MY_CPU_AMD64) && defined(_WIN32)
|
||||||
|
static Bool CPU_Sys_Is_SSE_Supported()
|
||||||
|
{
|
||||||
|
OSVERSIONINFO vi;
|
||||||
|
vi.dwOSVersionInfoSize = sizeof(vi);
|
||||||
|
if (!GetVersionEx(&vi))
|
||||||
|
return False;
|
||||||
|
return (vi.dwMajorVersion >= 5);
|
||||||
|
}
|
||||||
|
#define CHECK_SYS_SSE_SUPPORT if (!CPU_Sys_Is_SSE_Supported()) return False;
|
||||||
|
#else
|
||||||
|
#define CHECK_SYS_SSE_SUPPORT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Bool CPU_Is_Aes_Supported()
|
||||||
|
{
|
||||||
|
Cx86cpuid p;
|
||||||
|
CHECK_SYS_SSE_SUPPORT
|
||||||
|
if (!x86cpuid_CheckAndRead(&p))
|
||||||
|
return False;
|
||||||
|
return (p.c >> 25) & 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,138 @@
|
|||||||
|
/* CpuArch.h -- CPU specific code
|
||||||
|
2010-03-11: Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#ifndef __CPU_ARCH_H
|
||||||
|
#define __CPU_ARCH_H
|
||||||
|
|
||||||
|
#include "Types.h"
|
||||||
|
|
||||||
|
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_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__)
|
||||||
|
#define MY_CPU_AMD64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MY_CPU_AMD64) || defined(_M_IA64)
|
||||||
|
#define MY_CPU_64BIT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_M_IX86) || defined(__i386__)
|
||||||
|
#define MY_CPU_X86
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64)
|
||||||
|
#define MY_CPU_X86_OR_AMD64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MY_CPU_X86) || defined(_M_ARM)
|
||||||
|
#define MY_CPU_32BIT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_WIN32) && defined(_M_ARM)
|
||||||
|
#define MY_CPU_ARM_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)
|
||||||
|
#define MY_CPU_LE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MY_CPU_LE_UNALIGN
|
||||||
|
|
||||||
|
#define GetUi16(p) (*(const UInt16 *)(p))
|
||||||
|
#define GetUi32(p) (*(const UInt32 *)(p))
|
||||||
|
#define GetUi64(p) (*(const UInt64 *)(p))
|
||||||
|
#define SetUi16(p, d) *(UInt16 *)(p) = (d);
|
||||||
|
#define SetUi32(p, d) *(UInt32 *)(p) = (d);
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define GetUi16(p) (((const Byte *)(p))[0] | ((UInt16)((const Byte *)(p))[1] << 8))
|
||||||
|
|
||||||
|
#define GetUi32(p) ( \
|
||||||
|
((const Byte *)(p))[0] | \
|
||||||
|
((UInt32)((const Byte *)(p))[1] << 8) | \
|
||||||
|
((UInt32)((const Byte *)(p))[2] << 16) | \
|
||||||
|
((UInt32)((const Byte *)(p))[3] << 24))
|
||||||
|
|
||||||
|
#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 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); }
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MY_CPU_LE_UNALIGN) && defined(_WIN64) && (_MSC_VER >= 1300)
|
||||||
|
|
||||||
|
#pragma intrinsic(_byteswap_ulong)
|
||||||
|
#pragma intrinsic(_byteswap_uint64)
|
||||||
|
#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p))
|
||||||
|
#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p))
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define GetBe32(p) ( \
|
||||||
|
((UInt32)((const Byte *)(p))[0] << 24) | \
|
||||||
|
((UInt32)((const Byte *)(p))[1] << 16) | \
|
||||||
|
((UInt32)((const Byte *)(p))[2] << 8) | \
|
||||||
|
((const Byte *)(p))[3] )
|
||||||
|
|
||||||
|
#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4))
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define GetBe16(p) (((UInt16)((const Byte *)(p))[0] << 8) | ((const Byte *)(p))[1])
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef MY_CPU_X86_OR_AMD64
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
UInt32 maxFunc;
|
||||||
|
UInt32 vendor[3];
|
||||||
|
UInt32 ver;
|
||||||
|
UInt32 b;
|
||||||
|
UInt32 c;
|
||||||
|
UInt32 d;
|
||||||
|
} Cx86cpuid;
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
CPU_FIRM_INTEL,
|
||||||
|
CPU_FIRM_AMD,
|
||||||
|
CPU_FIRM_VIA
|
||||||
|
};
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
Bool CPU_Is_InOrder();
|
||||||
|
Bool CPU_Is_Aes_Supported();
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
EXTERN_C_END
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
/* Delta.c -- Delta converter
|
||||||
|
2009-05-26 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#include "Delta.h"
|
||||||
|
|
||||||
|
void Delta_Init(Byte *state)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; i < DELTA_STATE_SIZE; i++)
|
||||||
|
state[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MyMemCpy(Byte *dest, const Byte *src, unsigned size)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; i < size; i++)
|
||||||
|
dest[i] = src[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Delta_Encode(Byte *state, unsigned delta, Byte *data, SizeT size)
|
||||||
|
{
|
||||||
|
Byte buf[DELTA_STATE_SIZE];
|
||||||
|
unsigned j = 0;
|
||||||
|
MyMemCpy(buf, state, delta);
|
||||||
|
{
|
||||||
|
SizeT i;
|
||||||
|
for (i = 0; i < size;)
|
||||||
|
{
|
||||||
|
for (j = 0; j < delta && i < size; i++, j++)
|
||||||
|
{
|
||||||
|
Byte b = data[i];
|
||||||
|
data[i] = (Byte)(b - buf[j]);
|
||||||
|
buf[j] = b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (j == delta)
|
||||||
|
j = 0;
|
||||||
|
MyMemCpy(state, buf + j, delta - j);
|
||||||
|
MyMemCpy(state + delta - j, buf, j);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Delta_Decode(Byte *state, unsigned delta, Byte *data, SizeT size)
|
||||||
|
{
|
||||||
|
Byte buf[DELTA_STATE_SIZE];
|
||||||
|
unsigned j = 0;
|
||||||
|
MyMemCpy(buf, state, delta);
|
||||||
|
{
|
||||||
|
SizeT i;
|
||||||
|
for (i = 0; i < size;)
|
||||||
|
{
|
||||||
|
for (j = 0; j < delta && i < size; i++, j++)
|
||||||
|
{
|
||||||
|
buf[j] = data[i] = (Byte)(buf[j] + data[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (j == delta)
|
||||||
|
j = 0;
|
||||||
|
MyMemCpy(state, buf + j, delta - j);
|
||||||
|
MyMemCpy(state + delta - j, buf, j);
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
/* Delta.h -- Delta converter
|
||||||
|
2009-04-15 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#ifndef __DELTA_H
|
||||||
|
#define __DELTA_H
|
||||||
|
|
||||||
|
#include "Types.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define DELTA_STATE_SIZE 256
|
||||||
|
|
||||||
|
void Delta_Init(Byte *state);
|
||||||
|
void Delta_Encode(Byte *state, unsigned delta, Byte *data, SizeT size);
|
||||||
|
void Delta_Decode(Byte *state, unsigned delta, Byte *data, SizeT size);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,761 @@
|
|||||||
|
/* LzFind.c -- Match finder for LZ algorithms
|
||||||
|
2009-04-22 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "LzFind.h"
|
||||||
|
#include "LzHash.h"
|
||||||
|
|
||||||
|
#define kEmptyHashValue 0
|
||||||
|
#define kMaxValForNormalize ((UInt32)0xFFFFFFFF)
|
||||||
|
#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */
|
||||||
|
#define kNormalizeMask (~(kNormalizeStepMin - 1))
|
||||||
|
#define kMaxHistorySize ((UInt32)3 << 30)
|
||||||
|
|
||||||
|
#define kStartMaxLen 3
|
||||||
|
|
||||||
|
static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
if (!p->directInput)
|
||||||
|
{
|
||||||
|
alloc->Free(alloc, p->bufferBase);
|
||||||
|
p->bufferBase = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */
|
||||||
|
|
||||||
|
static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv;
|
||||||
|
if (p->directInput)
|
||||||
|
{
|
||||||
|
p->blockSize = blockSize;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (p->bufferBase == 0 || p->blockSize != blockSize)
|
||||||
|
{
|
||||||
|
LzInWindow_Free(p, alloc);
|
||||||
|
p->blockSize = blockSize;
|
||||||
|
p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize);
|
||||||
|
}
|
||||||
|
return (p->bufferBase != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; }
|
||||||
|
Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; }
|
||||||
|
|
||||||
|
UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; }
|
||||||
|
|
||||||
|
void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue)
|
||||||
|
{
|
||||||
|
p->posLimit -= subValue;
|
||||||
|
p->pos -= subValue;
|
||||||
|
p->streamPos -= subValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MatchFinder_ReadBlock(CMatchFinder *p)
|
||||||
|
{
|
||||||
|
if (p->streamEndWasReached || p->result != SZ_OK)
|
||||||
|
return;
|
||||||
|
if (p->directInput)
|
||||||
|
{
|
||||||
|
UInt32 curSize = 0xFFFFFFFF - p->streamPos;
|
||||||
|
if (curSize > p->directInputRem)
|
||||||
|
curSize = (UInt32)p->directInputRem;
|
||||||
|
p->directInputRem -= curSize;
|
||||||
|
p->streamPos += curSize;
|
||||||
|
if (p->directInputRem == 0)
|
||||||
|
p->streamEndWasReached = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
Byte *dest = p->buffer + (p->streamPos - p->pos);
|
||||||
|
size_t size = (p->bufferBase + p->blockSize - dest);
|
||||||
|
if (size == 0)
|
||||||
|
return;
|
||||||
|
p->result = p->stream->Read(p->stream, dest, &size);
|
||||||
|
if (p->result != SZ_OK)
|
||||||
|
return;
|
||||||
|
if (size == 0)
|
||||||
|
{
|
||||||
|
p->streamEndWasReached = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
p->streamPos += (UInt32)size;
|
||||||
|
if (p->streamPos - p->pos > p->keepSizeAfter)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatchFinder_MoveBlock(CMatchFinder *p)
|
||||||
|
{
|
||||||
|
memmove(p->bufferBase,
|
||||||
|
p->buffer - p->keepSizeBefore,
|
||||||
|
(size_t)(p->streamPos - p->pos + p->keepSizeBefore));
|
||||||
|
p->buffer = p->bufferBase + p->keepSizeBefore;
|
||||||
|
}
|
||||||
|
|
||||||
|
int MatchFinder_NeedMove(CMatchFinder *p)
|
||||||
|
{
|
||||||
|
if (p->directInput)
|
||||||
|
return 0;
|
||||||
|
/* if (p->streamEndWasReached) return 0; */
|
||||||
|
return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatchFinder_ReadIfRequired(CMatchFinder *p)
|
||||||
|
{
|
||||||
|
if (p->streamEndWasReached)
|
||||||
|
return;
|
||||||
|
if (p->keepSizeAfter >= p->streamPos - p->pos)
|
||||||
|
MatchFinder_ReadBlock(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p)
|
||||||
|
{
|
||||||
|
if (MatchFinder_NeedMove(p))
|
||||||
|
MatchFinder_MoveBlock(p);
|
||||||
|
MatchFinder_ReadBlock(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MatchFinder_SetDefaultSettings(CMatchFinder *p)
|
||||||
|
{
|
||||||
|
p->cutValue = 32;
|
||||||
|
p->btMode = 1;
|
||||||
|
p->numHashBytes = 4;
|
||||||
|
p->bigHash = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define kCrcPoly 0xEDB88320
|
||||||
|
|
||||||
|
void MatchFinder_Construct(CMatchFinder *p)
|
||||||
|
{
|
||||||
|
UInt32 i;
|
||||||
|
p->bufferBase = 0;
|
||||||
|
p->directInput = 0;
|
||||||
|
p->hash = 0;
|
||||||
|
MatchFinder_SetDefaultSettings(p);
|
||||||
|
|
||||||
|
for (i = 0; i < 256; i++)
|
||||||
|
{
|
||||||
|
UInt32 r = i;
|
||||||
|
int j;
|
||||||
|
for (j = 0; j < 8; j++)
|
||||||
|
r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
|
||||||
|
p->crc[i] = r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
alloc->Free(alloc, p->hash);
|
||||||
|
p->hash = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
MatchFinder_FreeThisClassMemory(p, alloc);
|
||||||
|
LzInWindow_Free(p, alloc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
size_t sizeInBytes = (size_t)num * sizeof(CLzRef);
|
||||||
|
if (sizeInBytes / sizeof(CLzRef) != num)
|
||||||
|
return 0;
|
||||||
|
return (CLzRef *)alloc->Alloc(alloc, sizeInBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
|
||||||
|
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
|
||||||
|
ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
UInt32 sizeReserv;
|
||||||
|
if (historySize > kMaxHistorySize)
|
||||||
|
{
|
||||||
|
MatchFinder_Free(p, alloc);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
sizeReserv = historySize >> 1;
|
||||||
|
if (historySize > ((UInt32)2 << 30))
|
||||||
|
sizeReserv = historySize >> 2;
|
||||||
|
sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19);
|
||||||
|
|
||||||
|
p->keepSizeBefore = historySize + keepAddBufferBefore + 1;
|
||||||
|
p->keepSizeAfter = matchMaxLen + keepAddBufferAfter;
|
||||||
|
/* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */
|
||||||
|
if (LzInWindow_Create(p, sizeReserv, alloc))
|
||||||
|
{
|
||||||
|
UInt32 newCyclicBufferSize = historySize + 1;
|
||||||
|
UInt32 hs;
|
||||||
|
p->matchMaxLen = matchMaxLen;
|
||||||
|
{
|
||||||
|
p->fixedHashSize = 0;
|
||||||
|
if (p->numHashBytes == 2)
|
||||||
|
hs = (1 << 16) - 1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hs = historySize - 1;
|
||||||
|
hs |= (hs >> 1);
|
||||||
|
hs |= (hs >> 2);
|
||||||
|
hs |= (hs >> 4);
|
||||||
|
hs |= (hs >> 8);
|
||||||
|
hs >>= 1;
|
||||||
|
hs |= 0xFFFF; /* don't change it! It's required for Deflate */
|
||||||
|
if (hs > (1 << 24))
|
||||||
|
{
|
||||||
|
if (p->numHashBytes == 3)
|
||||||
|
hs = (1 << 24) - 1;
|
||||||
|
else
|
||||||
|
hs >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p->hashMask = hs;
|
||||||
|
hs++;
|
||||||
|
if (p->numHashBytes > 2) p->fixedHashSize += kHash2Size;
|
||||||
|
if (p->numHashBytes > 3) p->fixedHashSize += kHash3Size;
|
||||||
|
if (p->numHashBytes > 4) p->fixedHashSize += kHash4Size;
|
||||||
|
hs += p->fixedHashSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
UInt32 prevSize = p->hashSizeSum + p->numSons;
|
||||||
|
UInt32 newSize;
|
||||||
|
p->historySize = historySize;
|
||||||
|
p->hashSizeSum = hs;
|
||||||
|
p->cyclicBufferSize = newCyclicBufferSize;
|
||||||
|
p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize);
|
||||||
|
newSize = p->hashSizeSum + p->numSons;
|
||||||
|
if (p->hash != 0 && prevSize == newSize)
|
||||||
|
return 1;
|
||||||
|
MatchFinder_FreeThisClassMemory(p, alloc);
|
||||||
|
p->hash = AllocRefs(newSize, alloc);
|
||||||
|
if (p->hash != 0)
|
||||||
|
{
|
||||||
|
p->son = p->hash + p->hashSizeSum;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MatchFinder_Free(p, alloc);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MatchFinder_SetLimits(CMatchFinder *p)
|
||||||
|
{
|
||||||
|
UInt32 limit = kMaxValForNormalize - p->pos;
|
||||||
|
UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos;
|
||||||
|
if (limit2 < limit)
|
||||||
|
limit = limit2;
|
||||||
|
limit2 = p->streamPos - p->pos;
|
||||||
|
if (limit2 <= p->keepSizeAfter)
|
||||||
|
{
|
||||||
|
if (limit2 > 0)
|
||||||
|
limit2 = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
limit2 -= p->keepSizeAfter;
|
||||||
|
if (limit2 < limit)
|
||||||
|
limit = limit2;
|
||||||
|
{
|
||||||
|
UInt32 lenLimit = p->streamPos - p->pos;
|
||||||
|
if (lenLimit > p->matchMaxLen)
|
||||||
|
lenLimit = p->matchMaxLen;
|
||||||
|
p->lenLimit = lenLimit;
|
||||||
|
}
|
||||||
|
p->posLimit = p->pos + limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatchFinder_Init(CMatchFinder *p)
|
||||||
|
{
|
||||||
|
UInt32 i;
|
||||||
|
for (i = 0; i < p->hashSizeSum; i++)
|
||||||
|
p->hash[i] = kEmptyHashValue;
|
||||||
|
p->cyclicBufferPos = 0;
|
||||||
|
p->buffer = p->bufferBase;
|
||||||
|
p->pos = p->streamPos = p->cyclicBufferSize;
|
||||||
|
p->result = SZ_OK;
|
||||||
|
p->streamEndWasReached = 0;
|
||||||
|
MatchFinder_ReadBlock(p);
|
||||||
|
MatchFinder_SetLimits(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static UInt32 MatchFinder_GetSubValue(CMatchFinder *p)
|
||||||
|
{
|
||||||
|
return (p->pos - p->historySize - 1) & kNormalizeMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems)
|
||||||
|
{
|
||||||
|
UInt32 i;
|
||||||
|
for (i = 0; i < numItems; i++)
|
||||||
|
{
|
||||||
|
UInt32 value = items[i];
|
||||||
|
if (value <= subValue)
|
||||||
|
value = kEmptyHashValue;
|
||||||
|
else
|
||||||
|
value -= subValue;
|
||||||
|
items[i] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MatchFinder_Normalize(CMatchFinder *p)
|
||||||
|
{
|
||||||
|
UInt32 subValue = MatchFinder_GetSubValue(p);
|
||||||
|
MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons);
|
||||||
|
MatchFinder_ReduceOffsets(p, subValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MatchFinder_CheckLimits(CMatchFinder *p)
|
||||||
|
{
|
||||||
|
if (p->pos == kMaxValForNormalize)
|
||||||
|
MatchFinder_Normalize(p);
|
||||||
|
if (!p->streamEndWasReached && p->keepSizeAfter == p->streamPos - p->pos)
|
||||||
|
MatchFinder_CheckAndMoveAndRead(p);
|
||||||
|
if (p->cyclicBufferPos == p->cyclicBufferSize)
|
||||||
|
p->cyclicBufferPos = 0;
|
||||||
|
MatchFinder_SetLimits(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
|
||||||
|
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
|
||||||
|
UInt32 *distances, UInt32 maxLen)
|
||||||
|
{
|
||||||
|
son[_cyclicBufferPos] = curMatch;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
UInt32 delta = pos - curMatch;
|
||||||
|
if (cutValue-- == 0 || delta >= _cyclicBufferSize)
|
||||||
|
return distances;
|
||||||
|
{
|
||||||
|
const Byte *pb = cur - delta;
|
||||||
|
curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)];
|
||||||
|
if (pb[maxLen] == cur[maxLen] && *pb == *cur)
|
||||||
|
{
|
||||||
|
UInt32 len = 0;
|
||||||
|
while (++len != lenLimit)
|
||||||
|
if (pb[len] != cur[len])
|
||||||
|
break;
|
||||||
|
if (maxLen < len)
|
||||||
|
{
|
||||||
|
*distances++ = maxLen = len;
|
||||||
|
*distances++ = delta - 1;
|
||||||
|
if (len == lenLimit)
|
||||||
|
return distances;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
|
||||||
|
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
|
||||||
|
UInt32 *distances, UInt32 maxLen)
|
||||||
|
{
|
||||||
|
CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
|
||||||
|
CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
|
||||||
|
UInt32 len0 = 0, len1 = 0;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
UInt32 delta = pos - curMatch;
|
||||||
|
if (cutValue-- == 0 || delta >= _cyclicBufferSize)
|
||||||
|
{
|
||||||
|
*ptr0 = *ptr1 = kEmptyHashValue;
|
||||||
|
return distances;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
|
||||||
|
const Byte *pb = cur - delta;
|
||||||
|
UInt32 len = (len0 < len1 ? len0 : len1);
|
||||||
|
if (pb[len] == cur[len])
|
||||||
|
{
|
||||||
|
if (++len != lenLimit && pb[len] == cur[len])
|
||||||
|
while (++len != lenLimit)
|
||||||
|
if (pb[len] != cur[len])
|
||||||
|
break;
|
||||||
|
if (maxLen < len)
|
||||||
|
{
|
||||||
|
*distances++ = maxLen = len;
|
||||||
|
*distances++ = delta - 1;
|
||||||
|
if (len == lenLimit)
|
||||||
|
{
|
||||||
|
*ptr1 = pair[0];
|
||||||
|
*ptr0 = pair[1];
|
||||||
|
return distances;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pb[len] < cur[len])
|
||||||
|
{
|
||||||
|
*ptr1 = curMatch;
|
||||||
|
ptr1 = pair + 1;
|
||||||
|
curMatch = *ptr1;
|
||||||
|
len1 = len;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*ptr0 = curMatch;
|
||||||
|
ptr0 = pair;
|
||||||
|
curMatch = *ptr0;
|
||||||
|
len0 = len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
|
||||||
|
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue)
|
||||||
|
{
|
||||||
|
CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
|
||||||
|
CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
|
||||||
|
UInt32 len0 = 0, len1 = 0;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
UInt32 delta = pos - curMatch;
|
||||||
|
if (cutValue-- == 0 || delta >= _cyclicBufferSize)
|
||||||
|
{
|
||||||
|
*ptr0 = *ptr1 = kEmptyHashValue;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
|
||||||
|
const Byte *pb = cur - delta;
|
||||||
|
UInt32 len = (len0 < len1 ? len0 : len1);
|
||||||
|
if (pb[len] == cur[len])
|
||||||
|
{
|
||||||
|
while (++len != lenLimit)
|
||||||
|
if (pb[len] != cur[len])
|
||||||
|
break;
|
||||||
|
{
|
||||||
|
if (len == lenLimit)
|
||||||
|
{
|
||||||
|
*ptr1 = pair[0];
|
||||||
|
*ptr0 = pair[1];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pb[len] < cur[len])
|
||||||
|
{
|
||||||
|
*ptr1 = curMatch;
|
||||||
|
ptr1 = pair + 1;
|
||||||
|
curMatch = *ptr1;
|
||||||
|
len1 = len;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*ptr0 = curMatch;
|
||||||
|
ptr0 = pair;
|
||||||
|
curMatch = *ptr0;
|
||||||
|
len0 = len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MOVE_POS \
|
||||||
|
++p->cyclicBufferPos; \
|
||||||
|
p->buffer++; \
|
||||||
|
if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p);
|
||||||
|
|
||||||
|
#define MOVE_POS_RET MOVE_POS return offset;
|
||||||
|
|
||||||
|
static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; }
|
||||||
|
|
||||||
|
#define GET_MATCHES_HEADER2(minLen, ret_op) \
|
||||||
|
UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \
|
||||||
|
lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \
|
||||||
|
cur = p->buffer;
|
||||||
|
|
||||||
|
#define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return 0)
|
||||||
|
#define SKIP_HEADER(minLen) GET_MATCHES_HEADER2(minLen, continue)
|
||||||
|
|
||||||
|
#define MF_PARAMS(p) p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue
|
||||||
|
|
||||||
|
#define GET_MATCHES_FOOTER(offset, maxLen) \
|
||||||
|
offset = (UInt32)(GetMatchesSpec1(lenLimit, curMatch, MF_PARAMS(p), \
|
||||||
|
distances + offset, maxLen) - distances); MOVE_POS_RET;
|
||||||
|
|
||||||
|
#define SKIP_FOOTER \
|
||||||
|
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS;
|
||||||
|
|
||||||
|
static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||||
|
{
|
||||||
|
UInt32 offset;
|
||||||
|
GET_MATCHES_HEADER(2)
|
||||||
|
HASH2_CALC;
|
||||||
|
curMatch = p->hash[hashValue];
|
||||||
|
p->hash[hashValue] = p->pos;
|
||||||
|
offset = 0;
|
||||||
|
GET_MATCHES_FOOTER(offset, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||||
|
{
|
||||||
|
UInt32 offset;
|
||||||
|
GET_MATCHES_HEADER(3)
|
||||||
|
HASH_ZIP_CALC;
|
||||||
|
curMatch = p->hash[hashValue];
|
||||||
|
p->hash[hashValue] = p->pos;
|
||||||
|
offset = 0;
|
||||||
|
GET_MATCHES_FOOTER(offset, 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||||
|
{
|
||||||
|
UInt32 hash2Value, delta2, maxLen, offset;
|
||||||
|
GET_MATCHES_HEADER(3)
|
||||||
|
|
||||||
|
HASH3_CALC;
|
||||||
|
|
||||||
|
delta2 = p->pos - p->hash[hash2Value];
|
||||||
|
curMatch = p->hash[kFix3HashSize + hashValue];
|
||||||
|
|
||||||
|
p->hash[hash2Value] =
|
||||||
|
p->hash[kFix3HashSize + hashValue] = p->pos;
|
||||||
|
|
||||||
|
|
||||||
|
maxLen = 2;
|
||||||
|
offset = 0;
|
||||||
|
if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
|
||||||
|
{
|
||||||
|
for (; maxLen != lenLimit; maxLen++)
|
||||||
|
if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
|
||||||
|
break;
|
||||||
|
distances[0] = maxLen;
|
||||||
|
distances[1] = delta2 - 1;
|
||||||
|
offset = 2;
|
||||||
|
if (maxLen == lenLimit)
|
||||||
|
{
|
||||||
|
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
|
||||||
|
MOVE_POS_RET;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GET_MATCHES_FOOTER(offset, maxLen)
|
||||||
|
}
|
||||||
|
|
||||||
|
static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||||
|
{
|
||||||
|
UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
|
||||||
|
GET_MATCHES_HEADER(4)
|
||||||
|
|
||||||
|
HASH4_CALC;
|
||||||
|
|
||||||
|
delta2 = p->pos - p->hash[ hash2Value];
|
||||||
|
delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
|
||||||
|
curMatch = p->hash[kFix4HashSize + hashValue];
|
||||||
|
|
||||||
|
p->hash[ hash2Value] =
|
||||||
|
p->hash[kFix3HashSize + hash3Value] =
|
||||||
|
p->hash[kFix4HashSize + hashValue] = p->pos;
|
||||||
|
|
||||||
|
maxLen = 1;
|
||||||
|
offset = 0;
|
||||||
|
if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
|
||||||
|
{
|
||||||
|
distances[0] = maxLen = 2;
|
||||||
|
distances[1] = delta2 - 1;
|
||||||
|
offset = 2;
|
||||||
|
}
|
||||||
|
if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
|
||||||
|
{
|
||||||
|
maxLen = 3;
|
||||||
|
distances[offset + 1] = delta3 - 1;
|
||||||
|
offset += 2;
|
||||||
|
delta2 = delta3;
|
||||||
|
}
|
||||||
|
if (offset != 0)
|
||||||
|
{
|
||||||
|
for (; maxLen != lenLimit; maxLen++)
|
||||||
|
if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
|
||||||
|
break;
|
||||||
|
distances[offset - 2] = maxLen;
|
||||||
|
if (maxLen == lenLimit)
|
||||||
|
{
|
||||||
|
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
|
||||||
|
MOVE_POS_RET;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (maxLen < 3)
|
||||||
|
maxLen = 3;
|
||||||
|
GET_MATCHES_FOOTER(offset, maxLen)
|
||||||
|
}
|
||||||
|
|
||||||
|
static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||||
|
{
|
||||||
|
UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
|
||||||
|
GET_MATCHES_HEADER(4)
|
||||||
|
|
||||||
|
HASH4_CALC;
|
||||||
|
|
||||||
|
delta2 = p->pos - p->hash[ hash2Value];
|
||||||
|
delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
|
||||||
|
curMatch = p->hash[kFix4HashSize + hashValue];
|
||||||
|
|
||||||
|
p->hash[ hash2Value] =
|
||||||
|
p->hash[kFix3HashSize + hash3Value] =
|
||||||
|
p->hash[kFix4HashSize + hashValue] = p->pos;
|
||||||
|
|
||||||
|
maxLen = 1;
|
||||||
|
offset = 0;
|
||||||
|
if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
|
||||||
|
{
|
||||||
|
distances[0] = maxLen = 2;
|
||||||
|
distances[1] = delta2 - 1;
|
||||||
|
offset = 2;
|
||||||
|
}
|
||||||
|
if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
|
||||||
|
{
|
||||||
|
maxLen = 3;
|
||||||
|
distances[offset + 1] = delta3 - 1;
|
||||||
|
offset += 2;
|
||||||
|
delta2 = delta3;
|
||||||
|
}
|
||||||
|
if (offset != 0)
|
||||||
|
{
|
||||||
|
for (; maxLen != lenLimit; maxLen++)
|
||||||
|
if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
|
||||||
|
break;
|
||||||
|
distances[offset - 2] = maxLen;
|
||||||
|
if (maxLen == lenLimit)
|
||||||
|
{
|
||||||
|
p->son[p->cyclicBufferPos] = curMatch;
|
||||||
|
MOVE_POS_RET;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (maxLen < 3)
|
||||||
|
maxLen = 3;
|
||||||
|
offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
|
||||||
|
distances + offset, maxLen) - (distances));
|
||||||
|
MOVE_POS_RET
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||||
|
{
|
||||||
|
UInt32 offset;
|
||||||
|
GET_MATCHES_HEADER(3)
|
||||||
|
HASH_ZIP_CALC;
|
||||||
|
curMatch = p->hash[hashValue];
|
||||||
|
p->hash[hashValue] = p->pos;
|
||||||
|
offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
|
||||||
|
distances, 2) - (distances));
|
||||||
|
MOVE_POS_RET
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
SKIP_HEADER(2)
|
||||||
|
HASH2_CALC;
|
||||||
|
curMatch = p->hash[hashValue];
|
||||||
|
p->hash[hashValue] = p->pos;
|
||||||
|
SKIP_FOOTER
|
||||||
|
}
|
||||||
|
while (--num != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
SKIP_HEADER(3)
|
||||||
|
HASH_ZIP_CALC;
|
||||||
|
curMatch = p->hash[hashValue];
|
||||||
|
p->hash[hashValue] = p->pos;
|
||||||
|
SKIP_FOOTER
|
||||||
|
}
|
||||||
|
while (--num != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
UInt32 hash2Value;
|
||||||
|
SKIP_HEADER(3)
|
||||||
|
HASH3_CALC;
|
||||||
|
curMatch = p->hash[kFix3HashSize + hashValue];
|
||||||
|
p->hash[hash2Value] =
|
||||||
|
p->hash[kFix3HashSize + hashValue] = p->pos;
|
||||||
|
SKIP_FOOTER
|
||||||
|
}
|
||||||
|
while (--num != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
UInt32 hash2Value, hash3Value;
|
||||||
|
SKIP_HEADER(4)
|
||||||
|
HASH4_CALC;
|
||||||
|
curMatch = p->hash[kFix4HashSize + hashValue];
|
||||||
|
p->hash[ hash2Value] =
|
||||||
|
p->hash[kFix3HashSize + hash3Value] = p->pos;
|
||||||
|
p->hash[kFix4HashSize + hashValue] = p->pos;
|
||||||
|
SKIP_FOOTER
|
||||||
|
}
|
||||||
|
while (--num != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
UInt32 hash2Value, hash3Value;
|
||||||
|
SKIP_HEADER(4)
|
||||||
|
HASH4_CALC;
|
||||||
|
curMatch = p->hash[kFix4HashSize + hashValue];
|
||||||
|
p->hash[ hash2Value] =
|
||||||
|
p->hash[kFix3HashSize + hash3Value] =
|
||||||
|
p->hash[kFix4HashSize + hashValue] = p->pos;
|
||||||
|
p->son[p->cyclicBufferPos] = curMatch;
|
||||||
|
MOVE_POS
|
||||||
|
}
|
||||||
|
while (--num != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
SKIP_HEADER(3)
|
||||||
|
HASH_ZIP_CALC;
|
||||||
|
curMatch = p->hash[hashValue];
|
||||||
|
p->hash[hashValue] = p->pos;
|
||||||
|
p->son[p->cyclicBufferPos] = curMatch;
|
||||||
|
MOVE_POS
|
||||||
|
}
|
||||||
|
while (--num != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable)
|
||||||
|
{
|
||||||
|
vTable->Init = (Mf_Init_Func)MatchFinder_Init;
|
||||||
|
vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte;
|
||||||
|
vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes;
|
||||||
|
vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos;
|
||||||
|
if (!p->btMode)
|
||||||
|
{
|
||||||
|
vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches;
|
||||||
|
vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip;
|
||||||
|
}
|
||||||
|
else if (p->numHashBytes == 2)
|
||||||
|
{
|
||||||
|
vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches;
|
||||||
|
vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip;
|
||||||
|
}
|
||||||
|
else if (p->numHashBytes == 3)
|
||||||
|
{
|
||||||
|
vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches;
|
||||||
|
vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches;
|
||||||
|
vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
/* LzFind.h -- Match finder for LZ algorithms
|
||||||
|
2009-04-22 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#ifndef __LZ_FIND_H
|
||||||
|
#define __LZ_FIND_H
|
||||||
|
|
||||||
|
#include "Types.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef UInt32 CLzRef;
|
||||||
|
|
||||||
|
typedef struct _CMatchFinder
|
||||||
|
{
|
||||||
|
Byte *buffer;
|
||||||
|
UInt32 pos;
|
||||||
|
UInt32 posLimit;
|
||||||
|
UInt32 streamPos;
|
||||||
|
UInt32 lenLimit;
|
||||||
|
|
||||||
|
UInt32 cyclicBufferPos;
|
||||||
|
UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */
|
||||||
|
|
||||||
|
UInt32 matchMaxLen;
|
||||||
|
CLzRef *hash;
|
||||||
|
CLzRef *son;
|
||||||
|
UInt32 hashMask;
|
||||||
|
UInt32 cutValue;
|
||||||
|
|
||||||
|
Byte *bufferBase;
|
||||||
|
ISeqInStream *stream;
|
||||||
|
int streamEndWasReached;
|
||||||
|
|
||||||
|
UInt32 blockSize;
|
||||||
|
UInt32 keepSizeBefore;
|
||||||
|
UInt32 keepSizeAfter;
|
||||||
|
|
||||||
|
UInt32 numHashBytes;
|
||||||
|
int directInput;
|
||||||
|
size_t directInputRem;
|
||||||
|
int btMode;
|
||||||
|
int bigHash;
|
||||||
|
UInt32 historySize;
|
||||||
|
UInt32 fixedHashSize;
|
||||||
|
UInt32 hashSizeSum;
|
||||||
|
UInt32 numSons;
|
||||||
|
SRes result;
|
||||||
|
UInt32 crc[256];
|
||||||
|
} CMatchFinder;
|
||||||
|
|
||||||
|
#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer)
|
||||||
|
#define Inline_MatchFinder_GetIndexByte(p, index) ((p)->buffer[(Int32)(index)])
|
||||||
|
|
||||||
|
#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos)
|
||||||
|
|
||||||
|
int MatchFinder_NeedMove(CMatchFinder *p);
|
||||||
|
Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p);
|
||||||
|
void MatchFinder_MoveBlock(CMatchFinder *p);
|
||||||
|
void MatchFinder_ReadIfRequired(CMatchFinder *p);
|
||||||
|
|
||||||
|
void MatchFinder_Construct(CMatchFinder *p);
|
||||||
|
|
||||||
|
/* Conditions:
|
||||||
|
historySize <= 3 GB
|
||||||
|
keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB
|
||||||
|
*/
|
||||||
|
int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
|
||||||
|
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
|
||||||
|
ISzAlloc *alloc);
|
||||||
|
void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc);
|
||||||
|
void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems);
|
||||||
|
void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue);
|
||||||
|
|
||||||
|
UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son,
|
||||||
|
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
|
||||||
|
UInt32 *distances, UInt32 maxLen);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Conditions:
|
||||||
|
Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func.
|
||||||
|
Mf_GetPointerToCurrentPos_Func's result must be used only before any other function
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef void (*Mf_Init_Func)(void *object);
|
||||||
|
typedef Byte (*Mf_GetIndexByte_Func)(void *object, Int32 index);
|
||||||
|
typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object);
|
||||||
|
typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object);
|
||||||
|
typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances);
|
||||||
|
typedef void (*Mf_Skip_Func)(void *object, UInt32);
|
||||||
|
|
||||||
|
typedef struct _IMatchFinder
|
||||||
|
{
|
||||||
|
Mf_Init_Func Init;
|
||||||
|
Mf_GetIndexByte_Func GetIndexByte;
|
||||||
|
Mf_GetNumAvailableBytes_Func GetNumAvailableBytes;
|
||||||
|
Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos;
|
||||||
|
Mf_GetMatches_Func GetMatches;
|
||||||
|
Mf_Skip_Func Skip;
|
||||||
|
} IMatchFinder;
|
||||||
|
|
||||||
|
void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);
|
||||||
|
|
||||||
|
void MatchFinder_Init(CMatchFinder *p);
|
||||||
|
UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
|
||||||
|
UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
|
||||||
|
void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
|
||||||
|
void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,793 @@
|
|||||||
|
/* LzFindMt.c -- multithreaded Match finder for LZ algorithms
|
||||||
|
2009-09-20 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#include "LzHash.h"
|
||||||
|
|
||||||
|
#include "LzFindMt.h"
|
||||||
|
|
||||||
|
void MtSync_Construct(CMtSync *p)
|
||||||
|
{
|
||||||
|
p->wasCreated = False;
|
||||||
|
p->csWasInitialized = False;
|
||||||
|
p->csWasEntered = False;
|
||||||
|
Thread_Construct(&p->thread);
|
||||||
|
Event_Construct(&p->canStart);
|
||||||
|
Event_Construct(&p->wasStarted);
|
||||||
|
Event_Construct(&p->wasStopped);
|
||||||
|
Semaphore_Construct(&p->freeSemaphore);
|
||||||
|
Semaphore_Construct(&p->filledSemaphore);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MtSync_GetNextBlock(CMtSync *p)
|
||||||
|
{
|
||||||
|
if (p->needStart)
|
||||||
|
{
|
||||||
|
p->numProcessedBlocks = 1;
|
||||||
|
p->needStart = False;
|
||||||
|
p->stopWriting = False;
|
||||||
|
p->exit = False;
|
||||||
|
Event_Reset(&p->wasStarted);
|
||||||
|
Event_Reset(&p->wasStopped);
|
||||||
|
|
||||||
|
Event_Set(&p->canStart);
|
||||||
|
Event_Wait(&p->wasStarted);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CriticalSection_Leave(&p->cs);
|
||||||
|
p->csWasEntered = False;
|
||||||
|
p->numProcessedBlocks++;
|
||||||
|
Semaphore_Release1(&p->freeSemaphore);
|
||||||
|
}
|
||||||
|
Semaphore_Wait(&p->filledSemaphore);
|
||||||
|
CriticalSection_Enter(&p->cs);
|
||||||
|
p->csWasEntered = True;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MtSync_StopWriting must be called if Writing was started */
|
||||||
|
|
||||||
|
void MtSync_StopWriting(CMtSync *p)
|
||||||
|
{
|
||||||
|
UInt32 myNumBlocks = p->numProcessedBlocks;
|
||||||
|
if (!Thread_WasCreated(&p->thread) || p->needStart)
|
||||||
|
return;
|
||||||
|
p->stopWriting = True;
|
||||||
|
if (p->csWasEntered)
|
||||||
|
{
|
||||||
|
CriticalSection_Leave(&p->cs);
|
||||||
|
p->csWasEntered = False;
|
||||||
|
}
|
||||||
|
Semaphore_Release1(&p->freeSemaphore);
|
||||||
|
|
||||||
|
Event_Wait(&p->wasStopped);
|
||||||
|
|
||||||
|
while (myNumBlocks++ != p->numProcessedBlocks)
|
||||||
|
{
|
||||||
|
Semaphore_Wait(&p->filledSemaphore);
|
||||||
|
Semaphore_Release1(&p->freeSemaphore);
|
||||||
|
}
|
||||||
|
p->needStart = True;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MtSync_Destruct(CMtSync *p)
|
||||||
|
{
|
||||||
|
if (Thread_WasCreated(&p->thread))
|
||||||
|
{
|
||||||
|
MtSync_StopWriting(p);
|
||||||
|
p->exit = True;
|
||||||
|
if (p->needStart)
|
||||||
|
Event_Set(&p->canStart);
|
||||||
|
Thread_Wait(&p->thread);
|
||||||
|
Thread_Close(&p->thread);
|
||||||
|
}
|
||||||
|
if (p->csWasInitialized)
|
||||||
|
{
|
||||||
|
CriticalSection_Delete(&p->cs);
|
||||||
|
p->csWasInitialized = False;
|
||||||
|
}
|
||||||
|
|
||||||
|
Event_Close(&p->canStart);
|
||||||
|
Event_Close(&p->wasStarted);
|
||||||
|
Event_Close(&p->wasStopped);
|
||||||
|
Semaphore_Close(&p->freeSemaphore);
|
||||||
|
Semaphore_Close(&p->filledSemaphore);
|
||||||
|
|
||||||
|
p->wasCreated = False;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define RINOK_THREAD(x) { if ((x) != 0) return SZ_ERROR_THREAD; }
|
||||||
|
|
||||||
|
static SRes MtSync_Create2(CMtSync *p, unsigned (MY_STD_CALL *startAddress)(void *), void *obj, UInt32 numBlocks)
|
||||||
|
{
|
||||||
|
if (p->wasCreated)
|
||||||
|
return SZ_OK;
|
||||||
|
|
||||||
|
RINOK_THREAD(CriticalSection_Init(&p->cs));
|
||||||
|
p->csWasInitialized = True;
|
||||||
|
|
||||||
|
RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->canStart));
|
||||||
|
RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->wasStarted));
|
||||||
|
RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->wasStopped));
|
||||||
|
|
||||||
|
RINOK_THREAD(Semaphore_Create(&p->freeSemaphore, numBlocks, numBlocks));
|
||||||
|
RINOK_THREAD(Semaphore_Create(&p->filledSemaphore, 0, numBlocks));
|
||||||
|
|
||||||
|
p->needStart = True;
|
||||||
|
|
||||||
|
RINOK_THREAD(Thread_Create(&p->thread, startAddress, obj));
|
||||||
|
p->wasCreated = True;
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SRes MtSync_Create(CMtSync *p, unsigned (MY_STD_CALL *startAddress)(void *), void *obj, UInt32 numBlocks)
|
||||||
|
{
|
||||||
|
SRes res = MtSync_Create2(p, startAddress, obj, numBlocks);
|
||||||
|
if (res != SZ_OK)
|
||||||
|
MtSync_Destruct(p);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MtSync_Init(CMtSync *p) { p->needStart = True; }
|
||||||
|
|
||||||
|
#define kMtMaxValForNormalize 0xFFFFFFFF
|
||||||
|
|
||||||
|
#define DEF_GetHeads2(name, v, action) \
|
||||||
|
static void GetHeads ## name(const Byte *p, UInt32 pos, \
|
||||||
|
UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc) \
|
||||||
|
{ action; for (; numHeads != 0; numHeads--) { \
|
||||||
|
const UInt32 value = (v); p++; *heads++ = pos - hash[value]; hash[value] = pos++; } }
|
||||||
|
|
||||||
|
#define DEF_GetHeads(name, v) DEF_GetHeads2(name, v, ;)
|
||||||
|
|
||||||
|
DEF_GetHeads2(2, (p[0] | ((UInt32)p[1] << 8)), hashMask = hashMask; crc = crc; )
|
||||||
|
DEF_GetHeads(3, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8)) & hashMask)
|
||||||
|
DEF_GetHeads(4, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (crc[p[3]] << 5)) & hashMask)
|
||||||
|
DEF_GetHeads(4b, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ ((UInt32)p[3] << 16)) & hashMask)
|
||||||
|
/* DEF_GetHeads(5, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (crc[p[3]] << 5) ^ (crc[p[4]] << 3)) & hashMask) */
|
||||||
|
|
||||||
|
void HashThreadFunc(CMatchFinderMt *mt)
|
||||||
|
{
|
||||||
|
CMtSync *p = &mt->hashSync;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
UInt32 numProcessedBlocks = 0;
|
||||||
|
Event_Wait(&p->canStart);
|
||||||
|
Event_Set(&p->wasStarted);
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (p->exit)
|
||||||
|
return;
|
||||||
|
if (p->stopWriting)
|
||||||
|
{
|
||||||
|
p->numProcessedBlocks = numProcessedBlocks;
|
||||||
|
Event_Set(&p->wasStopped);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
CMatchFinder *mf = mt->MatchFinder;
|
||||||
|
if (MatchFinder_NeedMove(mf))
|
||||||
|
{
|
||||||
|
CriticalSection_Enter(&mt->btSync.cs);
|
||||||
|
CriticalSection_Enter(&mt->hashSync.cs);
|
||||||
|
{
|
||||||
|
const Byte *beforePtr = MatchFinder_GetPointerToCurrentPos(mf);
|
||||||
|
const Byte *afterPtr;
|
||||||
|
MatchFinder_MoveBlock(mf);
|
||||||
|
afterPtr = MatchFinder_GetPointerToCurrentPos(mf);
|
||||||
|
mt->pointerToCurPos -= beforePtr - afterPtr;
|
||||||
|
mt->buffer -= beforePtr - afterPtr;
|
||||||
|
}
|
||||||
|
CriticalSection_Leave(&mt->btSync.cs);
|
||||||
|
CriticalSection_Leave(&mt->hashSync.cs);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Semaphore_Wait(&p->freeSemaphore);
|
||||||
|
|
||||||
|
MatchFinder_ReadIfRequired(mf);
|
||||||
|
if (mf->pos > (kMtMaxValForNormalize - kMtHashBlockSize))
|
||||||
|
{
|
||||||
|
UInt32 subValue = (mf->pos - mf->historySize - 1);
|
||||||
|
MatchFinder_ReduceOffsets(mf, subValue);
|
||||||
|
MatchFinder_Normalize3(subValue, mf->hash + mf->fixedHashSize, mf->hashMask + 1);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
UInt32 *heads = mt->hashBuf + ((numProcessedBlocks++) & kMtHashNumBlocksMask) * kMtHashBlockSize;
|
||||||
|
UInt32 num = mf->streamPos - mf->pos;
|
||||||
|
heads[0] = 2;
|
||||||
|
heads[1] = num;
|
||||||
|
if (num >= mf->numHashBytes)
|
||||||
|
{
|
||||||
|
num = num - mf->numHashBytes + 1;
|
||||||
|
if (num > kMtHashBlockSize - 2)
|
||||||
|
num = kMtHashBlockSize - 2;
|
||||||
|
mt->GetHeadsFunc(mf->buffer, mf->pos, mf->hash + mf->fixedHashSize, mf->hashMask, heads + 2, num, mf->crc);
|
||||||
|
heads[0] += num;
|
||||||
|
}
|
||||||
|
mf->pos += num;
|
||||||
|
mf->buffer += num;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Semaphore_Release1(&p->filledSemaphore);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatchFinderMt_GetNextBlock_Hash(CMatchFinderMt *p)
|
||||||
|
{
|
||||||
|
MtSync_GetNextBlock(&p->hashSync);
|
||||||
|
p->hashBufPosLimit = p->hashBufPos = ((p->hashSync.numProcessedBlocks - 1) & kMtHashNumBlocksMask) * kMtHashBlockSize;
|
||||||
|
p->hashBufPosLimit += p->hashBuf[p->hashBufPos++];
|
||||||
|
p->hashNumAvail = p->hashBuf[p->hashBufPos++];
|
||||||
|
}
|
||||||
|
|
||||||
|
#define kEmptyHashValue 0
|
||||||
|
|
||||||
|
/* #define MFMT_GM_INLINE */
|
||||||
|
|
||||||
|
#ifdef MFMT_GM_INLINE
|
||||||
|
|
||||||
|
#define NO_INLINE MY_FAST_CALL
|
||||||
|
|
||||||
|
Int32 NO_INLINE GetMatchesSpecN(UInt32 lenLimit, UInt32 pos, const Byte *cur, CLzRef *son,
|
||||||
|
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
|
||||||
|
UInt32 *_distances, UInt32 _maxLen, const UInt32 *hash, Int32 limit, UInt32 size, UInt32 *posRes)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
UInt32 *distances = _distances + 1;
|
||||||
|
UInt32 curMatch = pos - *hash++;
|
||||||
|
|
||||||
|
CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
|
||||||
|
CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
|
||||||
|
UInt32 len0 = 0, len1 = 0;
|
||||||
|
UInt32 cutValue = _cutValue;
|
||||||
|
UInt32 maxLen = _maxLen;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
UInt32 delta = pos - curMatch;
|
||||||
|
if (cutValue-- == 0 || delta >= _cyclicBufferSize)
|
||||||
|
{
|
||||||
|
*ptr0 = *ptr1 = kEmptyHashValue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
|
||||||
|
const Byte *pb = cur - delta;
|
||||||
|
UInt32 len = (len0 < len1 ? len0 : len1);
|
||||||
|
if (pb[len] == cur[len])
|
||||||
|
{
|
||||||
|
if (++len != lenLimit && pb[len] == cur[len])
|
||||||
|
while (++len != lenLimit)
|
||||||
|
if (pb[len] != cur[len])
|
||||||
|
break;
|
||||||
|
if (maxLen < len)
|
||||||
|
{
|
||||||
|
*distances++ = maxLen = len;
|
||||||
|
*distances++ = delta - 1;
|
||||||
|
if (len == lenLimit)
|
||||||
|
{
|
||||||
|
*ptr1 = pair[0];
|
||||||
|
*ptr0 = pair[1];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pb[len] < cur[len])
|
||||||
|
{
|
||||||
|
*ptr1 = curMatch;
|
||||||
|
ptr1 = pair + 1;
|
||||||
|
curMatch = *ptr1;
|
||||||
|
len1 = len;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*ptr0 = curMatch;
|
||||||
|
ptr0 = pair;
|
||||||
|
curMatch = *ptr0;
|
||||||
|
len0 = len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pos++;
|
||||||
|
_cyclicBufferPos++;
|
||||||
|
cur++;
|
||||||
|
{
|
||||||
|
UInt32 num = (UInt32)(distances - _distances);
|
||||||
|
*_distances = num - 1;
|
||||||
|
_distances += num;
|
||||||
|
limit -= num;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (limit > 0 && --size != 0);
|
||||||
|
*posRes = pos;
|
||||||
|
return limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
|
||||||
|
{
|
||||||
|
UInt32 numProcessed = 0;
|
||||||
|
UInt32 curPos = 2;
|
||||||
|
UInt32 limit = kMtBtBlockSize - (p->matchMaxLen * 2);
|
||||||
|
distances[1] = p->hashNumAvail;
|
||||||
|
while (curPos < limit)
|
||||||
|
{
|
||||||
|
if (p->hashBufPos == p->hashBufPosLimit)
|
||||||
|
{
|
||||||
|
MatchFinderMt_GetNextBlock_Hash(p);
|
||||||
|
distances[1] = numProcessed + p->hashNumAvail;
|
||||||
|
if (p->hashNumAvail >= p->numHashBytes)
|
||||||
|
continue;
|
||||||
|
for (; p->hashNumAvail != 0; p->hashNumAvail--)
|
||||||
|
distances[curPos++] = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
UInt32 size = p->hashBufPosLimit - p->hashBufPos;
|
||||||
|
UInt32 lenLimit = p->matchMaxLen;
|
||||||
|
UInt32 pos = p->pos;
|
||||||
|
UInt32 cyclicBufferPos = p->cyclicBufferPos;
|
||||||
|
if (lenLimit >= p->hashNumAvail)
|
||||||
|
lenLimit = p->hashNumAvail;
|
||||||
|
{
|
||||||
|
UInt32 size2 = p->hashNumAvail - lenLimit + 1;
|
||||||
|
if (size2 < size)
|
||||||
|
size = size2;
|
||||||
|
size2 = p->cyclicBufferSize - cyclicBufferPos;
|
||||||
|
if (size2 < size)
|
||||||
|
size = size2;
|
||||||
|
}
|
||||||
|
#ifndef MFMT_GM_INLINE
|
||||||
|
while (curPos < limit && size-- != 0)
|
||||||
|
{
|
||||||
|
UInt32 *startDistances = distances + curPos;
|
||||||
|
UInt32 num = (UInt32)(GetMatchesSpec1(lenLimit, pos - p->hashBuf[p->hashBufPos++],
|
||||||
|
pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue,
|
||||||
|
startDistances + 1, p->numHashBytes - 1) - startDistances);
|
||||||
|
*startDistances = num - 1;
|
||||||
|
curPos += num;
|
||||||
|
cyclicBufferPos++;
|
||||||
|
pos++;
|
||||||
|
p->buffer++;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
UInt32 posRes;
|
||||||
|
curPos = limit - GetMatchesSpecN(lenLimit, pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue,
|
||||||
|
distances + curPos, p->numHashBytes - 1, p->hashBuf + p->hashBufPos, (Int32)(limit - curPos) , size, &posRes);
|
||||||
|
p->hashBufPos += posRes - pos;
|
||||||
|
cyclicBufferPos += posRes - pos;
|
||||||
|
p->buffer += posRes - pos;
|
||||||
|
pos = posRes;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
numProcessed += pos - p->pos;
|
||||||
|
p->hashNumAvail -= pos - p->pos;
|
||||||
|
p->pos = pos;
|
||||||
|
if (cyclicBufferPos == p->cyclicBufferSize)
|
||||||
|
cyclicBufferPos = 0;
|
||||||
|
p->cyclicBufferPos = cyclicBufferPos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
distances[0] = curPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BtFillBlock(CMatchFinderMt *p, UInt32 globalBlockIndex)
|
||||||
|
{
|
||||||
|
CMtSync *sync = &p->hashSync;
|
||||||
|
if (!sync->needStart)
|
||||||
|
{
|
||||||
|
CriticalSection_Enter(&sync->cs);
|
||||||
|
sync->csWasEntered = True;
|
||||||
|
}
|
||||||
|
|
||||||
|
BtGetMatches(p, p->btBuf + (globalBlockIndex & kMtBtNumBlocksMask) * kMtBtBlockSize);
|
||||||
|
|
||||||
|
if (p->pos > kMtMaxValForNormalize - kMtBtBlockSize)
|
||||||
|
{
|
||||||
|
UInt32 subValue = p->pos - p->cyclicBufferSize;
|
||||||
|
MatchFinder_Normalize3(subValue, p->son, p->cyclicBufferSize * 2);
|
||||||
|
p->pos -= subValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sync->needStart)
|
||||||
|
{
|
||||||
|
CriticalSection_Leave(&sync->cs);
|
||||||
|
sync->csWasEntered = False;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BtThreadFunc(CMatchFinderMt *mt)
|
||||||
|
{
|
||||||
|
CMtSync *p = &mt->btSync;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
UInt32 blockIndex = 0;
|
||||||
|
Event_Wait(&p->canStart);
|
||||||
|
Event_Set(&p->wasStarted);
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (p->exit)
|
||||||
|
return;
|
||||||
|
if (p->stopWriting)
|
||||||
|
{
|
||||||
|
p->numProcessedBlocks = blockIndex;
|
||||||
|
MtSync_StopWriting(&mt->hashSync);
|
||||||
|
Event_Set(&p->wasStopped);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Semaphore_Wait(&p->freeSemaphore);
|
||||||
|
BtFillBlock(mt, blockIndex++);
|
||||||
|
Semaphore_Release1(&p->filledSemaphore);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatchFinderMt_Construct(CMatchFinderMt *p)
|
||||||
|
{
|
||||||
|
p->hashBuf = 0;
|
||||||
|
MtSync_Construct(&p->hashSync);
|
||||||
|
MtSync_Construct(&p->btSync);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatchFinderMt_FreeMem(CMatchFinderMt *p, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
alloc->Free(alloc, p->hashBuf);
|
||||||
|
p->hashBuf = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
MtSync_Destruct(&p->hashSync);
|
||||||
|
MtSync_Destruct(&p->btSync);
|
||||||
|
MatchFinderMt_FreeMem(p, alloc);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define kHashBufferSize (kMtHashBlockSize * kMtHashNumBlocks)
|
||||||
|
#define kBtBufferSize (kMtBtBlockSize * kMtBtNumBlocks)
|
||||||
|
|
||||||
|
static unsigned MY_STD_CALL HashThreadFunc2(void *p) { HashThreadFunc((CMatchFinderMt *)p); return 0; }
|
||||||
|
static unsigned MY_STD_CALL BtThreadFunc2(void *p)
|
||||||
|
{
|
||||||
|
Byte allocaDummy[0x180];
|
||||||
|
int i = 0;
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
allocaDummy[i] = (Byte)i;
|
||||||
|
BtThreadFunc((CMatchFinderMt *)p);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore,
|
||||||
|
UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
CMatchFinder *mf = p->MatchFinder;
|
||||||
|
p->historySize = historySize;
|
||||||
|
if (kMtBtBlockSize <= matchMaxLen * 4)
|
||||||
|
return SZ_ERROR_PARAM;
|
||||||
|
if (p->hashBuf == 0)
|
||||||
|
{
|
||||||
|
p->hashBuf = (UInt32 *)alloc->Alloc(alloc, (kHashBufferSize + kBtBufferSize) * sizeof(UInt32));
|
||||||
|
if (p->hashBuf == 0)
|
||||||
|
return SZ_ERROR_MEM;
|
||||||
|
p->btBuf = p->hashBuf + kHashBufferSize;
|
||||||
|
}
|
||||||
|
keepAddBufferBefore += (kHashBufferSize + kBtBufferSize);
|
||||||
|
keepAddBufferAfter += kMtHashBlockSize;
|
||||||
|
if (!MatchFinder_Create(mf, historySize, keepAddBufferBefore, matchMaxLen, keepAddBufferAfter, alloc))
|
||||||
|
return SZ_ERROR_MEM;
|
||||||
|
|
||||||
|
RINOK(MtSync_Create(&p->hashSync, HashThreadFunc2, p, kMtHashNumBlocks));
|
||||||
|
RINOK(MtSync_Create(&p->btSync, BtThreadFunc2, p, kMtBtNumBlocks));
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Call it after ReleaseStream / SetStream */
|
||||||
|
void MatchFinderMt_Init(CMatchFinderMt *p)
|
||||||
|
{
|
||||||
|
CMatchFinder *mf = p->MatchFinder;
|
||||||
|
p->btBufPos = p->btBufPosLimit = 0;
|
||||||
|
p->hashBufPos = p->hashBufPosLimit = 0;
|
||||||
|
MatchFinder_Init(mf);
|
||||||
|
p->pointerToCurPos = MatchFinder_GetPointerToCurrentPos(mf);
|
||||||
|
p->btNumAvailBytes = 0;
|
||||||
|
p->lzPos = p->historySize + 1;
|
||||||
|
|
||||||
|
p->hash = mf->hash;
|
||||||
|
p->fixedHashSize = mf->fixedHashSize;
|
||||||
|
p->crc = mf->crc;
|
||||||
|
|
||||||
|
p->son = mf->son;
|
||||||
|
p->matchMaxLen = mf->matchMaxLen;
|
||||||
|
p->numHashBytes = mf->numHashBytes;
|
||||||
|
p->pos = mf->pos;
|
||||||
|
p->buffer = mf->buffer;
|
||||||
|
p->cyclicBufferPos = mf->cyclicBufferPos;
|
||||||
|
p->cyclicBufferSize = mf->cyclicBufferSize;
|
||||||
|
p->cutValue = mf->cutValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ReleaseStream is required to finish multithreading */
|
||||||
|
void MatchFinderMt_ReleaseStream(CMatchFinderMt *p)
|
||||||
|
{
|
||||||
|
MtSync_StopWriting(&p->btSync);
|
||||||
|
/* p->MatchFinder->ReleaseStream(); */
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatchFinderMt_Normalize(CMatchFinderMt *p)
|
||||||
|
{
|
||||||
|
MatchFinder_Normalize3(p->lzPos - p->historySize - 1, p->hash, p->fixedHashSize);
|
||||||
|
p->lzPos = p->historySize + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatchFinderMt_GetNextBlock_Bt(CMatchFinderMt *p)
|
||||||
|
{
|
||||||
|
UInt32 blockIndex;
|
||||||
|
MtSync_GetNextBlock(&p->btSync);
|
||||||
|
blockIndex = ((p->btSync.numProcessedBlocks - 1) & kMtBtNumBlocksMask);
|
||||||
|
p->btBufPosLimit = p->btBufPos = blockIndex * kMtBtBlockSize;
|
||||||
|
p->btBufPosLimit += p->btBuf[p->btBufPos++];
|
||||||
|
p->btNumAvailBytes = p->btBuf[p->btBufPos++];
|
||||||
|
if (p->lzPos >= kMtMaxValForNormalize - kMtBtBlockSize)
|
||||||
|
MatchFinderMt_Normalize(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Byte * MatchFinderMt_GetPointerToCurrentPos(CMatchFinderMt *p)
|
||||||
|
{
|
||||||
|
return p->pointerToCurPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define GET_NEXT_BLOCK_IF_REQUIRED if (p->btBufPos == p->btBufPosLimit) MatchFinderMt_GetNextBlock_Bt(p);
|
||||||
|
|
||||||
|
UInt32 MatchFinderMt_GetNumAvailableBytes(CMatchFinderMt *p)
|
||||||
|
{
|
||||||
|
GET_NEXT_BLOCK_IF_REQUIRED;
|
||||||
|
return p->btNumAvailBytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
Byte MatchFinderMt_GetIndexByte(CMatchFinderMt *p, Int32 index)
|
||||||
|
{
|
||||||
|
return p->pointerToCurPos[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt32 * MixMatches2(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
|
||||||
|
{
|
||||||
|
UInt32 hash2Value, curMatch2;
|
||||||
|
UInt32 *hash = p->hash;
|
||||||
|
const Byte *cur = p->pointerToCurPos;
|
||||||
|
UInt32 lzPos = p->lzPos;
|
||||||
|
MT_HASH2_CALC
|
||||||
|
|
||||||
|
curMatch2 = hash[hash2Value];
|
||||||
|
hash[hash2Value] = lzPos;
|
||||||
|
|
||||||
|
if (curMatch2 >= matchMinPos)
|
||||||
|
if (cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
|
||||||
|
{
|
||||||
|
*distances++ = 2;
|
||||||
|
*distances++ = lzPos - curMatch2 - 1;
|
||||||
|
}
|
||||||
|
return distances;
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt32 * MixMatches3(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
|
||||||
|
{
|
||||||
|
UInt32 hash2Value, hash3Value, curMatch2, curMatch3;
|
||||||
|
UInt32 *hash = p->hash;
|
||||||
|
const Byte *cur = p->pointerToCurPos;
|
||||||
|
UInt32 lzPos = p->lzPos;
|
||||||
|
MT_HASH3_CALC
|
||||||
|
|
||||||
|
curMatch2 = hash[ hash2Value];
|
||||||
|
curMatch3 = hash[kFix3HashSize + hash3Value];
|
||||||
|
|
||||||
|
hash[ hash2Value] =
|
||||||
|
hash[kFix3HashSize + hash3Value] =
|
||||||
|
lzPos;
|
||||||
|
|
||||||
|
if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
|
||||||
|
{
|
||||||
|
distances[1] = lzPos - curMatch2 - 1;
|
||||||
|
if (cur[(ptrdiff_t)curMatch2 - lzPos + 2] == cur[2])
|
||||||
|
{
|
||||||
|
distances[0] = 3;
|
||||||
|
return distances + 2;
|
||||||
|
}
|
||||||
|
distances[0] = 2;
|
||||||
|
distances += 2;
|
||||||
|
}
|
||||||
|
if (curMatch3 >= matchMinPos && cur[(ptrdiff_t)curMatch3 - lzPos] == cur[0])
|
||||||
|
{
|
||||||
|
*distances++ = 3;
|
||||||
|
*distances++ = lzPos - curMatch3 - 1;
|
||||||
|
}
|
||||||
|
return distances;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
UInt32 *MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
|
||||||
|
{
|
||||||
|
UInt32 hash2Value, hash3Value, hash4Value, curMatch2, curMatch3, curMatch4;
|
||||||
|
UInt32 *hash = p->hash;
|
||||||
|
const Byte *cur = p->pointerToCurPos;
|
||||||
|
UInt32 lzPos = p->lzPos;
|
||||||
|
MT_HASH4_CALC
|
||||||
|
|
||||||
|
curMatch2 = hash[ hash2Value];
|
||||||
|
curMatch3 = hash[kFix3HashSize + hash3Value];
|
||||||
|
curMatch4 = hash[kFix4HashSize + hash4Value];
|
||||||
|
|
||||||
|
hash[ hash2Value] =
|
||||||
|
hash[kFix3HashSize + hash3Value] =
|
||||||
|
hash[kFix4HashSize + hash4Value] =
|
||||||
|
lzPos;
|
||||||
|
|
||||||
|
if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
|
||||||
|
{
|
||||||
|
distances[1] = lzPos - curMatch2 - 1;
|
||||||
|
if (cur[(ptrdiff_t)curMatch2 - lzPos + 2] == cur[2])
|
||||||
|
{
|
||||||
|
distances[0] = (cur[(ptrdiff_t)curMatch2 - lzPos + 3] == cur[3]) ? 4 : 3;
|
||||||
|
return distances + 2;
|
||||||
|
}
|
||||||
|
distances[0] = 2;
|
||||||
|
distances += 2;
|
||||||
|
}
|
||||||
|
if (curMatch3 >= matchMinPos && cur[(ptrdiff_t)curMatch3 - lzPos] == cur[0])
|
||||||
|
{
|
||||||
|
distances[1] = lzPos - curMatch3 - 1;
|
||||||
|
if (cur[(ptrdiff_t)curMatch3 - lzPos + 3] == cur[3])
|
||||||
|
{
|
||||||
|
distances[0] = 4;
|
||||||
|
return distances + 2;
|
||||||
|
}
|
||||||
|
distances[0] = 3;
|
||||||
|
distances += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (curMatch4 >= matchMinPos)
|
||||||
|
if (
|
||||||
|
cur[(ptrdiff_t)curMatch4 - lzPos] == cur[0] &&
|
||||||
|
cur[(ptrdiff_t)curMatch4 - lzPos + 3] == cur[3]
|
||||||
|
)
|
||||||
|
{
|
||||||
|
*distances++ = 4;
|
||||||
|
*distances++ = lzPos - curMatch4 - 1;
|
||||||
|
}
|
||||||
|
return distances;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define INCREASE_LZ_POS p->lzPos++; p->pointerToCurPos++;
|
||||||
|
|
||||||
|
UInt32 MatchFinderMt2_GetMatches(CMatchFinderMt *p, UInt32 *distances)
|
||||||
|
{
|
||||||
|
const UInt32 *btBuf = p->btBuf + p->btBufPos;
|
||||||
|
UInt32 len = *btBuf++;
|
||||||
|
p->btBufPos += 1 + len;
|
||||||
|
p->btNumAvailBytes--;
|
||||||
|
{
|
||||||
|
UInt32 i;
|
||||||
|
for (i = 0; i < len; i += 2)
|
||||||
|
{
|
||||||
|
*distances++ = *btBuf++;
|
||||||
|
*distances++ = *btBuf++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
INCREASE_LZ_POS
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances)
|
||||||
|
{
|
||||||
|
const UInt32 *btBuf = p->btBuf + p->btBufPos;
|
||||||
|
UInt32 len = *btBuf++;
|
||||||
|
p->btBufPos += 1 + len;
|
||||||
|
|
||||||
|
if (len == 0)
|
||||||
|
{
|
||||||
|
if (p->btNumAvailBytes-- >= 4)
|
||||||
|
len = (UInt32)(p->MixMatchesFunc(p, p->lzPos - p->historySize, distances) - (distances));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Condition: there are matches in btBuf with length < p->numHashBytes */
|
||||||
|
UInt32 *distances2;
|
||||||
|
p->btNumAvailBytes--;
|
||||||
|
distances2 = p->MixMatchesFunc(p, p->lzPos - btBuf[1], distances);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
*distances2++ = *btBuf++;
|
||||||
|
*distances2++ = *btBuf++;
|
||||||
|
}
|
||||||
|
while ((len -= 2) != 0);
|
||||||
|
len = (UInt32)(distances2 - (distances));
|
||||||
|
}
|
||||||
|
INCREASE_LZ_POS
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SKIP_HEADER2_MT do { GET_NEXT_BLOCK_IF_REQUIRED
|
||||||
|
#define SKIP_HEADER_MT(n) SKIP_HEADER2_MT if (p->btNumAvailBytes-- >= (n)) { const Byte *cur = p->pointerToCurPos; UInt32 *hash = p->hash;
|
||||||
|
#define SKIP_FOOTER_MT } INCREASE_LZ_POS p->btBufPos += p->btBuf[p->btBufPos] + 1; } while (--num != 0);
|
||||||
|
|
||||||
|
void MatchFinderMt0_Skip(CMatchFinderMt *p, UInt32 num)
|
||||||
|
{
|
||||||
|
SKIP_HEADER2_MT { p->btNumAvailBytes--;
|
||||||
|
SKIP_FOOTER_MT
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatchFinderMt2_Skip(CMatchFinderMt *p, UInt32 num)
|
||||||
|
{
|
||||||
|
SKIP_HEADER_MT(2)
|
||||||
|
UInt32 hash2Value;
|
||||||
|
MT_HASH2_CALC
|
||||||
|
hash[hash2Value] = p->lzPos;
|
||||||
|
SKIP_FOOTER_MT
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatchFinderMt3_Skip(CMatchFinderMt *p, UInt32 num)
|
||||||
|
{
|
||||||
|
SKIP_HEADER_MT(3)
|
||||||
|
UInt32 hash2Value, hash3Value;
|
||||||
|
MT_HASH3_CALC
|
||||||
|
hash[kFix3HashSize + hash3Value] =
|
||||||
|
hash[ hash2Value] =
|
||||||
|
p->lzPos;
|
||||||
|
SKIP_FOOTER_MT
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
void MatchFinderMt4_Skip(CMatchFinderMt *p, UInt32 num)
|
||||||
|
{
|
||||||
|
SKIP_HEADER_MT(4)
|
||||||
|
UInt32 hash2Value, hash3Value, hash4Value;
|
||||||
|
MT_HASH4_CALC
|
||||||
|
hash[kFix4HashSize + hash4Value] =
|
||||||
|
hash[kFix3HashSize + hash3Value] =
|
||||||
|
hash[ hash2Value] =
|
||||||
|
p->lzPos;
|
||||||
|
SKIP_FOOTER_MT
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable)
|
||||||
|
{
|
||||||
|
vTable->Init = (Mf_Init_Func)MatchFinderMt_Init;
|
||||||
|
vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinderMt_GetIndexByte;
|
||||||
|
vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinderMt_GetNumAvailableBytes;
|
||||||
|
vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinderMt_GetPointerToCurrentPos;
|
||||||
|
vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt_GetMatches;
|
||||||
|
switch(p->MatchFinder->numHashBytes)
|
||||||
|
{
|
||||||
|
case 2:
|
||||||
|
p->GetHeadsFunc = GetHeads2;
|
||||||
|
p->MixMatchesFunc = (Mf_Mix_Matches)0;
|
||||||
|
vTable->Skip = (Mf_Skip_Func)MatchFinderMt0_Skip;
|
||||||
|
vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt2_GetMatches;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
p->GetHeadsFunc = GetHeads3;
|
||||||
|
p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches2;
|
||||||
|
vTable->Skip = (Mf_Skip_Func)MatchFinderMt2_Skip;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* case 4: */
|
||||||
|
p->GetHeadsFunc = p->MatchFinder->bigHash ? GetHeads4b : GetHeads4;
|
||||||
|
/* p->GetHeadsFunc = GetHeads4; */
|
||||||
|
p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches3;
|
||||||
|
vTable->Skip = (Mf_Skip_Func)MatchFinderMt3_Skip;
|
||||||
|
break;
|
||||||
|
/*
|
||||||
|
default:
|
||||||
|
p->GetHeadsFunc = GetHeads5;
|
||||||
|
p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches4;
|
||||||
|
vTable->Skip = (Mf_Skip_Func)MatchFinderMt4_Skip;
|
||||||
|
break;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
/* LzFindMt.h -- multithreaded Match finder for LZ algorithms
|
||||||
|
2009-02-07 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#ifndef __LZ_FIND_MT_H
|
||||||
|
#define __LZ_FIND_MT_H
|
||||||
|
|
||||||
|
#include "LzFind.h"
|
||||||
|
#include "Threads.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define kMtHashBlockSize (1 << 13)
|
||||||
|
#define kMtHashNumBlocks (1 << 3)
|
||||||
|
#define kMtHashNumBlocksMask (kMtHashNumBlocks - 1)
|
||||||
|
|
||||||
|
#define kMtBtBlockSize (1 << 14)
|
||||||
|
#define kMtBtNumBlocks (1 << 6)
|
||||||
|
#define kMtBtNumBlocksMask (kMtBtNumBlocks - 1)
|
||||||
|
|
||||||
|
typedef struct _CMtSync
|
||||||
|
{
|
||||||
|
Bool wasCreated;
|
||||||
|
Bool needStart;
|
||||||
|
Bool exit;
|
||||||
|
Bool stopWriting;
|
||||||
|
|
||||||
|
CThread thread;
|
||||||
|
CAutoResetEvent canStart;
|
||||||
|
CAutoResetEvent wasStarted;
|
||||||
|
CAutoResetEvent wasStopped;
|
||||||
|
CSemaphore freeSemaphore;
|
||||||
|
CSemaphore filledSemaphore;
|
||||||
|
Bool csWasInitialized;
|
||||||
|
Bool csWasEntered;
|
||||||
|
CCriticalSection cs;
|
||||||
|
UInt32 numProcessedBlocks;
|
||||||
|
} CMtSync;
|
||||||
|
|
||||||
|
typedef UInt32 * (*Mf_Mix_Matches)(void *p, UInt32 matchMinPos, UInt32 *distances);
|
||||||
|
|
||||||
|
/* kMtCacheLineDummy must be >= size_of_CPU_cache_line */
|
||||||
|
#define kMtCacheLineDummy 128
|
||||||
|
|
||||||
|
typedef void (*Mf_GetHeads)(const Byte *buffer, UInt32 pos,
|
||||||
|
UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc);
|
||||||
|
|
||||||
|
typedef struct _CMatchFinderMt
|
||||||
|
{
|
||||||
|
/* LZ */
|
||||||
|
const Byte *pointerToCurPos;
|
||||||
|
UInt32 *btBuf;
|
||||||
|
UInt32 btBufPos;
|
||||||
|
UInt32 btBufPosLimit;
|
||||||
|
UInt32 lzPos;
|
||||||
|
UInt32 btNumAvailBytes;
|
||||||
|
|
||||||
|
UInt32 *hash;
|
||||||
|
UInt32 fixedHashSize;
|
||||||
|
UInt32 historySize;
|
||||||
|
const UInt32 *crc;
|
||||||
|
|
||||||
|
Mf_Mix_Matches MixMatchesFunc;
|
||||||
|
|
||||||
|
/* LZ + BT */
|
||||||
|
CMtSync btSync;
|
||||||
|
Byte btDummy[kMtCacheLineDummy];
|
||||||
|
|
||||||
|
/* BT */
|
||||||
|
UInt32 *hashBuf;
|
||||||
|
UInt32 hashBufPos;
|
||||||
|
UInt32 hashBufPosLimit;
|
||||||
|
UInt32 hashNumAvail;
|
||||||
|
|
||||||
|
CLzRef *son;
|
||||||
|
UInt32 matchMaxLen;
|
||||||
|
UInt32 numHashBytes;
|
||||||
|
UInt32 pos;
|
||||||
|
Byte *buffer;
|
||||||
|
UInt32 cyclicBufferPos;
|
||||||
|
UInt32 cyclicBufferSize; /* it must be historySize + 1 */
|
||||||
|
UInt32 cutValue;
|
||||||
|
|
||||||
|
/* BT + Hash */
|
||||||
|
CMtSync hashSync;
|
||||||
|
/* Byte hashDummy[kMtCacheLineDummy]; */
|
||||||
|
|
||||||
|
/* Hash */
|
||||||
|
Mf_GetHeads GetHeadsFunc;
|
||||||
|
CMatchFinder *MatchFinder;
|
||||||
|
} CMatchFinderMt;
|
||||||
|
|
||||||
|
void MatchFinderMt_Construct(CMatchFinderMt *p);
|
||||||
|
void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc);
|
||||||
|
SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore,
|
||||||
|
UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAlloc *alloc);
|
||||||
|
void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable);
|
||||||
|
void MatchFinderMt_ReleaseStream(CMatchFinderMt *p);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
/* LzHash.h -- HASH functions for LZ algorithms
|
||||||
|
2009-02-07 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#ifndef __LZ_HASH_H
|
||||||
|
#define __LZ_HASH_H
|
||||||
|
|
||||||
|
#define kHash2Size (1 << 10)
|
||||||
|
#define kHash3Size (1 << 16)
|
||||||
|
#define kHash4Size (1 << 20)
|
||||||
|
|
||||||
|
#define kFix3HashSize (kHash2Size)
|
||||||
|
#define kFix4HashSize (kHash2Size + kHash3Size)
|
||||||
|
#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size)
|
||||||
|
|
||||||
|
#define HASH2_CALC hashValue = cur[0] | ((UInt32)cur[1] << 8);
|
||||||
|
|
||||||
|
#define HASH3_CALC { \
|
||||||
|
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
||||||
|
hash2Value = temp & (kHash2Size - 1); \
|
||||||
|
hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; }
|
||||||
|
|
||||||
|
#define HASH4_CALC { \
|
||||||
|
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
||||||
|
hash2Value = temp & (kHash2Size - 1); \
|
||||||
|
hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
|
||||||
|
hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & p->hashMask; }
|
||||||
|
|
||||||
|
#define HASH5_CALC { \
|
||||||
|
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
||||||
|
hash2Value = temp & (kHash2Size - 1); \
|
||||||
|
hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
|
||||||
|
hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)); \
|
||||||
|
hashValue = (hash4Value ^ (p->crc[cur[4]] << 3)) & p->hashMask; \
|
||||||
|
hash4Value &= (kHash4Size - 1); }
|
||||||
|
|
||||||
|
/* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */
|
||||||
|
#define HASH_ZIP_CALC hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF;
|
||||||
|
|
||||||
|
|
||||||
|
#define MT_HASH2_CALC \
|
||||||
|
hash2Value = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1);
|
||||||
|
|
||||||
|
#define MT_HASH3_CALC { \
|
||||||
|
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
||||||
|
hash2Value = temp & (kHash2Size - 1); \
|
||||||
|
hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); }
|
||||||
|
|
||||||
|
#define MT_HASH4_CALC { \
|
||||||
|
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
||||||
|
hash2Value = temp & (kHash2Size - 1); \
|
||||||
|
hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
|
||||||
|
hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); }
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,356 @@
|
|||||||
|
/* Lzma2Dec.c -- LZMA2 Decoder
|
||||||
|
2009-05-03 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
/* #define SHOW_DEBUG_INFO */
|
||||||
|
|
||||||
|
#ifdef SHOW_DEBUG_INFO
|
||||||
|
#include <stdio.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "Lzma2Dec.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
00000000 - EOS
|
||||||
|
00000001 U U - Uncompressed Reset Dic
|
||||||
|
00000010 U U - Uncompressed No Reset
|
||||||
|
100uuuuu U U P P - LZMA no reset
|
||||||
|
101uuuuu U U P P - LZMA reset state
|
||||||
|
110uuuuu U U P P S - LZMA reset state + new prop
|
||||||
|
111uuuuu U U P P S - LZMA reset state + new prop + reset dic
|
||||||
|
|
||||||
|
u, U - Unpack Size
|
||||||
|
P - Pack Size
|
||||||
|
S - Props
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LZMA2_CONTROL_LZMA (1 << 7)
|
||||||
|
#define LZMA2_CONTROL_COPY_NO_RESET 2
|
||||||
|
#define LZMA2_CONTROL_COPY_RESET_DIC 1
|
||||||
|
#define LZMA2_CONTROL_EOF 0
|
||||||
|
|
||||||
|
#define LZMA2_IS_UNCOMPRESSED_STATE(p) (((p)->control & LZMA2_CONTROL_LZMA) == 0)
|
||||||
|
|
||||||
|
#define LZMA2_GET_LZMA_MODE(p) (((p)->control >> 5) & 3)
|
||||||
|
#define LZMA2_IS_THERE_PROP(mode) ((mode) >= 2)
|
||||||
|
|
||||||
|
#define LZMA2_LCLP_MAX 4
|
||||||
|
#define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11))
|
||||||
|
|
||||||
|
#ifdef SHOW_DEBUG_INFO
|
||||||
|
#define PRF(x) x
|
||||||
|
#else
|
||||||
|
#define PRF(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
LZMA2_STATE_CONTROL,
|
||||||
|
LZMA2_STATE_UNPACK0,
|
||||||
|
LZMA2_STATE_UNPACK1,
|
||||||
|
LZMA2_STATE_PACK0,
|
||||||
|
LZMA2_STATE_PACK1,
|
||||||
|
LZMA2_STATE_PROP,
|
||||||
|
LZMA2_STATE_DATA,
|
||||||
|
LZMA2_STATE_DATA_CONT,
|
||||||
|
LZMA2_STATE_FINISHED,
|
||||||
|
LZMA2_STATE_ERROR
|
||||||
|
} ELzma2State;
|
||||||
|
|
||||||
|
static SRes Lzma2Dec_GetOldProps(Byte prop, Byte *props)
|
||||||
|
{
|
||||||
|
UInt32 dicSize;
|
||||||
|
if (prop > 40)
|
||||||
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
|
dicSize = (prop == 40) ? 0xFFFFFFFF : LZMA2_DIC_SIZE_FROM_PROP(prop);
|
||||||
|
props[0] = (Byte)LZMA2_LCLP_MAX;
|
||||||
|
props[1] = (Byte)(dicSize);
|
||||||
|
props[2] = (Byte)(dicSize >> 8);
|
||||||
|
props[3] = (Byte)(dicSize >> 16);
|
||||||
|
props[4] = (Byte)(dicSize >> 24);
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
Byte props[LZMA_PROPS_SIZE];
|
||||||
|
RINOK(Lzma2Dec_GetOldProps(prop, props));
|
||||||
|
return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
|
||||||
|
}
|
||||||
|
|
||||||
|
SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
Byte props[LZMA_PROPS_SIZE];
|
||||||
|
RINOK(Lzma2Dec_GetOldProps(prop, props));
|
||||||
|
return LzmaDec_Allocate(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Lzma2Dec_Init(CLzma2Dec *p)
|
||||||
|
{
|
||||||
|
p->state = LZMA2_STATE_CONTROL;
|
||||||
|
p->needInitDic = True;
|
||||||
|
p->needInitState = True;
|
||||||
|
p->needInitProp = True;
|
||||||
|
LzmaDec_Init(&p->decoder);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
|
||||||
|
{
|
||||||
|
switch(p->state)
|
||||||
|
{
|
||||||
|
case LZMA2_STATE_CONTROL:
|
||||||
|
p->control = b;
|
||||||
|
PRF(printf("\n %4X ", p->decoder.dicPos));
|
||||||
|
PRF(printf(" %2X", b));
|
||||||
|
if (p->control == 0)
|
||||||
|
return LZMA2_STATE_FINISHED;
|
||||||
|
if (LZMA2_IS_UNCOMPRESSED_STATE(p))
|
||||||
|
{
|
||||||
|
if ((p->control & 0x7F) > 2)
|
||||||
|
return LZMA2_STATE_ERROR;
|
||||||
|
p->unpackSize = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
p->unpackSize = (UInt32)(p->control & 0x1F) << 16;
|
||||||
|
return LZMA2_STATE_UNPACK0;
|
||||||
|
|
||||||
|
case LZMA2_STATE_UNPACK0:
|
||||||
|
p->unpackSize |= (UInt32)b << 8;
|
||||||
|
return LZMA2_STATE_UNPACK1;
|
||||||
|
|
||||||
|
case LZMA2_STATE_UNPACK1:
|
||||||
|
p->unpackSize |= (UInt32)b;
|
||||||
|
p->unpackSize++;
|
||||||
|
PRF(printf(" %8d", p->unpackSize));
|
||||||
|
return (LZMA2_IS_UNCOMPRESSED_STATE(p)) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0;
|
||||||
|
|
||||||
|
case LZMA2_STATE_PACK0:
|
||||||
|
p->packSize = (UInt32)b << 8;
|
||||||
|
return LZMA2_STATE_PACK1;
|
||||||
|
|
||||||
|
case LZMA2_STATE_PACK1:
|
||||||
|
p->packSize |= (UInt32)b;
|
||||||
|
p->packSize++;
|
||||||
|
PRF(printf(" %8d", p->packSize));
|
||||||
|
return LZMA2_IS_THERE_PROP(LZMA2_GET_LZMA_MODE(p)) ? LZMA2_STATE_PROP:
|
||||||
|
(p->needInitProp ? LZMA2_STATE_ERROR : LZMA2_STATE_DATA);
|
||||||
|
|
||||||
|
case LZMA2_STATE_PROP:
|
||||||
|
{
|
||||||
|
int lc, lp;
|
||||||
|
if (b >= (9 * 5 * 5))
|
||||||
|
return LZMA2_STATE_ERROR;
|
||||||
|
lc = b % 9;
|
||||||
|
b /= 9;
|
||||||
|
p->decoder.prop.pb = b / 5;
|
||||||
|
lp = b % 5;
|
||||||
|
if (lc + lp > LZMA2_LCLP_MAX)
|
||||||
|
return LZMA2_STATE_ERROR;
|
||||||
|
p->decoder.prop.lc = lc;
|
||||||
|
p->decoder.prop.lp = lp;
|
||||||
|
p->needInitProp = False;
|
||||||
|
return LZMA2_STATE_DATA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return LZMA2_STATE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void LzmaDec_UpdateWithUncompressed(CLzmaDec *p, const Byte *src, SizeT size)
|
||||||
|
{
|
||||||
|
memcpy(p->dic + p->dicPos, src, size);
|
||||||
|
p->dicPos += size;
|
||||||
|
if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= size)
|
||||||
|
p->checkDicSize = p->prop.dicSize;
|
||||||
|
p->processedPos += (UInt32)size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState);
|
||||||
|
|
||||||
|
SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
|
||||||
|
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
|
||||||
|
{
|
||||||
|
SizeT inSize = *srcLen;
|
||||||
|
*srcLen = 0;
|
||||||
|
*status = LZMA_STATUS_NOT_SPECIFIED;
|
||||||
|
|
||||||
|
while (p->state != LZMA2_STATE_FINISHED)
|
||||||
|
{
|
||||||
|
SizeT dicPos = p->decoder.dicPos;
|
||||||
|
if (p->state == LZMA2_STATE_ERROR)
|
||||||
|
return SZ_ERROR_DATA;
|
||||||
|
if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY)
|
||||||
|
{
|
||||||
|
*status = LZMA_STATUS_NOT_FINISHED;
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT)
|
||||||
|
{
|
||||||
|
if (*srcLen == inSize)
|
||||||
|
{
|
||||||
|
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
(*srcLen)++;
|
||||||
|
p->state = Lzma2Dec_UpdateState(p, *src++);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
SizeT destSizeCur = dicLimit - dicPos;
|
||||||
|
SizeT srcSizeCur = inSize - *srcLen;
|
||||||
|
ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY;
|
||||||
|
|
||||||
|
if (p->unpackSize <= destSizeCur)
|
||||||
|
{
|
||||||
|
destSizeCur = (SizeT)p->unpackSize;
|
||||||
|
curFinishMode = LZMA_FINISH_END;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LZMA2_IS_UNCOMPRESSED_STATE(p))
|
||||||
|
{
|
||||||
|
if (*srcLen == inSize)
|
||||||
|
{
|
||||||
|
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p->state == LZMA2_STATE_DATA)
|
||||||
|
{
|
||||||
|
Bool initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC);
|
||||||
|
if (initDic)
|
||||||
|
p->needInitProp = p->needInitState = True;
|
||||||
|
else if (p->needInitDic)
|
||||||
|
return SZ_ERROR_DATA;
|
||||||
|
p->needInitDic = False;
|
||||||
|
LzmaDec_InitDicAndState(&p->decoder, initDic, False);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (srcSizeCur > destSizeCur)
|
||||||
|
srcSizeCur = destSizeCur;
|
||||||
|
|
||||||
|
if (srcSizeCur == 0)
|
||||||
|
return SZ_ERROR_DATA;
|
||||||
|
|
||||||
|
LzmaDec_UpdateWithUncompressed(&p->decoder, src, srcSizeCur);
|
||||||
|
|
||||||
|
src += srcSizeCur;
|
||||||
|
*srcLen += srcSizeCur;
|
||||||
|
p->unpackSize -= (UInt32)srcSizeCur;
|
||||||
|
p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SizeT outSizeProcessed;
|
||||||
|
SRes res;
|
||||||
|
|
||||||
|
if (p->state == LZMA2_STATE_DATA)
|
||||||
|
{
|
||||||
|
int mode = LZMA2_GET_LZMA_MODE(p);
|
||||||
|
Bool initDic = (mode == 3);
|
||||||
|
Bool initState = (mode > 0);
|
||||||
|
if ((!initDic && p->needInitDic) || (!initState && p->needInitState))
|
||||||
|
return SZ_ERROR_DATA;
|
||||||
|
|
||||||
|
LzmaDec_InitDicAndState(&p->decoder, initDic, initState);
|
||||||
|
p->needInitDic = False;
|
||||||
|
p->needInitState = False;
|
||||||
|
p->state = LZMA2_STATE_DATA_CONT;
|
||||||
|
}
|
||||||
|
if (srcSizeCur > p->packSize)
|
||||||
|
srcSizeCur = (SizeT)p->packSize;
|
||||||
|
|
||||||
|
res = LzmaDec_DecodeToDic(&p->decoder, dicPos + destSizeCur, src, &srcSizeCur, curFinishMode, status);
|
||||||
|
|
||||||
|
src += srcSizeCur;
|
||||||
|
*srcLen += srcSizeCur;
|
||||||
|
p->packSize -= (UInt32)srcSizeCur;
|
||||||
|
|
||||||
|
outSizeProcessed = p->decoder.dicPos - dicPos;
|
||||||
|
p->unpackSize -= (UInt32)outSizeProcessed;
|
||||||
|
|
||||||
|
RINOK(res);
|
||||||
|
if (*status == LZMA_STATUS_NEEDS_MORE_INPUT)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
if (srcSizeCur == 0 && outSizeProcessed == 0)
|
||||||
|
{
|
||||||
|
if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK ||
|
||||||
|
p->unpackSize != 0 || p->packSize != 0)
|
||||||
|
return SZ_ERROR_DATA;
|
||||||
|
p->state = LZMA2_STATE_CONTROL;
|
||||||
|
}
|
||||||
|
if (*status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
|
||||||
|
*status = LZMA_STATUS_NOT_FINISHED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*status = LZMA_STATUS_FINISHED_WITH_MARK;
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
|
||||||
|
{
|
||||||
|
SizeT outSize = *destLen, inSize = *srcLen;
|
||||||
|
*srcLen = *destLen = 0;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
SizeT srcSizeCur = inSize, outSizeCur, dicPos;
|
||||||
|
ELzmaFinishMode curFinishMode;
|
||||||
|
SRes res;
|
||||||
|
if (p->decoder.dicPos == p->decoder.dicBufSize)
|
||||||
|
p->decoder.dicPos = 0;
|
||||||
|
dicPos = p->decoder.dicPos;
|
||||||
|
if (outSize > p->decoder.dicBufSize - dicPos)
|
||||||
|
{
|
||||||
|
outSizeCur = p->decoder.dicBufSize;
|
||||||
|
curFinishMode = LZMA_FINISH_ANY;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
outSizeCur = dicPos + outSize;
|
||||||
|
curFinishMode = finishMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = Lzma2Dec_DecodeToDic(p, outSizeCur, src, &srcSizeCur, curFinishMode, status);
|
||||||
|
src += srcSizeCur;
|
||||||
|
inSize -= srcSizeCur;
|
||||||
|
*srcLen += srcSizeCur;
|
||||||
|
outSizeCur = p->decoder.dicPos - dicPos;
|
||||||
|
memcpy(dest, p->decoder.dic + dicPos, outSizeCur);
|
||||||
|
dest += outSizeCur;
|
||||||
|
outSize -= outSizeCur;
|
||||||
|
*destLen += outSizeCur;
|
||||||
|
if (res != 0)
|
||||||
|
return res;
|
||||||
|
if (outSizeCur == 0 || outSize == 0)
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
||||||
|
Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
CLzma2Dec decoder;
|
||||||
|
SRes res;
|
||||||
|
SizeT outSize = *destLen, inSize = *srcLen;
|
||||||
|
Byte props[LZMA_PROPS_SIZE];
|
||||||
|
|
||||||
|
Lzma2Dec_Construct(&decoder);
|
||||||
|
|
||||||
|
*destLen = *srcLen = 0;
|
||||||
|
*status = LZMA_STATUS_NOT_SPECIFIED;
|
||||||
|
decoder.decoder.dic = dest;
|
||||||
|
decoder.decoder.dicBufSize = outSize;
|
||||||
|
|
||||||
|
RINOK(Lzma2Dec_GetOldProps(prop, props));
|
||||||
|
RINOK(LzmaDec_AllocateProbs(&decoder.decoder, props, LZMA_PROPS_SIZE, alloc));
|
||||||
|
|
||||||
|
*srcLen = inSize;
|
||||||
|
res = Lzma2Dec_DecodeToDic(&decoder, outSize, src, srcLen, finishMode, status);
|
||||||
|
*destLen = decoder.decoder.dicPos;
|
||||||
|
if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
|
||||||
|
res = SZ_ERROR_INPUT_EOF;
|
||||||
|
|
||||||
|
LzmaDec_FreeProbs(&decoder.decoder, alloc);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
/* Lzma2Dec.h -- LZMA2 Decoder
|
||||||
|
2009-05-03 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#ifndef __LZMA2_DEC_H
|
||||||
|
#define __LZMA2_DEC_H
|
||||||
|
|
||||||
|
#include "LzmaDec.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ---------- State Interface ---------- */
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
CLzmaDec decoder;
|
||||||
|
UInt32 packSize;
|
||||||
|
UInt32 unpackSize;
|
||||||
|
int state;
|
||||||
|
Byte control;
|
||||||
|
Bool needInitDic;
|
||||||
|
Bool needInitState;
|
||||||
|
Bool needInitProp;
|
||||||
|
} CLzma2Dec;
|
||||||
|
|
||||||
|
#define Lzma2Dec_Construct(p) LzmaDec_Construct(&(p)->decoder)
|
||||||
|
#define Lzma2Dec_FreeProbs(p, alloc) LzmaDec_FreeProbs(&(p)->decoder, alloc);
|
||||||
|
#define Lzma2Dec_Free(p, alloc) LzmaDec_Free(&(p)->decoder, alloc);
|
||||||
|
|
||||||
|
SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc);
|
||||||
|
SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc);
|
||||||
|
void Lzma2Dec_Init(CLzma2Dec *p);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
finishMode:
|
||||||
|
It has meaning only if the decoding reaches output limit (*destLen or dicLimit).
|
||||||
|
LZMA_FINISH_ANY - use smallest number of input bytes
|
||||||
|
LZMA_FINISH_END - read EndOfStream marker after decoding
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
SZ_OK
|
||||||
|
status:
|
||||||
|
LZMA_STATUS_FINISHED_WITH_MARK
|
||||||
|
LZMA_STATUS_NOT_FINISHED
|
||||||
|
LZMA_STATUS_NEEDS_MORE_INPUT
|
||||||
|
SZ_ERROR_DATA - Data error
|
||||||
|
*/
|
||||||
|
|
||||||
|
SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
|
||||||
|
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
|
||||||
|
|
||||||
|
SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen,
|
||||||
|
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- One Call Interface ---------- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
finishMode:
|
||||||
|
It has meaning only if the decoding reaches output limit (*destLen).
|
||||||
|
LZMA_FINISH_ANY - use smallest number of input bytes
|
||||||
|
LZMA_FINISH_END - read EndOfStream marker after decoding
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
SZ_OK
|
||||||
|
status:
|
||||||
|
LZMA_STATUS_FINISHED_WITH_MARK
|
||||||
|
LZMA_STATUS_NOT_FINISHED
|
||||||
|
SZ_ERROR_DATA - Data error
|
||||||
|
SZ_ERROR_MEM - Memory allocation error
|
||||||
|
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
||||||
|
SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
|
||||||
|
*/
|
||||||
|
|
||||||
|
SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
||||||
|
Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,479 @@
|
|||||||
|
/* Lzma2Enc.c -- LZMA2 Encoder
|
||||||
|
2010-03-24 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
/* #include <stdio.h> */
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/* #define _7ZIP_ST */
|
||||||
|
|
||||||
|
#include "Lzma2Enc.h"
|
||||||
|
|
||||||
|
#ifndef _7ZIP_ST
|
||||||
|
#include "MtCoder.h"
|
||||||
|
#else
|
||||||
|
#define NUM_MT_CODER_THREADS_MAX 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LZMA2_CONTROL_LZMA (1 << 7)
|
||||||
|
#define LZMA2_CONTROL_COPY_NO_RESET 2
|
||||||
|
#define LZMA2_CONTROL_COPY_RESET_DIC 1
|
||||||
|
#define LZMA2_CONTROL_EOF 0
|
||||||
|
|
||||||
|
#define LZMA2_LCLP_MAX 4
|
||||||
|
|
||||||
|
#define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11))
|
||||||
|
|
||||||
|
#define LZMA2_PACK_SIZE_MAX (1 << 16)
|
||||||
|
#define LZMA2_COPY_CHUNK_SIZE LZMA2_PACK_SIZE_MAX
|
||||||
|
#define LZMA2_UNPACK_SIZE_MAX (1 << 21)
|
||||||
|
#define LZMA2_KEEP_WINDOW_SIZE LZMA2_UNPACK_SIZE_MAX
|
||||||
|
|
||||||
|
#define LZMA2_CHUNK_SIZE_COMPRESSED_MAX ((1 << 16) + 16)
|
||||||
|
|
||||||
|
|
||||||
|
#define PRF(x) /* x */
|
||||||
|
|
||||||
|
/* ---------- CLzma2EncInt ---------- */
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
CLzmaEncHandle enc;
|
||||||
|
UInt64 srcPos;
|
||||||
|
Byte props;
|
||||||
|
Bool needInitState;
|
||||||
|
Bool needInitProp;
|
||||||
|
} CLzma2EncInt;
|
||||||
|
|
||||||
|
static SRes Lzma2EncInt_Init(CLzma2EncInt *p, const CLzma2EncProps *props)
|
||||||
|
{
|
||||||
|
Byte propsEncoded[LZMA_PROPS_SIZE];
|
||||||
|
SizeT propsSize = LZMA_PROPS_SIZE;
|
||||||
|
RINOK(LzmaEnc_SetProps(p->enc, &props->lzmaProps));
|
||||||
|
RINOK(LzmaEnc_WriteProperties(p->enc, propsEncoded, &propsSize));
|
||||||
|
p->srcPos = 0;
|
||||||
|
p->props = propsEncoded[0];
|
||||||
|
p->needInitState = True;
|
||||||
|
p->needInitProp = True;
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp, ISeqInStream *inStream, UInt32 keepWindowSize,
|
||||||
|
ISzAlloc *alloc, ISzAlloc *allocBig);
|
||||||
|
SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen,
|
||||||
|
UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig);
|
||||||
|
SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
|
||||||
|
Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize);
|
||||||
|
const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp);
|
||||||
|
void LzmaEnc_Finish(CLzmaEncHandle pp);
|
||||||
|
void LzmaEnc_SaveState(CLzmaEncHandle pp);
|
||||||
|
void LzmaEnc_RestoreState(CLzmaEncHandle pp);
|
||||||
|
|
||||||
|
|
||||||
|
static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf,
|
||||||
|
size_t *packSizeRes, ISeqOutStream *outStream)
|
||||||
|
{
|
||||||
|
size_t packSizeLimit = *packSizeRes;
|
||||||
|
size_t packSize = packSizeLimit;
|
||||||
|
UInt32 unpackSize = LZMA2_UNPACK_SIZE_MAX;
|
||||||
|
unsigned lzHeaderSize = 5 + (p->needInitProp ? 1 : 0);
|
||||||
|
Bool useCopyBlock;
|
||||||
|
SRes res;
|
||||||
|
|
||||||
|
*packSizeRes = 0;
|
||||||
|
if (packSize < lzHeaderSize)
|
||||||
|
return SZ_ERROR_OUTPUT_EOF;
|
||||||
|
packSize -= lzHeaderSize;
|
||||||
|
|
||||||
|
LzmaEnc_SaveState(p->enc);
|
||||||
|
res = LzmaEnc_CodeOneMemBlock(p->enc, p->needInitState,
|
||||||
|
outBuf + lzHeaderSize, &packSize, LZMA2_PACK_SIZE_MAX, &unpackSize);
|
||||||
|
|
||||||
|
PRF(printf("\npackSize = %7d unpackSize = %7d ", packSize, unpackSize));
|
||||||
|
|
||||||
|
if (unpackSize == 0)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
if (res == SZ_OK)
|
||||||
|
useCopyBlock = (packSize + 2 >= unpackSize || packSize > (1 << 16));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (res != SZ_ERROR_OUTPUT_EOF)
|
||||||
|
return res;
|
||||||
|
res = SZ_OK;
|
||||||
|
useCopyBlock = True;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (useCopyBlock)
|
||||||
|
{
|
||||||
|
size_t destPos = 0;
|
||||||
|
PRF(printf("################# COPY "));
|
||||||
|
while (unpackSize > 0)
|
||||||
|
{
|
||||||
|
UInt32 u = (unpackSize < LZMA2_COPY_CHUNK_SIZE) ? unpackSize : LZMA2_COPY_CHUNK_SIZE;
|
||||||
|
if (packSizeLimit - destPos < u + 3)
|
||||||
|
return SZ_ERROR_OUTPUT_EOF;
|
||||||
|
outBuf[destPos++] = (Byte)(p->srcPos == 0 ? LZMA2_CONTROL_COPY_RESET_DIC : LZMA2_CONTROL_COPY_NO_RESET);
|
||||||
|
outBuf[destPos++] = (Byte)((u - 1) >> 8);
|
||||||
|
outBuf[destPos++] = (Byte)(u - 1);
|
||||||
|
memcpy(outBuf + destPos, LzmaEnc_GetCurBuf(p->enc) - unpackSize, u);
|
||||||
|
unpackSize -= u;
|
||||||
|
destPos += u;
|
||||||
|
p->srcPos += u;
|
||||||
|
if (outStream)
|
||||||
|
{
|
||||||
|
*packSizeRes += destPos;
|
||||||
|
if (outStream->Write(outStream, outBuf, destPos) != destPos)
|
||||||
|
return SZ_ERROR_WRITE;
|
||||||
|
destPos = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*packSizeRes = destPos;
|
||||||
|
/* needInitState = True; */
|
||||||
|
}
|
||||||
|
LzmaEnc_RestoreState(p->enc);
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
size_t destPos = 0;
|
||||||
|
UInt32 u = unpackSize - 1;
|
||||||
|
UInt32 pm = (UInt32)(packSize - 1);
|
||||||
|
unsigned mode = (p->srcPos == 0) ? 3 : (p->needInitState ? (p->needInitProp ? 2 : 1) : 0);
|
||||||
|
|
||||||
|
PRF(printf(" "));
|
||||||
|
|
||||||
|
outBuf[destPos++] = (Byte)(LZMA2_CONTROL_LZMA | (mode << 5) | (u >> 16) & 0x1F);
|
||||||
|
outBuf[destPos++] = (Byte)(u >> 8);
|
||||||
|
outBuf[destPos++] = (Byte)u;
|
||||||
|
outBuf[destPos++] = (Byte)(pm >> 8);
|
||||||
|
outBuf[destPos++] = (Byte)pm;
|
||||||
|
|
||||||
|
if (p->needInitProp)
|
||||||
|
outBuf[destPos++] = p->props;
|
||||||
|
|
||||||
|
p->needInitProp = False;
|
||||||
|
p->needInitState = False;
|
||||||
|
destPos += packSize;
|
||||||
|
p->srcPos += unpackSize;
|
||||||
|
|
||||||
|
if (outStream)
|
||||||
|
if (outStream->Write(outStream, outBuf, destPos) != destPos)
|
||||||
|
return SZ_ERROR_WRITE;
|
||||||
|
*packSizeRes = destPos;
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------- Lzma2 Props ---------- */
|
||||||
|
|
||||||
|
void Lzma2EncProps_Init(CLzma2EncProps *p)
|
||||||
|
{
|
||||||
|
LzmaEncProps_Init(&p->lzmaProps);
|
||||||
|
p->numTotalThreads = -1;
|
||||||
|
p->numBlockThreads = -1;
|
||||||
|
p->blockSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Lzma2EncProps_Normalize(CLzma2EncProps *p)
|
||||||
|
{
|
||||||
|
int t1, t1n, t2, t3;
|
||||||
|
{
|
||||||
|
CLzmaEncProps lzmaProps = p->lzmaProps;
|
||||||
|
LzmaEncProps_Normalize(&lzmaProps);
|
||||||
|
t1n = lzmaProps.numThreads;
|
||||||
|
}
|
||||||
|
|
||||||
|
t1 = p->lzmaProps.numThreads;
|
||||||
|
t2 = p->numBlockThreads;
|
||||||
|
t3 = p->numTotalThreads;
|
||||||
|
|
||||||
|
if (t2 > NUM_MT_CODER_THREADS_MAX)
|
||||||
|
t2 = NUM_MT_CODER_THREADS_MAX;
|
||||||
|
|
||||||
|
if (t3 <= 0)
|
||||||
|
{
|
||||||
|
if (t2 <= 0)
|
||||||
|
t2 = 1;
|
||||||
|
t3 = t1n * t2;
|
||||||
|
}
|
||||||
|
else if (t2 <= 0)
|
||||||
|
{
|
||||||
|
t2 = t3 / t1n;
|
||||||
|
if (t2 == 0)
|
||||||
|
{
|
||||||
|
t1 = 1;
|
||||||
|
t2 = t3;
|
||||||
|
}
|
||||||
|
if (t2 > NUM_MT_CODER_THREADS_MAX)
|
||||||
|
t2 = NUM_MT_CODER_THREADS_MAX;
|
||||||
|
}
|
||||||
|
else if (t1 <= 0)
|
||||||
|
{
|
||||||
|
t1 = t3 / t2;
|
||||||
|
if (t1 == 0)
|
||||||
|
t1 = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
t3 = t1n * t2;
|
||||||
|
|
||||||
|
p->lzmaProps.numThreads = t1;
|
||||||
|
p->numBlockThreads = t2;
|
||||||
|
p->numTotalThreads = t3;
|
||||||
|
LzmaEncProps_Normalize(&p->lzmaProps);
|
||||||
|
|
||||||
|
if (p->blockSize == 0)
|
||||||
|
{
|
||||||
|
UInt32 dictSize = p->lzmaProps.dictSize;
|
||||||
|
UInt64 blockSize = (UInt64)dictSize << 2;
|
||||||
|
const UInt32 kMinSize = (UInt32)1 << 20;
|
||||||
|
const UInt32 kMaxSize = (UInt32)1 << 28;
|
||||||
|
if (blockSize < kMinSize) blockSize = kMinSize;
|
||||||
|
if (blockSize > kMaxSize) blockSize = kMaxSize;
|
||||||
|
if (blockSize < dictSize) blockSize = dictSize;
|
||||||
|
p->blockSize = (size_t)blockSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static SRes Progress(ICompressProgress *p, UInt64 inSize, UInt64 outSize)
|
||||||
|
{
|
||||||
|
return (p && p->Progress(p, inSize, outSize) != SZ_OK) ? SZ_ERROR_PROGRESS : SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------- Lzma2 ---------- */
|
||||||
|
|
||||||
|
extern struct _CLzma2Enc;
|
||||||
|
|
||||||
|
typedef struct _CLzma2Enc
|
||||||
|
{
|
||||||
|
Byte propEncoded;
|
||||||
|
CLzma2EncProps props;
|
||||||
|
|
||||||
|
Byte *outBuf;
|
||||||
|
|
||||||
|
ISzAlloc *alloc;
|
||||||
|
ISzAlloc *allocBig;
|
||||||
|
|
||||||
|
CLzma2EncInt coders[NUM_MT_CODER_THREADS_MAX];
|
||||||
|
|
||||||
|
#ifndef _7ZIP_ST
|
||||||
|
CMtCoder mtCoder;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} CLzma2Enc;
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- Lzma2EncThread ---------- */
|
||||||
|
|
||||||
|
static SRes Lzma2Enc_EncodeMt1(CLzma2EncInt *p, CLzma2Enc *mainEncoder,
|
||||||
|
ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress)
|
||||||
|
{
|
||||||
|
UInt64 packTotal = 0;
|
||||||
|
SRes res = SZ_OK;
|
||||||
|
|
||||||
|
if (mainEncoder->outBuf == 0)
|
||||||
|
{
|
||||||
|
mainEncoder->outBuf = IAlloc_Alloc(mainEncoder->alloc, LZMA2_CHUNK_SIZE_COMPRESSED_MAX);
|
||||||
|
if (mainEncoder->outBuf == 0)
|
||||||
|
return SZ_ERROR_MEM;
|
||||||
|
}
|
||||||
|
RINOK(Lzma2EncInt_Init(p, &mainEncoder->props));
|
||||||
|
RINOK(LzmaEnc_PrepareForLzma2(p->enc, inStream, LZMA2_KEEP_WINDOW_SIZE,
|
||||||
|
mainEncoder->alloc, mainEncoder->allocBig));
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
size_t packSize = LZMA2_CHUNK_SIZE_COMPRESSED_MAX;
|
||||||
|
res = Lzma2EncInt_EncodeSubblock(p, mainEncoder->outBuf, &packSize, outStream);
|
||||||
|
if (res != SZ_OK)
|
||||||
|
break;
|
||||||
|
packTotal += packSize;
|
||||||
|
res = Progress(progress, p->srcPos, packTotal);
|
||||||
|
if (res != SZ_OK)
|
||||||
|
break;
|
||||||
|
if (packSize == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
LzmaEnc_Finish(p->enc);
|
||||||
|
if (res == SZ_OK)
|
||||||
|
{
|
||||||
|
Byte b = 0;
|
||||||
|
if (outStream->Write(outStream, &b, 1) != 1)
|
||||||
|
return SZ_ERROR_WRITE;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef _7ZIP_ST
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
IMtCoderCallback funcTable;
|
||||||
|
CLzma2Enc *lzma2Enc;
|
||||||
|
} CMtCallbackImp;
|
||||||
|
|
||||||
|
static SRes MtCallbackImp_Code(void *pp, unsigned index, Byte *dest, size_t *destSize,
|
||||||
|
const Byte *src, size_t srcSize, int finished)
|
||||||
|
{
|
||||||
|
CMtCallbackImp *imp = (CMtCallbackImp *)pp;
|
||||||
|
CLzma2Enc *mainEncoder = imp->lzma2Enc;
|
||||||
|
CLzma2EncInt *p = &mainEncoder->coders[index];
|
||||||
|
|
||||||
|
SRes res = SZ_OK;
|
||||||
|
{
|
||||||
|
size_t destLim = *destSize;
|
||||||
|
*destSize = 0;
|
||||||
|
|
||||||
|
if (srcSize != 0)
|
||||||
|
{
|
||||||
|
RINOK(Lzma2EncInt_Init(p, &mainEncoder->props));
|
||||||
|
|
||||||
|
RINOK(LzmaEnc_MemPrepare(p->enc, src, srcSize, LZMA2_KEEP_WINDOW_SIZE,
|
||||||
|
mainEncoder->alloc, mainEncoder->allocBig));
|
||||||
|
|
||||||
|
while (p->srcPos < srcSize)
|
||||||
|
{
|
||||||
|
size_t packSize = destLim - *destSize;
|
||||||
|
res = Lzma2EncInt_EncodeSubblock(p, dest + *destSize, &packSize, NULL);
|
||||||
|
if (res != SZ_OK)
|
||||||
|
break;
|
||||||
|
*destSize += packSize;
|
||||||
|
|
||||||
|
if (packSize == 0)
|
||||||
|
{
|
||||||
|
res = SZ_ERROR_FAIL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MtProgress_Set(&mainEncoder->mtCoder.mtProgress, index, p->srcPos, *destSize) != SZ_OK)
|
||||||
|
{
|
||||||
|
res = SZ_ERROR_PROGRESS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LzmaEnc_Finish(p->enc);
|
||||||
|
if (res != SZ_OK)
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
if (finished)
|
||||||
|
{
|
||||||
|
if (*destSize == destLim)
|
||||||
|
return SZ_ERROR_OUTPUT_EOF;
|
||||||
|
dest[(*destSize)++] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ---------- Lzma2Enc ---------- */
|
||||||
|
|
||||||
|
CLzma2EncHandle Lzma2Enc_Create(ISzAlloc *alloc, ISzAlloc *allocBig)
|
||||||
|
{
|
||||||
|
CLzma2Enc *p = (CLzma2Enc *)alloc->Alloc(alloc, sizeof(CLzma2Enc));
|
||||||
|
if (p == 0)
|
||||||
|
return NULL;
|
||||||
|
Lzma2EncProps_Init(&p->props);
|
||||||
|
Lzma2EncProps_Normalize(&p->props);
|
||||||
|
p->outBuf = 0;
|
||||||
|
p->alloc = alloc;
|
||||||
|
p->allocBig = allocBig;
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; i < NUM_MT_CODER_THREADS_MAX; i++)
|
||||||
|
p->coders[i].enc = 0;
|
||||||
|
}
|
||||||
|
#ifndef _7ZIP_ST
|
||||||
|
MtCoder_Construct(&p->mtCoder);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Lzma2Enc_Destroy(CLzma2EncHandle pp)
|
||||||
|
{
|
||||||
|
CLzma2Enc *p = (CLzma2Enc *)pp;
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; i < NUM_MT_CODER_THREADS_MAX; i++)
|
||||||
|
{
|
||||||
|
CLzma2EncInt *t = &p->coders[i];
|
||||||
|
if (t->enc)
|
||||||
|
{
|
||||||
|
LzmaEnc_Destroy(t->enc, p->alloc, p->allocBig);
|
||||||
|
t->enc = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef _7ZIP_ST
|
||||||
|
MtCoder_Destruct(&p->mtCoder);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
IAlloc_Free(p->alloc, p->outBuf);
|
||||||
|
IAlloc_Free(p->alloc, pp);
|
||||||
|
}
|
||||||
|
|
||||||
|
SRes Lzma2Enc_SetProps(CLzma2EncHandle pp, const CLzma2EncProps *props)
|
||||||
|
{
|
||||||
|
CLzma2Enc *p = (CLzma2Enc *)pp;
|
||||||
|
CLzmaEncProps lzmaProps = props->lzmaProps;
|
||||||
|
LzmaEncProps_Normalize(&lzmaProps);
|
||||||
|
if (lzmaProps.lc + lzmaProps.lp > LZMA2_LCLP_MAX)
|
||||||
|
return SZ_ERROR_PARAM;
|
||||||
|
p->props = *props;
|
||||||
|
Lzma2EncProps_Normalize(&p->props);
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
Byte Lzma2Enc_WriteProperties(CLzma2EncHandle pp)
|
||||||
|
{
|
||||||
|
CLzma2Enc *p = (CLzma2Enc *)pp;
|
||||||
|
unsigned i;
|
||||||
|
UInt32 dicSize = LzmaEncProps_GetDictSize(&p->props.lzmaProps);
|
||||||
|
for (i = 0; i < 40; i++)
|
||||||
|
if (dicSize <= LZMA2_DIC_SIZE_FROM_PROP(i))
|
||||||
|
break;
|
||||||
|
return (Byte)i;
|
||||||
|
}
|
||||||
|
|
||||||
|
SRes Lzma2Enc_Encode(CLzma2EncHandle pp,
|
||||||
|
ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress)
|
||||||
|
{
|
||||||
|
CLzma2Enc *p = (CLzma2Enc *)pp;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < p->props.numBlockThreads; i++)
|
||||||
|
{
|
||||||
|
CLzma2EncInt *t = &p->coders[i];
|
||||||
|
if (t->enc == NULL)
|
||||||
|
{
|
||||||
|
t->enc = LzmaEnc_Create(p->alloc);
|
||||||
|
if (t->enc == NULL)
|
||||||
|
return SZ_ERROR_MEM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef _7ZIP_ST
|
||||||
|
if (p->props.numBlockThreads <= 1)
|
||||||
|
#endif
|
||||||
|
return Lzma2Enc_EncodeMt1(&p->coders[0], p, outStream, inStream, progress);
|
||||||
|
|
||||||
|
#ifndef _7ZIP_ST
|
||||||
|
|
||||||
|
{
|
||||||
|
CMtCallbackImp mtCallback;
|
||||||
|
|
||||||
|
mtCallback.funcTable.Code = MtCallbackImp_Code;
|
||||||
|
mtCallback.lzma2Enc = p;
|
||||||
|
|
||||||
|
p->mtCoder.progress = progress;
|
||||||
|
p->mtCoder.inStream = inStream;
|
||||||
|
p->mtCoder.outStream = outStream;
|
||||||
|
p->mtCoder.alloc = p->alloc;
|
||||||
|
p->mtCoder.mtCallback = &mtCallback.funcTable;
|
||||||
|
|
||||||
|
p->mtCoder.blockSize = p->props.blockSize;
|
||||||
|
p->mtCoder.destBlockSize = p->props.blockSize + (p->props.blockSize >> 10) + 16;
|
||||||
|
p->mtCoder.numThreads = p->props.numBlockThreads;
|
||||||
|
|
||||||
|
return MtCoder_Code(&p->mtCoder);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
/* Lzma2Enc.h -- LZMA2 Encoder
|
||||||
|
2009-02-07 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#ifndef __LZMA2_ENC_H
|
||||||
|
#define __LZMA2_ENC_H
|
||||||
|
|
||||||
|
#include "LzmaEnc.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
CLzmaEncProps lzmaProps;
|
||||||
|
size_t blockSize;
|
||||||
|
int numBlockThreads;
|
||||||
|
int numTotalThreads;
|
||||||
|
} CLzma2EncProps;
|
||||||
|
|
||||||
|
void Lzma2EncProps_Init(CLzma2EncProps *p);
|
||||||
|
void Lzma2EncProps_Normalize(CLzma2EncProps *p);
|
||||||
|
|
||||||
|
/* ---------- CLzmaEnc2Handle Interface ---------- */
|
||||||
|
|
||||||
|
/* Lzma2Enc_* functions can return the following exit codes:
|
||||||
|
Returns:
|
||||||
|
SZ_OK - OK
|
||||||
|
SZ_ERROR_MEM - Memory allocation error
|
||||||
|
SZ_ERROR_PARAM - Incorrect paramater in props
|
||||||
|
SZ_ERROR_WRITE - Write callback error
|
||||||
|
SZ_ERROR_PROGRESS - some break from progress callback
|
||||||
|
SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef void * CLzma2EncHandle;
|
||||||
|
|
||||||
|
CLzma2EncHandle Lzma2Enc_Create(ISzAlloc *alloc, ISzAlloc *allocBig);
|
||||||
|
void Lzma2Enc_Destroy(CLzma2EncHandle p);
|
||||||
|
SRes Lzma2Enc_SetProps(CLzma2EncHandle p, const CLzma2EncProps *props);
|
||||||
|
Byte Lzma2Enc_WriteProperties(CLzma2EncHandle p);
|
||||||
|
SRes Lzma2Enc_Encode(CLzma2EncHandle p,
|
||||||
|
ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress);
|
||||||
|
|
||||||
|
/* ---------- One Call Interface ---------- */
|
||||||
|
|
||||||
|
/* Lzma2Encode
|
||||||
|
Return code:
|
||||||
|
SZ_OK - OK
|
||||||
|
SZ_ERROR_MEM - Memory allocation error
|
||||||
|
SZ_ERROR_PARAM - Incorrect paramater
|
||||||
|
SZ_ERROR_OUTPUT_EOF - output buffer overflow
|
||||||
|
SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
SRes Lzma2Encode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
|
||||||
|
const CLzmaEncProps *props, Byte *propsEncoded, int writeEndMark,
|
||||||
|
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,111 @@
|
|||||||
|
/* Lzma86.h -- LZMA + x86 (BCJ) Filter
|
||||||
|
2009-08-14 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#ifndef __LZMA86_H
|
||||||
|
#define __LZMA86_H
|
||||||
|
|
||||||
|
#include "Types.h"
|
||||||
|
|
||||||
|
EXTERN_C_BEGIN
|
||||||
|
|
||||||
|
#define LZMA86_SIZE_OFFSET (1 + 5)
|
||||||
|
#define LZMA86_HEADER_SIZE (LZMA86_SIZE_OFFSET + 8)
|
||||||
|
|
||||||
|
/*
|
||||||
|
It's an example for LZMA + x86 Filter use.
|
||||||
|
You can use .lzma86 extension, if you write that stream to file.
|
||||||
|
.lzma86 header adds one additional byte to standard .lzma header.
|
||||||
|
.lzma86 header (14 bytes):
|
||||||
|
Offset Size Description
|
||||||
|
0 1 = 0 - no filter, pure LZMA
|
||||||
|
= 1 - x86 filter + LZMA
|
||||||
|
1 1 lc, lp and pb in encoded form
|
||||||
|
2 4 dictSize (little endian)
|
||||||
|
6 8 uncompressed size (little endian)
|
||||||
|
|
||||||
|
|
||||||
|
Lzma86_Encode
|
||||||
|
-------------
|
||||||
|
level - compression level: 0 <= level <= 9, the default value for "level" is 5.
|
||||||
|
|
||||||
|
dictSize - The dictionary size in bytes. The maximum value is
|
||||||
|
128 MB = (1 << 27) bytes for 32-bit version
|
||||||
|
1 GB = (1 << 30) bytes for 64-bit version
|
||||||
|
The default value is 16 MB = (1 << 24) bytes, for level = 5.
|
||||||
|
It's recommended to use the dictionary that is larger than 4 KB and
|
||||||
|
that can be calculated as (1 << N) or (3 << N) sizes.
|
||||||
|
For better compression ratio dictSize must be >= inSize.
|
||||||
|
|
||||||
|
filterMode:
|
||||||
|
SZ_FILTER_NO - no Filter
|
||||||
|
SZ_FILTER_YES - x86 Filter
|
||||||
|
SZ_FILTER_AUTO - it tries both alternatives to select best.
|
||||||
|
Encoder will use 2 or 3 passes:
|
||||||
|
2 passes when FILTER_NO provides better compression.
|
||||||
|
3 passes when FILTER_YES provides better compression.
|
||||||
|
|
||||||
|
Lzma86Encode allocates Data with MyAlloc functions.
|
||||||
|
RAM Requirements for compressing:
|
||||||
|
RamSize = dictionarySize * 11.5 + 6MB + FilterBlockSize
|
||||||
|
filterMode FilterBlockSize
|
||||||
|
SZ_FILTER_NO 0
|
||||||
|
SZ_FILTER_YES inSize
|
||||||
|
SZ_FILTER_AUTO inSize
|
||||||
|
|
||||||
|
|
||||||
|
Return code:
|
||||||
|
SZ_OK - OK
|
||||||
|
SZ_ERROR_MEM - Memory allocation error
|
||||||
|
SZ_ERROR_PARAM - Incorrect paramater
|
||||||
|
SZ_ERROR_OUTPUT_EOF - output buffer overflow
|
||||||
|
SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
|
||||||
|
*/
|
||||||
|
|
||||||
|
enum ESzFilterMode
|
||||||
|
{
|
||||||
|
SZ_FILTER_NO,
|
||||||
|
SZ_FILTER_YES,
|
||||||
|
SZ_FILTER_AUTO
|
||||||
|
};
|
||||||
|
|
||||||
|
SRes Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen,
|
||||||
|
int level, UInt32 dictSize, int filterMode);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Lzma86_GetUnpackSize:
|
||||||
|
In:
|
||||||
|
src - input data
|
||||||
|
srcLen - input data size
|
||||||
|
Out:
|
||||||
|
unpackSize - size of uncompressed stream
|
||||||
|
Return code:
|
||||||
|
SZ_OK - OK
|
||||||
|
SZ_ERROR_INPUT_EOF - Error in headers
|
||||||
|
*/
|
||||||
|
|
||||||
|
SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Lzma86_Decode:
|
||||||
|
In:
|
||||||
|
dest - output data
|
||||||
|
destLen - output data size
|
||||||
|
src - input data
|
||||||
|
srcLen - input data size
|
||||||
|
Out:
|
||||||
|
destLen - processed output size
|
||||||
|
srcLen - processed input size
|
||||||
|
Return code:
|
||||||
|
SZ_OK - OK
|
||||||
|
SZ_ERROR_DATA - Data error
|
||||||
|
SZ_ERROR_MEM - Memory allocation error
|
||||||
|
SZ_ERROR_UNSUPPORTED - unsupported file
|
||||||
|
SZ_ERROR_INPUT_EOF - it needs more bytes in input buffer
|
||||||
|
*/
|
||||||
|
|
||||||
|
SRes Lzma86_Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen);
|
||||||
|
|
||||||
|
EXTERN_C_END
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
/* Lzma86Dec.c -- LZMA + x86 (BCJ) Filter Decoder
|
||||||
|
2009-08-14 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#include "Lzma86.h"
|
||||||
|
|
||||||
|
#include "Alloc.h"
|
||||||
|
#include "Bra.h"
|
||||||
|
#include "LzmaDec.h"
|
||||||
|
|
||||||
|
static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }
|
||||||
|
static void SzFree(void *p, void *address) { p = p; MyFree(address); }
|
||||||
|
|
||||||
|
SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
if (srcLen < LZMA86_HEADER_SIZE)
|
||||||
|
return SZ_ERROR_INPUT_EOF;
|
||||||
|
*unpackSize = 0;
|
||||||
|
for (i = 0; i < sizeof(UInt64); i++)
|
||||||
|
*unpackSize += ((UInt64)src[LZMA86_SIZE_OFFSET + i]) << (8 * i);
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
SRes Lzma86_Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen)
|
||||||
|
{
|
||||||
|
ISzAlloc g_Alloc = { SzAlloc, SzFree };
|
||||||
|
SRes res;
|
||||||
|
int useFilter;
|
||||||
|
SizeT inSizePure;
|
||||||
|
ELzmaStatus status;
|
||||||
|
|
||||||
|
if (*srcLen < LZMA86_HEADER_SIZE)
|
||||||
|
return SZ_ERROR_INPUT_EOF;
|
||||||
|
|
||||||
|
useFilter = src[0];
|
||||||
|
|
||||||
|
if (useFilter > 1)
|
||||||
|
{
|
||||||
|
*destLen = 0;
|
||||||
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
inSizePure = *srcLen - LZMA86_HEADER_SIZE;
|
||||||
|
res = LzmaDecode(dest, destLen, src + LZMA86_HEADER_SIZE, &inSizePure,
|
||||||
|
src + 1, LZMA_PROPS_SIZE, LZMA_FINISH_ANY, &status, &g_Alloc);
|
||||||
|
*srcLen = inSizePure + LZMA86_HEADER_SIZE;
|
||||||
|
if (res != SZ_OK)
|
||||||
|
return res;
|
||||||
|
if (useFilter == 1)
|
||||||
|
{
|
||||||
|
UInt32 x86State;
|
||||||
|
x86_Convert_Init(x86State);
|
||||||
|
x86_Convert(dest, *destLen, 0, &x86State, 0);
|
||||||
|
}
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
/* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder
|
||||||
|
2009-08-14 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "Lzma86.h"
|
||||||
|
|
||||||
|
#include "Alloc.h"
|
||||||
|
#include "Bra.h"
|
||||||
|
#include "LzmaEnc.h"
|
||||||
|
|
||||||
|
#define SZE_OUT_OVERFLOW SZE_DATA_ERROR
|
||||||
|
|
||||||
|
static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }
|
||||||
|
static void SzFree(void *p, void *address) { p = p; MyFree(address); }
|
||||||
|
|
||||||
|
int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen,
|
||||||
|
int level, UInt32 dictSize, int filterMode)
|
||||||
|
{
|
||||||
|
ISzAlloc g_Alloc = { SzAlloc, SzFree };
|
||||||
|
size_t outSize2 = *destLen;
|
||||||
|
Byte *filteredStream;
|
||||||
|
Bool useFilter;
|
||||||
|
int mainResult = SZ_ERROR_OUTPUT_EOF;
|
||||||
|
CLzmaEncProps props;
|
||||||
|
LzmaEncProps_Init(&props);
|
||||||
|
props.level = level;
|
||||||
|
props.dictSize = dictSize;
|
||||||
|
|
||||||
|
*destLen = 0;
|
||||||
|
if (outSize2 < LZMA86_HEADER_SIZE)
|
||||||
|
return SZ_ERROR_OUTPUT_EOF;
|
||||||
|
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
UInt64 t = srcLen;
|
||||||
|
for (i = 0; i < 8; i++, t >>= 8)
|
||||||
|
dest[LZMA86_SIZE_OFFSET + i] = (Byte)t;
|
||||||
|
}
|
||||||
|
|
||||||
|
filteredStream = 0;
|
||||||
|
useFilter = (filterMode != SZ_FILTER_NO);
|
||||||
|
if (useFilter)
|
||||||
|
{
|
||||||
|
if (srcLen != 0)
|
||||||
|
{
|
||||||
|
filteredStream = (Byte *)MyAlloc(srcLen);
|
||||||
|
if (filteredStream == 0)
|
||||||
|
return SZ_ERROR_MEM;
|
||||||
|
memcpy(filteredStream, src, srcLen);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
UInt32 x86State;
|
||||||
|
x86_Convert_Init(x86State);
|
||||||
|
x86_Convert(filteredStream, srcLen, 0, &x86State, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
size_t minSize = 0;
|
||||||
|
Bool bestIsFiltered = False;
|
||||||
|
|
||||||
|
/* passes for SZ_FILTER_AUTO:
|
||||||
|
0 - BCJ + LZMA
|
||||||
|
1 - LZMA
|
||||||
|
2 - BCJ + LZMA agaian, if pass 0 (BCJ + LZMA) is better.
|
||||||
|
*/
|
||||||
|
int numPasses = (filterMode == SZ_FILTER_AUTO) ? 3 : 1;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < numPasses; i++)
|
||||||
|
{
|
||||||
|
size_t outSizeProcessed = outSize2 - LZMA86_HEADER_SIZE;
|
||||||
|
size_t outPropsSize = 5;
|
||||||
|
SRes curRes;
|
||||||
|
Bool curModeIsFiltered = (numPasses > 1 && i == numPasses - 1);
|
||||||
|
if (curModeIsFiltered && !bestIsFiltered)
|
||||||
|
break;
|
||||||
|
if (useFilter && i == 0)
|
||||||
|
curModeIsFiltered = True;
|
||||||
|
|
||||||
|
curRes = LzmaEncode(dest + LZMA86_HEADER_SIZE, &outSizeProcessed,
|
||||||
|
curModeIsFiltered ? filteredStream : src, srcLen,
|
||||||
|
&props, dest + 1, &outPropsSize, 0,
|
||||||
|
NULL, &g_Alloc, &g_Alloc);
|
||||||
|
|
||||||
|
if (curRes != SZ_ERROR_OUTPUT_EOF)
|
||||||
|
{
|
||||||
|
if (curRes != SZ_OK)
|
||||||
|
{
|
||||||
|
mainResult = curRes;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (outSizeProcessed <= minSize || mainResult != SZ_OK)
|
||||||
|
{
|
||||||
|
minSize = outSizeProcessed;
|
||||||
|
bestIsFiltered = curModeIsFiltered;
|
||||||
|
mainResult = SZ_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dest[0] = (bestIsFiltered ? 1 : 0);
|
||||||
|
*destLen = LZMA86_HEADER_SIZE + minSize;
|
||||||
|
}
|
||||||
|
if (useFilter)
|
||||||
|
MyFree(filteredStream);
|
||||||
|
return mainResult;
|
||||||
|
}
|
||||||
@@ -0,0 +1,999 @@
|
|||||||
|
/* LzmaDec.c -- LZMA Decoder
|
||||||
|
2009-09-20 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#include "LzmaDec.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define kNumTopBits 24
|
||||||
|
#define kTopValue ((UInt32)1 << kNumTopBits)
|
||||||
|
|
||||||
|
#define kNumBitModelTotalBits 11
|
||||||
|
#define kBitModelTotal (1 << kNumBitModelTotalBits)
|
||||||
|
#define kNumMoveBits 5
|
||||||
|
|
||||||
|
#define RC_INIT_SIZE 5
|
||||||
|
|
||||||
|
#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); }
|
||||||
|
|
||||||
|
#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
|
||||||
|
#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
|
||||||
|
#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits));
|
||||||
|
#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \
|
||||||
|
{ UPDATE_0(p); i = (i + i); A0; } else \
|
||||||
|
{ UPDATE_1(p); i = (i + i) + 1; A1; }
|
||||||
|
#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;)
|
||||||
|
|
||||||
|
#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); }
|
||||||
|
#define TREE_DECODE(probs, limit, i) \
|
||||||
|
{ i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; }
|
||||||
|
|
||||||
|
/* #define _LZMA_SIZE_OPT */
|
||||||
|
|
||||||
|
#ifdef _LZMA_SIZE_OPT
|
||||||
|
#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i)
|
||||||
|
#else
|
||||||
|
#define TREE_6_DECODE(probs, i) \
|
||||||
|
{ i = 1; \
|
||||||
|
TREE_GET_BIT(probs, i); \
|
||||||
|
TREE_GET_BIT(probs, i); \
|
||||||
|
TREE_GET_BIT(probs, i); \
|
||||||
|
TREE_GET_BIT(probs, i); \
|
||||||
|
TREE_GET_BIT(probs, i); \
|
||||||
|
TREE_GET_BIT(probs, i); \
|
||||||
|
i -= 0x40; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); }
|
||||||
|
|
||||||
|
#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
|
||||||
|
#define UPDATE_0_CHECK range = bound;
|
||||||
|
#define UPDATE_1_CHECK range -= bound; code -= bound;
|
||||||
|
#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \
|
||||||
|
{ UPDATE_0_CHECK; i = (i + i); A0; } else \
|
||||||
|
{ UPDATE_1_CHECK; i = (i + i) + 1; A1; }
|
||||||
|
#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;)
|
||||||
|
#define TREE_DECODE_CHECK(probs, limit, i) \
|
||||||
|
{ i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; }
|
||||||
|
|
||||||
|
|
||||||
|
#define kNumPosBitsMax 4
|
||||||
|
#define kNumPosStatesMax (1 << kNumPosBitsMax)
|
||||||
|
|
||||||
|
#define kLenNumLowBits 3
|
||||||
|
#define kLenNumLowSymbols (1 << kLenNumLowBits)
|
||||||
|
#define kLenNumMidBits 3
|
||||||
|
#define kLenNumMidSymbols (1 << kLenNumMidBits)
|
||||||
|
#define kLenNumHighBits 8
|
||||||
|
#define kLenNumHighSymbols (1 << kLenNumHighBits)
|
||||||
|
|
||||||
|
#define LenChoice 0
|
||||||
|
#define LenChoice2 (LenChoice + 1)
|
||||||
|
#define LenLow (LenChoice2 + 1)
|
||||||
|
#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
|
||||||
|
#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
|
||||||
|
#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
|
||||||
|
|
||||||
|
|
||||||
|
#define kNumStates 12
|
||||||
|
#define kNumLitStates 7
|
||||||
|
|
||||||
|
#define kStartPosModelIndex 4
|
||||||
|
#define kEndPosModelIndex 14
|
||||||
|
#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
|
||||||
|
|
||||||
|
#define kNumPosSlotBits 6
|
||||||
|
#define kNumLenToPosStates 4
|
||||||
|
|
||||||
|
#define kNumAlignBits 4
|
||||||
|
#define kAlignTableSize (1 << kNumAlignBits)
|
||||||
|
|
||||||
|
#define kMatchMinLen 2
|
||||||
|
#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
|
||||||
|
|
||||||
|
#define IsMatch 0
|
||||||
|
#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
|
||||||
|
#define IsRepG0 (IsRep + kNumStates)
|
||||||
|
#define IsRepG1 (IsRepG0 + kNumStates)
|
||||||
|
#define IsRepG2 (IsRepG1 + kNumStates)
|
||||||
|
#define IsRep0Long (IsRepG2 + kNumStates)
|
||||||
|
#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
|
||||||
|
#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
|
||||||
|
#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
|
||||||
|
#define LenCoder (Align + kAlignTableSize)
|
||||||
|
#define RepLenCoder (LenCoder + kNumLenProbs)
|
||||||
|
#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)))
|
||||||
|
|
||||||
|
#if Literal != LZMA_BASE_SIZE
|
||||||
|
StopCompilingDueBUG
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LZMA_DIC_MIN (1 << 12)
|
||||||
|
|
||||||
|
/* First LZMA-symbol is always decoded.
|
||||||
|
And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization
|
||||||
|
Out:
|
||||||
|
Result:
|
||||||
|
SZ_OK - OK
|
||||||
|
SZ_ERROR_DATA - Error
|
||||||
|
p->remainLen:
|
||||||
|
< kMatchSpecLenStart : normal remain
|
||||||
|
= kMatchSpecLenStart : finished
|
||||||
|
= kMatchSpecLenStart + 1 : Flush marker
|
||||||
|
= kMatchSpecLenStart + 2 : State Init Marker
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
|
||||||
|
{
|
||||||
|
CLzmaProb *probs = p->probs;
|
||||||
|
|
||||||
|
unsigned state = p->state;
|
||||||
|
UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3];
|
||||||
|
unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1;
|
||||||
|
unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1;
|
||||||
|
unsigned lc = p->prop.lc;
|
||||||
|
|
||||||
|
Byte *dic = p->dic;
|
||||||
|
SizeT dicBufSize = p->dicBufSize;
|
||||||
|
SizeT dicPos = p->dicPos;
|
||||||
|
|
||||||
|
UInt32 processedPos = p->processedPos;
|
||||||
|
UInt32 checkDicSize = p->checkDicSize;
|
||||||
|
unsigned len = 0;
|
||||||
|
|
||||||
|
const Byte *buf = p->buf;
|
||||||
|
UInt32 range = p->range;
|
||||||
|
UInt32 code = p->code;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
CLzmaProb *prob;
|
||||||
|
UInt32 bound;
|
||||||
|
unsigned ttt;
|
||||||
|
unsigned posState = processedPos & pbMask;
|
||||||
|
|
||||||
|
prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
|
||||||
|
IF_BIT_0(prob)
|
||||||
|
{
|
||||||
|
unsigned symbol;
|
||||||
|
UPDATE_0(prob);
|
||||||
|
prob = probs + Literal;
|
||||||
|
if (checkDicSize != 0 || processedPos != 0)
|
||||||
|
prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +
|
||||||
|
(dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));
|
||||||
|
|
||||||
|
if (state < kNumLitStates)
|
||||||
|
{
|
||||||
|
state -= (state < 4) ? state : 3;
|
||||||
|
symbol = 1;
|
||||||
|
do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
|
||||||
|
unsigned offs = 0x100;
|
||||||
|
state -= (state < 10) ? 3 : 6;
|
||||||
|
symbol = 1;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
unsigned bit;
|
||||||
|
CLzmaProb *probLit;
|
||||||
|
matchByte <<= 1;
|
||||||
|
bit = (matchByte & offs);
|
||||||
|
probLit = prob + offs + bit + symbol;
|
||||||
|
GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit)
|
||||||
|
}
|
||||||
|
while (symbol < 0x100);
|
||||||
|
}
|
||||||
|
dic[dicPos++] = (Byte)symbol;
|
||||||
|
processedPos++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UPDATE_1(prob);
|
||||||
|
prob = probs + IsRep + state;
|
||||||
|
IF_BIT_0(prob)
|
||||||
|
{
|
||||||
|
UPDATE_0(prob);
|
||||||
|
state += kNumStates;
|
||||||
|
prob = probs + LenCoder;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UPDATE_1(prob);
|
||||||
|
if (checkDicSize == 0 && processedPos == 0)
|
||||||
|
return SZ_ERROR_DATA;
|
||||||
|
prob = probs + IsRepG0 + state;
|
||||||
|
IF_BIT_0(prob)
|
||||||
|
{
|
||||||
|
UPDATE_0(prob);
|
||||||
|
prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
|
||||||
|
IF_BIT_0(prob)
|
||||||
|
{
|
||||||
|
UPDATE_0(prob);
|
||||||
|
dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
|
||||||
|
dicPos++;
|
||||||
|
processedPos++;
|
||||||
|
state = state < kNumLitStates ? 9 : 11;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
UPDATE_1(prob);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UInt32 distance;
|
||||||
|
UPDATE_1(prob);
|
||||||
|
prob = probs + IsRepG1 + state;
|
||||||
|
IF_BIT_0(prob)
|
||||||
|
{
|
||||||
|
UPDATE_0(prob);
|
||||||
|
distance = rep1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UPDATE_1(prob);
|
||||||
|
prob = probs + IsRepG2 + state;
|
||||||
|
IF_BIT_0(prob)
|
||||||
|
{
|
||||||
|
UPDATE_0(prob);
|
||||||
|
distance = rep2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UPDATE_1(prob);
|
||||||
|
distance = rep3;
|
||||||
|
rep3 = rep2;
|
||||||
|
}
|
||||||
|
rep2 = rep1;
|
||||||
|
}
|
||||||
|
rep1 = rep0;
|
||||||
|
rep0 = distance;
|
||||||
|
}
|
||||||
|
state = state < kNumLitStates ? 8 : 11;
|
||||||
|
prob = probs + RepLenCoder;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
unsigned limit, offset;
|
||||||
|
CLzmaProb *probLen = prob + LenChoice;
|
||||||
|
IF_BIT_0(probLen)
|
||||||
|
{
|
||||||
|
UPDATE_0(probLen);
|
||||||
|
probLen = prob + LenLow + (posState << kLenNumLowBits);
|
||||||
|
offset = 0;
|
||||||
|
limit = (1 << kLenNumLowBits);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UPDATE_1(probLen);
|
||||||
|
probLen = prob + LenChoice2;
|
||||||
|
IF_BIT_0(probLen)
|
||||||
|
{
|
||||||
|
UPDATE_0(probLen);
|
||||||
|
probLen = prob + LenMid + (posState << kLenNumMidBits);
|
||||||
|
offset = kLenNumLowSymbols;
|
||||||
|
limit = (1 << kLenNumMidBits);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UPDATE_1(probLen);
|
||||||
|
probLen = prob + LenHigh;
|
||||||
|
offset = kLenNumLowSymbols + kLenNumMidSymbols;
|
||||||
|
limit = (1 << kLenNumHighBits);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TREE_DECODE(probLen, limit, len);
|
||||||
|
len += offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state >= kNumStates)
|
||||||
|
{
|
||||||
|
UInt32 distance;
|
||||||
|
prob = probs + PosSlot +
|
||||||
|
((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits);
|
||||||
|
TREE_6_DECODE(prob, distance);
|
||||||
|
if (distance >= kStartPosModelIndex)
|
||||||
|
{
|
||||||
|
unsigned posSlot = (unsigned)distance;
|
||||||
|
int numDirectBits = (int)(((distance >> 1) - 1));
|
||||||
|
distance = (2 | (distance & 1));
|
||||||
|
if (posSlot < kEndPosModelIndex)
|
||||||
|
{
|
||||||
|
distance <<= numDirectBits;
|
||||||
|
prob = probs + SpecPos + distance - posSlot - 1;
|
||||||
|
{
|
||||||
|
UInt32 mask = 1;
|
||||||
|
unsigned i = 1;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
GET_BIT2(prob + i, i, ; , distance |= mask);
|
||||||
|
mask <<= 1;
|
||||||
|
}
|
||||||
|
while (--numDirectBits != 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
numDirectBits -= kNumAlignBits;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
NORMALIZE
|
||||||
|
range >>= 1;
|
||||||
|
|
||||||
|
{
|
||||||
|
UInt32 t;
|
||||||
|
code -= range;
|
||||||
|
t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */
|
||||||
|
distance = (distance << 1) + (t + 1);
|
||||||
|
code += range & t;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
distance <<= 1;
|
||||||
|
if (code >= range)
|
||||||
|
{
|
||||||
|
code -= range;
|
||||||
|
distance |= 1;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
while (--numDirectBits != 0);
|
||||||
|
prob = probs + Align;
|
||||||
|
distance <<= kNumAlignBits;
|
||||||
|
{
|
||||||
|
unsigned i = 1;
|
||||||
|
GET_BIT2(prob + i, i, ; , distance |= 1);
|
||||||
|
GET_BIT2(prob + i, i, ; , distance |= 2);
|
||||||
|
GET_BIT2(prob + i, i, ; , distance |= 4);
|
||||||
|
GET_BIT2(prob + i, i, ; , distance |= 8);
|
||||||
|
}
|
||||||
|
if (distance == (UInt32)0xFFFFFFFF)
|
||||||
|
{
|
||||||
|
len += kMatchSpecLenStart;
|
||||||
|
state -= kNumStates;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rep3 = rep2;
|
||||||
|
rep2 = rep1;
|
||||||
|
rep1 = rep0;
|
||||||
|
rep0 = distance + 1;
|
||||||
|
if (checkDicSize == 0)
|
||||||
|
{
|
||||||
|
if (distance >= processedPos)
|
||||||
|
return SZ_ERROR_DATA;
|
||||||
|
}
|
||||||
|
else if (distance >= checkDicSize)
|
||||||
|
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);
|
||||||
|
|
||||||
|
processedPos += curLen;
|
||||||
|
|
||||||
|
len -= curLen;
|
||||||
|
if (pos + curLen <= dicBufSize)
|
||||||
|
{
|
||||||
|
Byte *dest = dic + dicPos;
|
||||||
|
ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos;
|
||||||
|
const Byte *lim = dest + curLen;
|
||||||
|
dicPos += curLen;
|
||||||
|
do
|
||||||
|
*(dest) = (Byte)*(dest + src);
|
||||||
|
while (++dest != lim);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
dic[dicPos++] = dic[pos];
|
||||||
|
if (++pos == dicBufSize)
|
||||||
|
pos = 0;
|
||||||
|
}
|
||||||
|
while (--curLen != 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (dicPos < limit && buf < bufLimit);
|
||||||
|
NORMALIZE;
|
||||||
|
p->buf = buf;
|
||||||
|
p->range = range;
|
||||||
|
p->code = code;
|
||||||
|
p->remainLen = len;
|
||||||
|
p->dicPos = dicPos;
|
||||||
|
p->processedPos = processedPos;
|
||||||
|
p->reps[0] = rep0;
|
||||||
|
p->reps[1] = rep1;
|
||||||
|
p->reps[2] = rep2;
|
||||||
|
p->reps[3] = rep3;
|
||||||
|
p->state = state;
|
||||||
|
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
|
||||||
|
{
|
||||||
|
if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart)
|
||||||
|
{
|
||||||
|
Byte *dic = p->dic;
|
||||||
|
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);
|
||||||
|
|
||||||
|
if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len)
|
||||||
|
p->checkDicSize = p->prop.dicSize;
|
||||||
|
|
||||||
|
p->processedPos += len;
|
||||||
|
p->remainLen -= len;
|
||||||
|
while (len-- != 0)
|
||||||
|
{
|
||||||
|
dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
|
||||||
|
dicPos++;
|
||||||
|
}
|
||||||
|
p->dicPos = dicPos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
SizeT limit2 = limit;
|
||||||
|
if (p->checkDicSize == 0)
|
||||||
|
{
|
||||||
|
UInt32 rem = p->prop.dicSize - p->processedPos;
|
||||||
|
if (limit - p->dicPos > rem)
|
||||||
|
limit2 = p->dicPos + rem;
|
||||||
|
}
|
||||||
|
RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit));
|
||||||
|
if (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;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
DUMMY_ERROR, /* unexpected end of input stream */
|
||||||
|
DUMMY_LIT,
|
||||||
|
DUMMY_MATCH,
|
||||||
|
DUMMY_REP
|
||||||
|
} ELzmaDummy;
|
||||||
|
|
||||||
|
static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize)
|
||||||
|
{
|
||||||
|
UInt32 range = p->range;
|
||||||
|
UInt32 code = p->code;
|
||||||
|
const Byte *bufLimit = buf + inSize;
|
||||||
|
CLzmaProb *probs = p->probs;
|
||||||
|
unsigned state = p->state;
|
||||||
|
ELzmaDummy res;
|
||||||
|
|
||||||
|
{
|
||||||
|
CLzmaProb *prob;
|
||||||
|
UInt32 bound;
|
||||||
|
unsigned ttt;
|
||||||
|
unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1);
|
||||||
|
|
||||||
|
prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
|
||||||
|
IF_BIT_0_CHECK(prob)
|
||||||
|
{
|
||||||
|
UPDATE_0_CHECK
|
||||||
|
|
||||||
|
/* if (bufLimit - buf >= 7) return DUMMY_LIT; */
|
||||||
|
|
||||||
|
prob = probs + Literal;
|
||||||
|
if (p->checkDicSize != 0 || p->processedPos != 0)
|
||||||
|
prob += (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))));
|
||||||
|
|
||||||
|
if (state < kNumLitStates)
|
||||||
|
{
|
||||||
|
unsigned symbol = 1;
|
||||||
|
do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned matchByte = p->dic[p->dicPos - p->reps[0] +
|
||||||
|
((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)];
|
||||||
|
unsigned offs = 0x100;
|
||||||
|
unsigned symbol = 1;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
unsigned bit;
|
||||||
|
CLzmaProb *probLit;
|
||||||
|
matchByte <<= 1;
|
||||||
|
bit = (matchByte & offs);
|
||||||
|
probLit = prob + offs + bit + symbol;
|
||||||
|
GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit)
|
||||||
|
}
|
||||||
|
while (symbol < 0x100);
|
||||||
|
}
|
||||||
|
res = DUMMY_LIT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned len;
|
||||||
|
UPDATE_1_CHECK;
|
||||||
|
|
||||||
|
prob = probs + IsRep + state;
|
||||||
|
IF_BIT_0_CHECK(prob)
|
||||||
|
{
|
||||||
|
UPDATE_0_CHECK;
|
||||||
|
state = 0;
|
||||||
|
prob = probs + LenCoder;
|
||||||
|
res = DUMMY_MATCH;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UPDATE_1_CHECK;
|
||||||
|
res = DUMMY_REP;
|
||||||
|
prob = probs + IsRepG0 + state;
|
||||||
|
IF_BIT_0_CHECK(prob)
|
||||||
|
{
|
||||||
|
UPDATE_0_CHECK;
|
||||||
|
prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
|
||||||
|
IF_BIT_0_CHECK(prob)
|
||||||
|
{
|
||||||
|
UPDATE_0_CHECK;
|
||||||
|
NORMALIZE_CHECK;
|
||||||
|
return DUMMY_REP;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UPDATE_1_CHECK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UPDATE_1_CHECK;
|
||||||
|
prob = probs + IsRepG1 + state;
|
||||||
|
IF_BIT_0_CHECK(prob)
|
||||||
|
{
|
||||||
|
UPDATE_0_CHECK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UPDATE_1_CHECK;
|
||||||
|
prob = probs + IsRepG2 + state;
|
||||||
|
IF_BIT_0_CHECK(prob)
|
||||||
|
{
|
||||||
|
UPDATE_0_CHECK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UPDATE_1_CHECK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
state = kNumStates;
|
||||||
|
prob = probs + RepLenCoder;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
unsigned limit, offset;
|
||||||
|
CLzmaProb *probLen = prob + LenChoice;
|
||||||
|
IF_BIT_0_CHECK(probLen)
|
||||||
|
{
|
||||||
|
UPDATE_0_CHECK;
|
||||||
|
probLen = prob + LenLow + (posState << kLenNumLowBits);
|
||||||
|
offset = 0;
|
||||||
|
limit = 1 << kLenNumLowBits;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UPDATE_1_CHECK;
|
||||||
|
probLen = prob + LenChoice2;
|
||||||
|
IF_BIT_0_CHECK(probLen)
|
||||||
|
{
|
||||||
|
UPDATE_0_CHECK;
|
||||||
|
probLen = prob + LenMid + (posState << kLenNumMidBits);
|
||||||
|
offset = kLenNumLowSymbols;
|
||||||
|
limit = 1 << kLenNumMidBits;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UPDATE_1_CHECK;
|
||||||
|
probLen = prob + LenHigh;
|
||||||
|
offset = kLenNumLowSymbols + kLenNumMidSymbols;
|
||||||
|
limit = 1 << kLenNumHighBits;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TREE_DECODE_CHECK(probLen, limit, len);
|
||||||
|
len += offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state < 4)
|
||||||
|
{
|
||||||
|
unsigned posSlot;
|
||||||
|
prob = probs + PosSlot +
|
||||||
|
((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
|
||||||
|
kNumPosSlotBits);
|
||||||
|
TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);
|
||||||
|
if (posSlot >= kStartPosModelIndex)
|
||||||
|
{
|
||||||
|
int numDirectBits = ((posSlot >> 1) - 1);
|
||||||
|
|
||||||
|
/* if (bufLimit - buf >= 8) return DUMMY_MATCH; */
|
||||||
|
|
||||||
|
if (posSlot < kEndPosModelIndex)
|
||||||
|
{
|
||||||
|
prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
numDirectBits -= kNumAlignBits;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
NORMALIZE_CHECK
|
||||||
|
range >>= 1;
|
||||||
|
code -= range & (((code - range) >> 31) - 1);
|
||||||
|
/* if (code >= range) code -= range; */
|
||||||
|
}
|
||||||
|
while (--numDirectBits != 0);
|
||||||
|
prob = probs + Align;
|
||||||
|
numDirectBits = kNumAlignBits;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
unsigned i = 1;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
GET_BIT_CHECK(prob + i, i);
|
||||||
|
}
|
||||||
|
while (--numDirectBits != 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NORMALIZE_CHECK;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
p->needFlush = 1;
|
||||||
|
p->remainLen = 0;
|
||||||
|
p->tempBufSize = 0;
|
||||||
|
|
||||||
|
if (initDic)
|
||||||
|
{
|
||||||
|
p->processedPos = 0;
|
||||||
|
p->checkDicSize = 0;
|
||||||
|
p->needInitState = 1;
|
||||||
|
}
|
||||||
|
if (initState)
|
||||||
|
p->needInitState = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LzmaDec_Init(CLzmaDec *p)
|
||||||
|
{
|
||||||
|
p->dicPos = 0;
|
||||||
|
LzmaDec_InitDicAndState(p, True, True);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void LzmaDec_InitStateReal(CLzmaDec *p)
|
||||||
|
{
|
||||||
|
UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp));
|
||||||
|
UInt32 i;
|
||||||
|
CLzmaProb *probs = p->probs;
|
||||||
|
for (i = 0; i < numProbs; i++)
|
||||||
|
probs[i] = kBitModelTotal >> 1;
|
||||||
|
p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1;
|
||||||
|
p->state = 0;
|
||||||
|
p->needInitState = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,
|
||||||
|
ELzmaFinishMode finishMode, ELzmaStatus *status)
|
||||||
|
{
|
||||||
|
SizeT inSize = *srcLen;
|
||||||
|
(*srcLen) = 0;
|
||||||
|
LzmaDec_WriteRem(p, dicLimit);
|
||||||
|
|
||||||
|
*status = LZMA_STATUS_NOT_SPECIFIED;
|
||||||
|
|
||||||
|
while (p->remainLen != kMatchSpecLenStart)
|
||||||
|
{
|
||||||
|
int checkEndMarkNow;
|
||||||
|
|
||||||
|
if (p->needFlush != 0)
|
||||||
|
{
|
||||||
|
for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)
|
||||||
|
p->tempBuf[p->tempBufSize++] = *src++;
|
||||||
|
if (p->tempBufSize < RC_INIT_SIZE)
|
||||||
|
{
|
||||||
|
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
if (p->tempBuf[0] != 0)
|
||||||
|
return SZ_ERROR_DATA;
|
||||||
|
|
||||||
|
LzmaDec_InitRc(p, p->tempBuf);
|
||||||
|
p->tempBufSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
checkEndMarkNow = 0;
|
||||||
|
if (p->dicPos >= dicLimit)
|
||||||
|
{
|
||||||
|
if (p->remainLen == 0 && p->code == 0)
|
||||||
|
{
|
||||||
|
*status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK;
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
if (finishMode == LZMA_FINISH_ANY)
|
||||||
|
{
|
||||||
|
*status = LZMA_STATUS_NOT_FINISHED;
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
if (p->remainLen != 0)
|
||||||
|
{
|
||||||
|
*status = LZMA_STATUS_NOT_FINISHED;
|
||||||
|
return SZ_ERROR_DATA;
|
||||||
|
}
|
||||||
|
checkEndMarkNow = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p->needInitState)
|
||||||
|
LzmaDec_InitStateReal(p);
|
||||||
|
|
||||||
|
if (p->tempBufSize == 0)
|
||||||
|
{
|
||||||
|
SizeT processed;
|
||||||
|
const Byte *bufLimit;
|
||||||
|
if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
|
||||||
|
{
|
||||||
|
int dummyRes = LzmaDec_TryDummy(p, src, inSize);
|
||||||
|
if (dummyRes == DUMMY_ERROR)
|
||||||
|
{
|
||||||
|
memcpy(p->tempBuf, src, inSize);
|
||||||
|
p->tempBufSize = (unsigned)inSize;
|
||||||
|
(*srcLen) += inSize;
|
||||||
|
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
|
||||||
|
{
|
||||||
|
*status = LZMA_STATUS_NOT_FINISHED;
|
||||||
|
return SZ_ERROR_DATA;
|
||||||
|
}
|
||||||
|
bufLimit = src;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX;
|
||||||
|
p->buf = src;
|
||||||
|
if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0)
|
||||||
|
return SZ_ERROR_DATA;
|
||||||
|
processed = (SizeT)(p->buf - src);
|
||||||
|
(*srcLen) += processed;
|
||||||
|
src += processed;
|
||||||
|
inSize -= processed;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned rem = p->tempBufSize, lookAhead = 0;
|
||||||
|
while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize)
|
||||||
|
p->tempBuf[rem++] = src[lookAhead++];
|
||||||
|
p->tempBufSize = rem;
|
||||||
|
if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
|
||||||
|
{
|
||||||
|
int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem);
|
||||||
|
if (dummyRes == DUMMY_ERROR)
|
||||||
|
{
|
||||||
|
(*srcLen) += lookAhead;
|
||||||
|
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
|
||||||
|
{
|
||||||
|
*status = LZMA_STATUS_NOT_FINISHED;
|
||||||
|
return SZ_ERROR_DATA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p->buf = p->tempBuf;
|
||||||
|
if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0)
|
||||||
|
return SZ_ERROR_DATA;
|
||||||
|
lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf));
|
||||||
|
(*srcLen) += lookAhead;
|
||||||
|
src += lookAhead;
|
||||||
|
inSize -= lookAhead;
|
||||||
|
p->tempBufSize = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (p->code == 0)
|
||||||
|
*status = LZMA_STATUS_FINISHED_WITH_MARK;
|
||||||
|
return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
|
||||||
|
{
|
||||||
|
SizeT outSize = *destLen;
|
||||||
|
SizeT inSize = *srcLen;
|
||||||
|
*srcLen = *destLen = 0;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
SizeT inSizeCur = inSize, outSizeCur, dicPos;
|
||||||
|
ELzmaFinishMode curFinishMode;
|
||||||
|
SRes res;
|
||||||
|
if (p->dicPos == p->dicBufSize)
|
||||||
|
p->dicPos = 0;
|
||||||
|
dicPos = p->dicPos;
|
||||||
|
if (outSize > p->dicBufSize - dicPos)
|
||||||
|
{
|
||||||
|
outSizeCur = p->dicBufSize;
|
||||||
|
curFinishMode = LZMA_FINISH_ANY;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
outSizeCur = dicPos + outSize;
|
||||||
|
curFinishMode = finishMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status);
|
||||||
|
src += inSizeCur;
|
||||||
|
inSize -= inSizeCur;
|
||||||
|
*srcLen += inSizeCur;
|
||||||
|
outSizeCur = p->dicPos - dicPos;
|
||||||
|
memcpy(dest, p->dic + dicPos, outSizeCur);
|
||||||
|
dest += outSizeCur;
|
||||||
|
outSize -= outSizeCur;
|
||||||
|
*destLen += outSizeCur;
|
||||||
|
if (res != 0)
|
||||||
|
return res;
|
||||||
|
if (outSizeCur == 0 || outSize == 0)
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
alloc->Free(alloc, p->probs);
|
||||||
|
p->probs = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
alloc->Free(alloc, p->dic);
|
||||||
|
p->dic = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
LzmaDec_FreeProbs(p, alloc);
|
||||||
|
LzmaDec_FreeDict(p, alloc);
|
||||||
|
}
|
||||||
|
|
||||||
|
SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
|
||||||
|
{
|
||||||
|
UInt32 dicSize;
|
||||||
|
Byte d;
|
||||||
|
|
||||||
|
if (size < LZMA_PROPS_SIZE)
|
||||||
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
|
else
|
||||||
|
dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24);
|
||||||
|
|
||||||
|
if (dicSize < LZMA_DIC_MIN)
|
||||||
|
dicSize = LZMA_DIC_MIN;
|
||||||
|
p->dicSize = dicSize;
|
||||||
|
|
||||||
|
d = data[0];
|
||||||
|
if (d >= (9 * 5 * 5))
|
||||||
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
|
|
||||||
|
p->lc = d % 9;
|
||||||
|
d /= 9;
|
||||||
|
p->pb = d / 5;
|
||||||
|
p->lp = d % 5;
|
||||||
|
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
UInt32 numProbs = LzmaProps_GetNumProbs(propNew);
|
||||||
|
if (p->probs == 0 || numProbs != p->numProbs)
|
||||||
|
{
|
||||||
|
LzmaDec_FreeProbs(p, alloc);
|
||||||
|
p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb));
|
||||||
|
p->numProbs = numProbs;
|
||||||
|
if (p->probs == 0)
|
||||||
|
return SZ_ERROR_MEM;
|
||||||
|
}
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
CLzmaProps propNew;
|
||||||
|
RINOK(LzmaProps_Decode(&propNew, props, propsSize));
|
||||||
|
RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
|
||||||
|
p->prop = propNew;
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *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)
|
||||||
|
{
|
||||||
|
LzmaDec_FreeDict(p, alloc);
|
||||||
|
p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize);
|
||||||
|
if (p->dic == 0)
|
||||||
|
{
|
||||||
|
LzmaDec_FreeProbs(p, alloc);
|
||||||
|
return SZ_ERROR_MEM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p->dicBufSize = dicBufSize;
|
||||||
|
p->prop = propNew;
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
||||||
|
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
|
||||||
|
ELzmaStatus *status, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
CLzmaDec p;
|
||||||
|
SRes res;
|
||||||
|
SizeT inSize = *srcLen;
|
||||||
|
SizeT outSize = *destLen;
|
||||||
|
*srcLen = *destLen = 0;
|
||||||
|
if (inSize < RC_INIT_SIZE)
|
||||||
|
return SZ_ERROR_INPUT_EOF;
|
||||||
|
|
||||||
|
LzmaDec_Construct(&p);
|
||||||
|
res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc);
|
||||||
|
if (res != 0)
|
||||||
|
return res;
|
||||||
|
p.dic = dest;
|
||||||
|
p.dicBufSize = outSize;
|
||||||
|
|
||||||
|
LzmaDec_Init(&p);
|
||||||
|
|
||||||
|
*srcLen = inSize;
|
||||||
|
res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
|
||||||
|
|
||||||
|
if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
|
||||||
|
res = SZ_ERROR_INPUT_EOF;
|
||||||
|
|
||||||
|
(*destLen) = p.dicPos;
|
||||||
|
LzmaDec_FreeProbs(&p, alloc);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
@@ -0,0 +1,231 @@
|
|||||||
|
/* LzmaDec.h -- LZMA Decoder
|
||||||
|
2009-02-07 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#ifndef __LZMA_DEC_H
|
||||||
|
#define __LZMA_DEC_H
|
||||||
|
|
||||||
|
#include "Types.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* #define _LZMA_PROB32 */
|
||||||
|
/* _LZMA_PROB32 can increase the speed on some CPUs,
|
||||||
|
but memory usage for CLzmaDec::probs will be doubled in that case */
|
||||||
|
|
||||||
|
#ifdef _LZMA_PROB32
|
||||||
|
#define CLzmaProb UInt32
|
||||||
|
#else
|
||||||
|
#define CLzmaProb UInt16
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- LZMA Properties ---------- */
|
||||||
|
|
||||||
|
#define LZMA_PROPS_SIZE 5
|
||||||
|
|
||||||
|
typedef struct _CLzmaProps
|
||||||
|
{
|
||||||
|
unsigned lc, lp, pb;
|
||||||
|
UInt32 dicSize;
|
||||||
|
} CLzmaProps;
|
||||||
|
|
||||||
|
/* LzmaProps_Decode - decodes properties
|
||||||
|
Returns:
|
||||||
|
SZ_OK
|
||||||
|
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
||||||
|
*/
|
||||||
|
|
||||||
|
SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- LZMA Decoder state ---------- */
|
||||||
|
|
||||||
|
/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case.
|
||||||
|
Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */
|
||||||
|
|
||||||
|
#define LZMA_REQUIRED_INPUT_MAX 20
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
CLzmaProps prop;
|
||||||
|
CLzmaProb *probs;
|
||||||
|
Byte *dic;
|
||||||
|
const Byte *buf;
|
||||||
|
UInt32 range, code;
|
||||||
|
SizeT dicPos;
|
||||||
|
SizeT dicBufSize;
|
||||||
|
UInt32 processedPos;
|
||||||
|
UInt32 checkDicSize;
|
||||||
|
unsigned state;
|
||||||
|
UInt32 reps[4];
|
||||||
|
unsigned remainLen;
|
||||||
|
int needFlush;
|
||||||
|
int needInitState;
|
||||||
|
UInt32 numProbs;
|
||||||
|
unsigned tempBufSize;
|
||||||
|
Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];
|
||||||
|
} CLzmaDec;
|
||||||
|
|
||||||
|
#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; }
|
||||||
|
|
||||||
|
void LzmaDec_Init(CLzmaDec *p);
|
||||||
|
|
||||||
|
/* There are two types of LZMA streams:
|
||||||
|
0) Stream with end mark. That end mark adds about 6 bytes to compressed size.
|
||||||
|
1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
LZMA_FINISH_ANY, /* finish at any point */
|
||||||
|
LZMA_FINISH_END /* block must be finished at the end */
|
||||||
|
} ELzmaFinishMode;
|
||||||
|
|
||||||
|
/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!!
|
||||||
|
|
||||||
|
You must use LZMA_FINISH_END, when you know that current output buffer
|
||||||
|
covers last bytes of block. In other cases you must use LZMA_FINISH_ANY.
|
||||||
|
|
||||||
|
If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK,
|
||||||
|
and output value of destLen will be less than output buffer size limit.
|
||||||
|
You can check status result also.
|
||||||
|
|
||||||
|
You can use multiple checks to test data integrity after full decompression:
|
||||||
|
1) Check Result and "status" variable.
|
||||||
|
2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
|
||||||
|
3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
|
||||||
|
You must use correct finish mode in that case. */
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */
|
||||||
|
LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */
|
||||||
|
LZMA_STATUS_NOT_FINISHED, /* stream was not finished */
|
||||||
|
LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */
|
||||||
|
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */
|
||||||
|
} ELzmaStatus;
|
||||||
|
|
||||||
|
/* ELzmaStatus is used only as output value for function call */
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- Interfaces ---------- */
|
||||||
|
|
||||||
|
/* There are 3 levels of interfaces:
|
||||||
|
1) Dictionary Interface
|
||||||
|
2) Buffer Interface
|
||||||
|
3) One Call Interface
|
||||||
|
You can select any of these interfaces, but don't mix functions from different
|
||||||
|
groups for same object. */
|
||||||
|
|
||||||
|
|
||||||
|
/* There are two variants to allocate state for Dictionary Interface:
|
||||||
|
1) LzmaDec_Allocate / LzmaDec_Free
|
||||||
|
2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs
|
||||||
|
You can use variant 2, if you set dictionary buffer manually.
|
||||||
|
For Buffer Interface you must always use variant 1.
|
||||||
|
|
||||||
|
LzmaDec_Allocate* can return:
|
||||||
|
SZ_OK
|
||||||
|
SZ_ERROR_MEM - Memory allocation error
|
||||||
|
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
||||||
|
*/
|
||||||
|
|
||||||
|
SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc);
|
||||||
|
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);
|
||||||
|
|
||||||
|
SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc);
|
||||||
|
void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
|
||||||
|
|
||||||
|
/* ---------- Dictionary Interface ---------- */
|
||||||
|
|
||||||
|
/* You can use it, if you want to eliminate the overhead for data copying from
|
||||||
|
dictionary to some other external buffer.
|
||||||
|
You must work with CLzmaDec variables directly in this interface.
|
||||||
|
|
||||||
|
STEPS:
|
||||||
|
LzmaDec_Constr()
|
||||||
|
LzmaDec_Allocate()
|
||||||
|
for (each new stream)
|
||||||
|
{
|
||||||
|
LzmaDec_Init()
|
||||||
|
while (it needs more decompression)
|
||||||
|
{
|
||||||
|
LzmaDec_DecodeToDic()
|
||||||
|
use data from CLzmaDec::dic and update CLzmaDec::dicPos
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LzmaDec_Free()
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* LzmaDec_DecodeToDic
|
||||||
|
|
||||||
|
The decoding to internal dictionary buffer (CLzmaDec::dic).
|
||||||
|
You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
|
||||||
|
|
||||||
|
finishMode:
|
||||||
|
It has meaning only if the decoding reaches output limit (dicLimit).
|
||||||
|
LZMA_FINISH_ANY - Decode just dicLimit bytes.
|
||||||
|
LZMA_FINISH_END - Stream must be finished after dicLimit.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
SZ_OK
|
||||||
|
status:
|
||||||
|
LZMA_STATUS_FINISHED_WITH_MARK
|
||||||
|
LZMA_STATUS_NOT_FINISHED
|
||||||
|
LZMA_STATUS_NEEDS_MORE_INPUT
|
||||||
|
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
|
||||||
|
SZ_ERROR_DATA - Data error
|
||||||
|
*/
|
||||||
|
|
||||||
|
SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit,
|
||||||
|
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- Buffer Interface ---------- */
|
||||||
|
|
||||||
|
/* It's zlib-like interface.
|
||||||
|
See LzmaDec_DecodeToDic description for information about STEPS and return results,
|
||||||
|
but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need
|
||||||
|
to work with CLzmaDec variables manually.
|
||||||
|
|
||||||
|
finishMode:
|
||||||
|
It has meaning only if the decoding reaches output limit (*destLen).
|
||||||
|
LZMA_FINISH_ANY - Decode just destLen bytes.
|
||||||
|
LZMA_FINISH_END - Stream must be finished after (*destLen).
|
||||||
|
*/
|
||||||
|
|
||||||
|
SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
|
||||||
|
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- One Call Interface ---------- */
|
||||||
|
|
||||||
|
/* LzmaDecode
|
||||||
|
|
||||||
|
finishMode:
|
||||||
|
It has meaning only if the decoding reaches output limit (*destLen).
|
||||||
|
LZMA_FINISH_ANY - Decode just destLen bytes.
|
||||||
|
LZMA_FINISH_END - Stream must be finished after (*destLen).
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
SZ_OK
|
||||||
|
status:
|
||||||
|
LZMA_STATUS_FINISHED_WITH_MARK
|
||||||
|
LZMA_STATUS_NOT_FINISHED
|
||||||
|
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
|
||||||
|
SZ_ERROR_DATA - Data error
|
||||||
|
SZ_ERROR_MEM - Memory allocation error
|
||||||
|
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
||||||
|
SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
|
||||||
|
*/
|
||||||
|
|
||||||
|
SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
||||||
|
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
|
||||||
|
ELzmaStatus *status, ISzAlloc *alloc);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,80 @@
|
|||||||
|
/* LzmaEnc.h -- LZMA Encoder
|
||||||
|
2009-02-07 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#ifndef __LZMA_ENC_H
|
||||||
|
#define __LZMA_ENC_H
|
||||||
|
|
||||||
|
#include "Types.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LZMA_PROPS_SIZE 5
|
||||||
|
|
||||||
|
typedef struct _CLzmaEncProps
|
||||||
|
{
|
||||||
|
int level; /* 0 <= level <= 9 */
|
||||||
|
UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version
|
||||||
|
(1 << 12) <= dictSize <= (1 << 30) for 64-bit version
|
||||||
|
default = (1 << 24) */
|
||||||
|
int lc; /* 0 <= lc <= 8, default = 3 */
|
||||||
|
int lp; /* 0 <= lp <= 4, default = 0 */
|
||||||
|
int pb; /* 0 <= pb <= 4, default = 2 */
|
||||||
|
int algo; /* 0 - fast, 1 - normal, default = 1 */
|
||||||
|
int fb; /* 5 <= fb <= 273, default = 32 */
|
||||||
|
int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */
|
||||||
|
int numHashBytes; /* 2, 3 or 4, default = 4 */
|
||||||
|
UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */
|
||||||
|
unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */
|
||||||
|
int numThreads; /* 1 or 2, default = 2 */
|
||||||
|
} CLzmaEncProps;
|
||||||
|
|
||||||
|
void LzmaEncProps_Init(CLzmaEncProps *p);
|
||||||
|
void LzmaEncProps_Normalize(CLzmaEncProps *p);
|
||||||
|
UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2);
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- CLzmaEncHandle Interface ---------- */
|
||||||
|
|
||||||
|
/* LzmaEnc_* functions can return the following exit codes:
|
||||||
|
Returns:
|
||||||
|
SZ_OK - OK
|
||||||
|
SZ_ERROR_MEM - Memory allocation error
|
||||||
|
SZ_ERROR_PARAM - Incorrect paramater in props
|
||||||
|
SZ_ERROR_WRITE - Write callback error.
|
||||||
|
SZ_ERROR_PROGRESS - some break from progress callback
|
||||||
|
SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef void * CLzmaEncHandle;
|
||||||
|
|
||||||
|
CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc);
|
||||||
|
void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig);
|
||||||
|
SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props);
|
||||||
|
SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size);
|
||||||
|
SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream,
|
||||||
|
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
|
||||||
|
SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
|
||||||
|
int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
|
||||||
|
|
||||||
|
/* ---------- One Call Interface ---------- */
|
||||||
|
|
||||||
|
/* LzmaEncode
|
||||||
|
Return code:
|
||||||
|
SZ_OK - OK
|
||||||
|
SZ_ERROR_MEM - Memory allocation error
|
||||||
|
SZ_ERROR_PARAM - Incorrect paramater
|
||||||
|
SZ_ERROR_OUTPUT_EOF - output buffer overflow
|
||||||
|
SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
|
||||||
|
*/
|
||||||
|
|
||||||
|
SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
|
||||||
|
const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
|
||||||
|
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
/* LzmaLib.c -- LZMA library wrapper
|
||||||
|
2008-08-05
|
||||||
|
Igor Pavlov
|
||||||
|
Public domain */
|
||||||
|
|
||||||
|
#include "LzmaEnc.h"
|
||||||
|
#include "LzmaDec.h"
|
||||||
|
#include "Alloc.h"
|
||||||
|
#include "LzmaLib.h"
|
||||||
|
|
||||||
|
static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }
|
||||||
|
static void SzFree(void *p, void *address) { p = p; MyFree(address); }
|
||||||
|
static ISzAlloc g_Alloc = { SzAlloc, SzFree };
|
||||||
|
|
||||||
|
MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen,
|
||||||
|
unsigned char *outProps, size_t *outPropsSize,
|
||||||
|
int level, /* 0 <= level <= 9, default = 5 */
|
||||||
|
unsigned dictSize, /* use (1 << N) or (3 << N). 4 KB < dictSize <= 128 MB */
|
||||||
|
int lc, /* 0 <= lc <= 8, default = 3 */
|
||||||
|
int lp, /* 0 <= lp <= 4, default = 0 */
|
||||||
|
int pb, /* 0 <= pb <= 4, default = 2 */
|
||||||
|
int fb, /* 5 <= fb <= 273, default = 32 */
|
||||||
|
int numThreads /* 1 or 2, default = 2 */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
CLzmaEncProps props;
|
||||||
|
LzmaEncProps_Init(&props);
|
||||||
|
props.level = level;
|
||||||
|
props.dictSize = dictSize;
|
||||||
|
props.lc = lc;
|
||||||
|
props.lp = lp;
|
||||||
|
props.pb = pb;
|
||||||
|
props.fb = fb;
|
||||||
|
props.numThreads = numThreads;
|
||||||
|
|
||||||
|
return LzmaEncode(dest, destLen, src, srcLen, &props, outProps, outPropsSize, 0,
|
||||||
|
NULL, &g_Alloc, &g_Alloc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t *srcLen,
|
||||||
|
const unsigned char *props, size_t propsSize)
|
||||||
|
{
|
||||||
|
ELzmaStatus status;
|
||||||
|
return LzmaDecode(dest, destLen, src, srcLen, props, (unsigned)propsSize, LZMA_FINISH_ANY, &status, &g_Alloc);
|
||||||
|
}
|
||||||
@@ -0,0 +1,135 @@
|
|||||||
|
/* LzmaLib.h -- LZMA library interface
|
||||||
|
2009-04-07 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#ifndef __LZMA_LIB_H
|
||||||
|
#define __LZMA_LIB_H
|
||||||
|
|
||||||
|
#include "Types.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MY_STDAPI int MY_STD_CALL
|
||||||
|
|
||||||
|
#define LZMA_PROPS_SIZE 5
|
||||||
|
|
||||||
|
/*
|
||||||
|
RAM requirements for LZMA:
|
||||||
|
for compression: (dictSize * 11.5 + 6 MB) + state_size
|
||||||
|
for decompression: dictSize + state_size
|
||||||
|
state_size = (4 + (1.5 << (lc + lp))) KB
|
||||||
|
by default (lc=3, lp=0), state_size = 16 KB.
|
||||||
|
|
||||||
|
LZMA properties (5 bytes) format
|
||||||
|
Offset Size Description
|
||||||
|
0 1 lc, lp and pb in encoded form.
|
||||||
|
1 4 dictSize (little endian).
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
LzmaCompress
|
||||||
|
------------
|
||||||
|
|
||||||
|
outPropsSize -
|
||||||
|
In: the pointer to the size of outProps buffer; *outPropsSize = LZMA_PROPS_SIZE = 5.
|
||||||
|
Out: the pointer to the size of written properties in outProps buffer; *outPropsSize = LZMA_PROPS_SIZE = 5.
|
||||||
|
|
||||||
|
LZMA Encoder will use defult values for any parameter, if it is
|
||||||
|
-1 for any from: level, loc, lp, pb, fb, numThreads
|
||||||
|
0 for dictSize
|
||||||
|
|
||||||
|
level - compression level: 0 <= level <= 9;
|
||||||
|
|
||||||
|
level dictSize algo fb
|
||||||
|
0: 16 KB 0 32
|
||||||
|
1: 64 KB 0 32
|
||||||
|
2: 256 KB 0 32
|
||||||
|
3: 1 MB 0 32
|
||||||
|
4: 4 MB 0 32
|
||||||
|
5: 16 MB 1 32
|
||||||
|
6: 32 MB 1 32
|
||||||
|
7+: 64 MB 1 64
|
||||||
|
|
||||||
|
The default value for "level" is 5.
|
||||||
|
|
||||||
|
algo = 0 means fast method
|
||||||
|
algo = 1 means normal method
|
||||||
|
|
||||||
|
dictSize - The dictionary size in bytes. The maximum value is
|
||||||
|
128 MB = (1 << 27) bytes for 32-bit version
|
||||||
|
1 GB = (1 << 30) bytes for 64-bit version
|
||||||
|
The default value is 16 MB = (1 << 24) bytes.
|
||||||
|
It's recommended to use the dictionary that is larger than 4 KB and
|
||||||
|
that can be calculated as (1 << N) or (3 << N) sizes.
|
||||||
|
|
||||||
|
lc - The number of literal context bits (high bits of previous literal).
|
||||||
|
It can be in the range from 0 to 8. The default value is 3.
|
||||||
|
Sometimes lc=4 gives the gain for big files.
|
||||||
|
|
||||||
|
lp - The number of literal pos bits (low bits of current position for literals).
|
||||||
|
It can be in the range from 0 to 4. The default value is 0.
|
||||||
|
The lp switch is intended for periodical data when the period is equal to 2^lp.
|
||||||
|
For example, for 32-bit (4 bytes) periodical data you can use lp=2. Often it's
|
||||||
|
better to set lc=0, if you change lp switch.
|
||||||
|
|
||||||
|
pb - The number of pos bits (low bits of current position).
|
||||||
|
It can be in the range from 0 to 4. The default value is 2.
|
||||||
|
The pb switch is intended for periodical data when the period is equal 2^pb.
|
||||||
|
|
||||||
|
fb - Word size (the number of fast bytes).
|
||||||
|
It can be in the range from 5 to 273. The default value is 32.
|
||||||
|
Usually, a big number gives a little bit better compression ratio and
|
||||||
|
slower compression process.
|
||||||
|
|
||||||
|
numThreads - The number of thereads. 1 or 2. The default value is 2.
|
||||||
|
Fast mode (algo = 0) can use only 1 thread.
|
||||||
|
|
||||||
|
Out:
|
||||||
|
destLen - processed output size
|
||||||
|
Returns:
|
||||||
|
SZ_OK - OK
|
||||||
|
SZ_ERROR_MEM - Memory allocation error
|
||||||
|
SZ_ERROR_PARAM - Incorrect paramater
|
||||||
|
SZ_ERROR_OUTPUT_EOF - output buffer overflow
|
||||||
|
SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
|
||||||
|
*/
|
||||||
|
|
||||||
|
MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen,
|
||||||
|
unsigned char *outProps, size_t *outPropsSize, /* *outPropsSize must be = 5 */
|
||||||
|
int level, /* 0 <= level <= 9, default = 5 */
|
||||||
|
unsigned dictSize, /* default = (1 << 24) */
|
||||||
|
int lc, /* 0 <= lc <= 8, default = 3 */
|
||||||
|
int lp, /* 0 <= lp <= 4, default = 0 */
|
||||||
|
int pb, /* 0 <= pb <= 4, default = 2 */
|
||||||
|
int fb, /* 5 <= fb <= 273, default = 32 */
|
||||||
|
int numThreads /* 1 or 2, default = 2 */
|
||||||
|
);
|
||||||
|
|
||||||
|
/*
|
||||||
|
LzmaUncompress
|
||||||
|
--------------
|
||||||
|
In:
|
||||||
|
dest - output data
|
||||||
|
destLen - output data size
|
||||||
|
src - input data
|
||||||
|
srcLen - input data size
|
||||||
|
Out:
|
||||||
|
destLen - processed output size
|
||||||
|
srcLen - processed input size
|
||||||
|
Returns:
|
||||||
|
SZ_OK - OK
|
||||||
|
SZ_ERROR_DATA - Data error
|
||||||
|
SZ_ERROR_MEM - Memory allocation arror
|
||||||
|
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
||||||
|
SZ_ERROR_INPUT_EOF - it needs more bytes in input buffer (src)
|
||||||
|
*/
|
||||||
|
|
||||||
|
MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, SizeT *srcLen,
|
||||||
|
const unsigned char *props, size_t propsSize);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,327 @@
|
|||||||
|
/* MtCoder.c -- Multi-thread Coder
|
||||||
|
2010-03-24 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "MtCoder.h"
|
||||||
|
|
||||||
|
void LoopThread_Construct(CLoopThread *p)
|
||||||
|
{
|
||||||
|
Thread_Construct(&p->thread);
|
||||||
|
Event_Construct(&p->startEvent);
|
||||||
|
Event_Construct(&p->finishedEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoopThread_Close(CLoopThread *p)
|
||||||
|
{
|
||||||
|
Thread_Close(&p->thread);
|
||||||
|
Event_Close(&p->startEvent);
|
||||||
|
Event_Close(&p->finishedEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE LoopThreadFunc(void *pp)
|
||||||
|
{
|
||||||
|
CLoopThread *p = (CLoopThread *)pp;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (Event_Wait(&p->startEvent) != 0)
|
||||||
|
return SZ_ERROR_THREAD;
|
||||||
|
if (p->stop)
|
||||||
|
return 0;
|
||||||
|
p->res = p->func(p->param);
|
||||||
|
if (Event_Set(&p->finishedEvent) != 0)
|
||||||
|
return SZ_ERROR_THREAD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WRes LoopThread_Create(CLoopThread *p)
|
||||||
|
{
|
||||||
|
p->stop = 0;
|
||||||
|
RINOK(AutoResetEvent_CreateNotSignaled(&p->startEvent));
|
||||||
|
RINOK(AutoResetEvent_CreateNotSignaled(&p->finishedEvent));
|
||||||
|
return Thread_Create(&p->thread, LoopThreadFunc, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
WRes LoopThread_StopAndWait(CLoopThread *p)
|
||||||
|
{
|
||||||
|
p->stop = 1;
|
||||||
|
if (Event_Set(&p->startEvent) != 0)
|
||||||
|
return SZ_ERROR_THREAD;
|
||||||
|
return Thread_Wait(&p->thread);
|
||||||
|
}
|
||||||
|
|
||||||
|
WRes LoopThread_StartSubThread(CLoopThread *p) { return Event_Set(&p->startEvent); }
|
||||||
|
WRes LoopThread_WaitSubThread(CLoopThread *p) { return Event_Wait(&p->finishedEvent); }
|
||||||
|
|
||||||
|
static SRes Progress(ICompressProgress *p, UInt64 inSize, UInt64 outSize)
|
||||||
|
{
|
||||||
|
return (p && p->Progress(p, inSize, outSize) != SZ_OK) ? SZ_ERROR_PROGRESS : SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MtProgress_Init(CMtProgress *p, ICompressProgress *progress)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; i < NUM_MT_CODER_THREADS_MAX; i++)
|
||||||
|
p->inSizes[i] = p->outSizes[i] = 0;
|
||||||
|
p->totalInSize = p->totalOutSize = 0;
|
||||||
|
p->progress = progress;
|
||||||
|
p->res = SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MtProgress_Reinit(CMtProgress *p, unsigned index)
|
||||||
|
{
|
||||||
|
p->inSizes[index] = 0;
|
||||||
|
p->outSizes[index] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define UPDATE_PROGRESS(size, prev, total) \
|
||||||
|
if (size != (UInt64)(Int64)-1) { total += size - prev; prev = size; }
|
||||||
|
|
||||||
|
SRes MtProgress_Set(CMtProgress *p, unsigned index, UInt64 inSize, UInt64 outSize)
|
||||||
|
{
|
||||||
|
SRes res;
|
||||||
|
CriticalSection_Enter(&p->cs);
|
||||||
|
UPDATE_PROGRESS(inSize, p->inSizes[index], p->totalInSize)
|
||||||
|
UPDATE_PROGRESS(outSize, p->outSizes[index], p->totalOutSize)
|
||||||
|
if (p->res == SZ_OK)
|
||||||
|
p->res = Progress(p->progress, p->totalInSize, p->totalOutSize);
|
||||||
|
res = p->res;
|
||||||
|
CriticalSection_Leave(&p->cs);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MtProgress_SetError(CMtProgress *p, SRes res)
|
||||||
|
{
|
||||||
|
CriticalSection_Enter(&p->cs);
|
||||||
|
if (p->res == SZ_OK)
|
||||||
|
p->res = res;
|
||||||
|
CriticalSection_Leave(&p->cs);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MtCoder_SetError(CMtCoder* p, SRes res)
|
||||||
|
{
|
||||||
|
CriticalSection_Enter(&p->cs);
|
||||||
|
if (p->res == SZ_OK)
|
||||||
|
p->res = res;
|
||||||
|
CriticalSection_Leave(&p->cs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------- MtThread ---------- */
|
||||||
|
|
||||||
|
void CMtThread_Construct(CMtThread *p, CMtCoder *mtCoder)
|
||||||
|
{
|
||||||
|
p->mtCoder = mtCoder;
|
||||||
|
p->outBuf = 0;
|
||||||
|
p->inBuf = 0;
|
||||||
|
Event_Construct(&p->canRead);
|
||||||
|
Event_Construct(&p->canWrite);
|
||||||
|
LoopThread_Construct(&p->thread);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define RINOK_THREAD(x) { if((x) != 0) return SZ_ERROR_THREAD; }
|
||||||
|
|
||||||
|
static void CMtThread_CloseEvents(CMtThread *p)
|
||||||
|
{
|
||||||
|
Event_Close(&p->canRead);
|
||||||
|
Event_Close(&p->canWrite);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CMtThread_Destruct(CMtThread *p)
|
||||||
|
{
|
||||||
|
CMtThread_CloseEvents(p);
|
||||||
|
|
||||||
|
if (Thread_WasCreated(&p->thread.thread))
|
||||||
|
{
|
||||||
|
LoopThread_StopAndWait(&p->thread);
|
||||||
|
LoopThread_Close(&p->thread);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p->mtCoder->alloc)
|
||||||
|
IAlloc_Free(p->mtCoder->alloc, p->outBuf);
|
||||||
|
p->outBuf = 0;
|
||||||
|
|
||||||
|
if (p->mtCoder->alloc)
|
||||||
|
IAlloc_Free(p->mtCoder->alloc, p->inBuf);
|
||||||
|
p->inBuf = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MY_BUF_ALLOC(buf, size, newSize) \
|
||||||
|
if (buf == 0 || size != newSize) \
|
||||||
|
{ IAlloc_Free(p->mtCoder->alloc, buf); \
|
||||||
|
size = newSize; buf = IAlloc_Alloc(p->mtCoder->alloc, size); \
|
||||||
|
if (buf == 0) return SZ_ERROR_MEM; }
|
||||||
|
|
||||||
|
static SRes CMtThread_Prepare(CMtThread *p)
|
||||||
|
{
|
||||||
|
MY_BUF_ALLOC(p->inBuf, p->inBufSize, p->mtCoder->blockSize)
|
||||||
|
MY_BUF_ALLOC(p->outBuf, p->outBufSize, p->mtCoder->destBlockSize)
|
||||||
|
|
||||||
|
p->stopReading = False;
|
||||||
|
p->stopWriting = False;
|
||||||
|
RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->canRead));
|
||||||
|
RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->canWrite));
|
||||||
|
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SRes FullRead(ISeqInStream *stream, Byte *data, size_t *processedSize)
|
||||||
|
{
|
||||||
|
size_t size = *processedSize;
|
||||||
|
*processedSize = 0;
|
||||||
|
while (size != 0)
|
||||||
|
{
|
||||||
|
size_t curSize = size;
|
||||||
|
SRes res = stream->Read(stream, data, &curSize);
|
||||||
|
*processedSize += curSize;
|
||||||
|
data += curSize;
|
||||||
|
size -= curSize;
|
||||||
|
RINOK(res);
|
||||||
|
if (curSize == 0)
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define GET_NEXT_THREAD(p) &p->mtCoder->threads[p->index == p->mtCoder->numThreads - 1 ? 0 : p->index + 1]
|
||||||
|
|
||||||
|
static SRes MtThread_Process(CMtThread *p, Bool *stop)
|
||||||
|
{
|
||||||
|
CMtThread *next;
|
||||||
|
*stop = True;
|
||||||
|
if (Event_Wait(&p->canRead) != 0)
|
||||||
|
return SZ_ERROR_THREAD;
|
||||||
|
|
||||||
|
next = GET_NEXT_THREAD(p);
|
||||||
|
|
||||||
|
if (p->stopReading)
|
||||||
|
{
|
||||||
|
next->stopReading = True;
|
||||||
|
return Event_Set(&next->canRead) == 0 ? SZ_OK : SZ_ERROR_THREAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
size_t size = p->mtCoder->blockSize;
|
||||||
|
size_t destSize = p->outBufSize;
|
||||||
|
|
||||||
|
RINOK(FullRead(p->mtCoder->inStream, p->inBuf, &size));
|
||||||
|
next->stopReading = *stop = (size != p->mtCoder->blockSize);
|
||||||
|
if (Event_Set(&next->canRead) != 0)
|
||||||
|
return SZ_ERROR_THREAD;
|
||||||
|
|
||||||
|
RINOK(p->mtCoder->mtCallback->Code(p->mtCoder->mtCallback, p->index,
|
||||||
|
p->outBuf, &destSize, p->inBuf, size, *stop));
|
||||||
|
|
||||||
|
MtProgress_Reinit(&p->mtCoder->mtProgress, p->index);
|
||||||
|
|
||||||
|
if (Event_Wait(&p->canWrite) != 0)
|
||||||
|
return SZ_ERROR_THREAD;
|
||||||
|
if (p->stopWriting)
|
||||||
|
return SZ_ERROR_FAIL;
|
||||||
|
if (p->mtCoder->outStream->Write(p->mtCoder->outStream, p->outBuf, destSize) != destSize)
|
||||||
|
return SZ_ERROR_WRITE;
|
||||||
|
return Event_Set(&next->canWrite) == 0 ? SZ_OK : SZ_ERROR_THREAD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE ThreadFunc(void *pp)
|
||||||
|
{
|
||||||
|
CMtThread *p = (CMtThread *)pp;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
Bool stop;
|
||||||
|
CMtThread *next = GET_NEXT_THREAD(p);
|
||||||
|
SRes res = MtThread_Process(p, &stop);
|
||||||
|
if (res != SZ_OK)
|
||||||
|
{
|
||||||
|
MtCoder_SetError(p->mtCoder, res);
|
||||||
|
MtProgress_SetError(&p->mtCoder->mtProgress, res);
|
||||||
|
next->stopReading = True;
|
||||||
|
next->stopWriting = True;
|
||||||
|
Event_Set(&next->canRead);
|
||||||
|
Event_Set(&next->canWrite);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
if (stop)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MtCoder_Construct(CMtCoder* p)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
p->alloc = 0;
|
||||||
|
for (i = 0; i < NUM_MT_CODER_THREADS_MAX; i++)
|
||||||
|
{
|
||||||
|
CMtThread *t = &p->threads[i];
|
||||||
|
t->index = i;
|
||||||
|
CMtThread_Construct(t, p);
|
||||||
|
}
|
||||||
|
CriticalSection_Init(&p->cs);
|
||||||
|
CriticalSection_Init(&p->mtProgress.cs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MtCoder_Destruct(CMtCoder* p)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; i < NUM_MT_CODER_THREADS_MAX; i++)
|
||||||
|
CMtThread_Destruct(&p->threads[i]);
|
||||||
|
CriticalSection_Delete(&p->cs);
|
||||||
|
CriticalSection_Delete(&p->mtProgress.cs);
|
||||||
|
}
|
||||||
|
|
||||||
|
SRes MtCoder_Code(CMtCoder *p)
|
||||||
|
{
|
||||||
|
unsigned i, numThreads = p->numThreads;
|
||||||
|
SRes res = SZ_OK;
|
||||||
|
p->res = SZ_OK;
|
||||||
|
|
||||||
|
MtProgress_Init(&p->mtProgress, p->progress);
|
||||||
|
|
||||||
|
for (i = 0; i < numThreads; i++)
|
||||||
|
{
|
||||||
|
RINOK(CMtThread_Prepare(&p->threads[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < numThreads; i++)
|
||||||
|
{
|
||||||
|
CMtThread *t = &p->threads[i];
|
||||||
|
CLoopThread *lt = &t->thread;
|
||||||
|
|
||||||
|
if (!Thread_WasCreated(<->thread))
|
||||||
|
{
|
||||||
|
lt->func = ThreadFunc;
|
||||||
|
lt->param = t;
|
||||||
|
|
||||||
|
if (LoopThread_Create(lt) != SZ_OK)
|
||||||
|
{
|
||||||
|
res = SZ_ERROR_THREAD;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res == SZ_OK)
|
||||||
|
{
|
||||||
|
unsigned j;
|
||||||
|
for (i = 0; i < numThreads; i++)
|
||||||
|
{
|
||||||
|
CMtThread *t = &p->threads[i];
|
||||||
|
if (LoopThread_StartSubThread(&t->thread) != SZ_OK)
|
||||||
|
{
|
||||||
|
res = SZ_ERROR_THREAD;
|
||||||
|
p->threads[0].stopReading = True;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Event_Set(&p->threads[0].canWrite);
|
||||||
|
Event_Set(&p->threads[0].canRead);
|
||||||
|
|
||||||
|
for (j = 0; j < i; j++)
|
||||||
|
LoopThread_WaitSubThread(&p->threads[j].thread);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < numThreads; i++)
|
||||||
|
CMtThread_CloseEvents(&p->threads[i]);
|
||||||
|
return (res == SZ_OK) ? p->res : res;
|
||||||
|
}
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
/* MtCoder.h -- Multi-thread Coder
|
||||||
|
2009-11-19 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#ifndef __MT_CODER_H
|
||||||
|
#define __MT_CODER_H
|
||||||
|
|
||||||
|
#include "Threads.h"
|
||||||
|
|
||||||
|
EXTERN_C_BEGIN
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
CThread thread;
|
||||||
|
CAutoResetEvent startEvent;
|
||||||
|
CAutoResetEvent finishedEvent;
|
||||||
|
int stop;
|
||||||
|
|
||||||
|
THREAD_FUNC_TYPE func;
|
||||||
|
LPVOID param;
|
||||||
|
THREAD_FUNC_RET_TYPE res;
|
||||||
|
} CLoopThread;
|
||||||
|
|
||||||
|
void LoopThread_Construct(CLoopThread *p);
|
||||||
|
void LoopThread_Close(CLoopThread *p);
|
||||||
|
WRes LoopThread_Create(CLoopThread *p);
|
||||||
|
WRes LoopThread_StopAndWait(CLoopThread *p);
|
||||||
|
WRes LoopThread_StartSubThread(CLoopThread *p);
|
||||||
|
WRes LoopThread_WaitSubThread(CLoopThread *p);
|
||||||
|
|
||||||
|
#ifndef _7ZIP_ST
|
||||||
|
#define NUM_MT_CODER_THREADS_MAX 32
|
||||||
|
#else
|
||||||
|
#define NUM_MT_CODER_THREADS_MAX 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
UInt64 totalInSize;
|
||||||
|
UInt64 totalOutSize;
|
||||||
|
ICompressProgress *progress;
|
||||||
|
SRes res;
|
||||||
|
CCriticalSection cs;
|
||||||
|
UInt64 inSizes[NUM_MT_CODER_THREADS_MAX];
|
||||||
|
UInt64 outSizes[NUM_MT_CODER_THREADS_MAX];
|
||||||
|
} CMtProgress;
|
||||||
|
|
||||||
|
SRes MtProgress_Set(CMtProgress *p, unsigned index, UInt64 inSize, UInt64 outSize);
|
||||||
|
|
||||||
|
struct _CMtCoder;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
struct _CMtCoder *mtCoder;
|
||||||
|
Byte *outBuf;
|
||||||
|
size_t outBufSize;
|
||||||
|
Byte *inBuf;
|
||||||
|
size_t inBufSize;
|
||||||
|
unsigned index;
|
||||||
|
CLoopThread thread;
|
||||||
|
|
||||||
|
Bool stopReading;
|
||||||
|
Bool stopWriting;
|
||||||
|
CAutoResetEvent canRead;
|
||||||
|
CAutoResetEvent canWrite;
|
||||||
|
} CMtThread;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
SRes (*Code)(void *p, unsigned index, Byte *dest, size_t *destSize,
|
||||||
|
const Byte *src, size_t srcSize, int finished);
|
||||||
|
} IMtCoderCallback;
|
||||||
|
|
||||||
|
typedef struct _CMtCoder
|
||||||
|
{
|
||||||
|
size_t blockSize;
|
||||||
|
size_t destBlockSize;
|
||||||
|
unsigned numThreads;
|
||||||
|
|
||||||
|
ISeqInStream *inStream;
|
||||||
|
ISeqOutStream *outStream;
|
||||||
|
ICompressProgress *progress;
|
||||||
|
ISzAlloc *alloc;
|
||||||
|
|
||||||
|
IMtCoderCallback *mtCallback;
|
||||||
|
CCriticalSection cs;
|
||||||
|
SRes res;
|
||||||
|
|
||||||
|
CMtProgress mtProgress;
|
||||||
|
CMtThread threads[NUM_MT_CODER_THREADS_MAX];
|
||||||
|
} CMtCoder;
|
||||||
|
|
||||||
|
void MtCoder_Construct(CMtCoder* p);
|
||||||
|
void MtCoder_Destruct(CMtCoder* p);
|
||||||
|
SRes MtCoder_Code(CMtCoder *p);
|
||||||
|
|
||||||
|
EXTERN_C_END
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
/* Ppmd.h -- PPMD codec common code
|
||||||
|
2010-03-12 : Igor Pavlov : Public domain
|
||||||
|
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
|
||||||
|
|
||||||
|
#ifndef __PPMD_H
|
||||||
|
#define __PPMD_H
|
||||||
|
|
||||||
|
#include "Types.h"
|
||||||
|
#include "CpuArch.h"
|
||||||
|
|
||||||
|
EXTERN_C_BEGIN
|
||||||
|
|
||||||
|
#ifdef MY_CPU_32BIT
|
||||||
|
#define PPMD_32BIT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define PPMD_INT_BITS 7
|
||||||
|
#define PPMD_PERIOD_BITS 7
|
||||||
|
#define PPMD_BIN_SCALE (1 << (PPMD_INT_BITS + PPMD_PERIOD_BITS))
|
||||||
|
|
||||||
|
#define PPMD_GET_MEAN_SPEC(summ, shift, round) (((summ) + (1 << ((shift) - (round)))) >> (shift))
|
||||||
|
#define PPMD_GET_MEAN(summ) PPMD_GET_MEAN_SPEC((summ), PPMD_PERIOD_BITS, 2)
|
||||||
|
#define PPMD_UPDATE_PROB_0(prob) ((prob) + (1 << PPMD_INT_BITS) - PPMD_GET_MEAN(prob))
|
||||||
|
#define PPMD_UPDATE_PROB_1(prob) ((prob) - PPMD_GET_MEAN(prob))
|
||||||
|
|
||||||
|
#define PPMD_N1 4
|
||||||
|
#define PPMD_N2 4
|
||||||
|
#define PPMD_N3 4
|
||||||
|
#define PPMD_N4 ((128 + 3 - 1 * PPMD_N1 - 2 * PPMD_N2 - 3 * PPMD_N3) / 4)
|
||||||
|
#define PPMD_NUM_INDEXES (PPMD_N1 + PPMD_N2 + PPMD_N3 + PPMD_N4)
|
||||||
|
|
||||||
|
/* SEE-contexts for PPM-contexts with masked symbols */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
UInt16 Summ; /* Freq */
|
||||||
|
Byte Shift; /* Speed of Freq change; low Shift is for fast change */
|
||||||
|
Byte Count; /* Count to next change of Shift */
|
||||||
|
} CPpmd_See;
|
||||||
|
|
||||||
|
#define Ppmd_See_Update(p) if ((p)->Shift < PPMD_PERIOD_BITS && --(p)->Count == 0) \
|
||||||
|
{ (p)->Summ <<= 1; (p)->Count = (Byte)(3 << (p)->Shift++); }
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
Byte Symbol;
|
||||||
|
Byte Freq;
|
||||||
|
UInt16 SuccessorLow;
|
||||||
|
UInt16 SuccessorHigh;
|
||||||
|
} CPpmd_State;
|
||||||
|
|
||||||
|
typedef
|
||||||
|
#ifdef PPMD_32BIT
|
||||||
|
CPpmd_State *
|
||||||
|
#else
|
||||||
|
UInt32
|
||||||
|
#endif
|
||||||
|
CPpmd_State_Ref;
|
||||||
|
|
||||||
|
typedef
|
||||||
|
#ifdef PPMD_32BIT
|
||||||
|
void *
|
||||||
|
#else
|
||||||
|
UInt32
|
||||||
|
#endif
|
||||||
|
CPpmd_Void_Ref;
|
||||||
|
|
||||||
|
typedef
|
||||||
|
#ifdef PPMD_32BIT
|
||||||
|
Byte *
|
||||||
|
#else
|
||||||
|
UInt32
|
||||||
|
#endif
|
||||||
|
CPpmd_Byte_Ref;
|
||||||
|
|
||||||
|
#define PPMD_SetAllBitsIn256Bytes(p) \
|
||||||
|
{ unsigned i; for (i = 0; i < 256 / sizeof(p[0]); i += 8) { \
|
||||||
|
p[i+7] = p[i+6] = p[i+5] = p[i+4] = p[i+3] = p[i+2] = p[i+1] = p[i+0] = ~(size_t)0; }}
|
||||||
|
|
||||||
|
EXTERN_C_END
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,708 @@
|
|||||||
|
/* Ppmd7.c -- PPMdH codec
|
||||||
|
2010-03-12 : Igor Pavlov : Public domain
|
||||||
|
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
|
||||||
|
|
||||||
|
#include <memory.h>
|
||||||
|
|
||||||
|
#include "Ppmd7.h"
|
||||||
|
|
||||||
|
const Byte PPMD7_kExpEscape[16] = { 25, 14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 };
|
||||||
|
static const UInt16 kInitBinEsc[] = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051};
|
||||||
|
|
||||||
|
#define MAX_FREQ 124
|
||||||
|
#define UNIT_SIZE 12
|
||||||
|
|
||||||
|
#define U2B(nu) ((UInt32)(nu) * UNIT_SIZE)
|
||||||
|
#define U2I(nu) (p->Units2Indx[(nu) - 1])
|
||||||
|
#define I2U(indx) (p->Indx2Units[indx])
|
||||||
|
|
||||||
|
#ifdef PPMD_32BIT
|
||||||
|
#define REF(ptr) (ptr)
|
||||||
|
#else
|
||||||
|
#define REF(ptr) ((UInt32)((Byte *)(ptr) - (p)->Base))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define STATS_REF(ptr) ((CPpmd_State_Ref)REF(ptr))
|
||||||
|
|
||||||
|
#define CTX(ref) ((CPpmd7_Context *)Ppmd7_GetContext(p, ref))
|
||||||
|
#define STATS(ctx) Ppmd7_GetStats(p, ctx)
|
||||||
|
#define ONE_STATE(ctx) Ppmd7Context_OneState(ctx)
|
||||||
|
#define SUFFIX(ctx) CTX((ctx)->Suffix)
|
||||||
|
|
||||||
|
typedef CPpmd7_Context * CTX_PTR;
|
||||||
|
|
||||||
|
struct CPpmd7_Node_;
|
||||||
|
|
||||||
|
typedef
|
||||||
|
#ifdef PPMD_32BIT
|
||||||
|
struct CPpmd7_Node_ *
|
||||||
|
#else
|
||||||
|
UInt32
|
||||||
|
#endif
|
||||||
|
CPpmd7_Node_Ref;
|
||||||
|
|
||||||
|
typedef struct CPpmd7_Node_
|
||||||
|
{
|
||||||
|
UInt16 Stamp; /* must be at offset 0 as CPpmd7_Context::NumStats. Stamp=0 means free */
|
||||||
|
UInt16 NU;
|
||||||
|
CPpmd7_Node_Ref Next; /* must be at offset >= 4 */
|
||||||
|
CPpmd7_Node_Ref Prev;
|
||||||
|
} CPpmd7_Node;
|
||||||
|
|
||||||
|
#ifdef PPMD_32BIT
|
||||||
|
#define NODE(ptr) (ptr)
|
||||||
|
#else
|
||||||
|
#define NODE(offs) ((CPpmd7_Node *)(p->Base + (offs)))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void Ppmd7_Construct(CPpmd7 *p)
|
||||||
|
{
|
||||||
|
unsigned i, k, m;
|
||||||
|
|
||||||
|
p->Base = 0;
|
||||||
|
|
||||||
|
for (i = 0, k = 0; i < PPMD_NUM_INDEXES; i++)
|
||||||
|
{
|
||||||
|
unsigned step = (i >= 12 ? 4 : (i >> 2) + 1);
|
||||||
|
do { p->Units2Indx[k++] = (Byte)i; } while(--step);
|
||||||
|
p->Indx2Units[i] = (Byte)k;
|
||||||
|
}
|
||||||
|
|
||||||
|
p->NS2BSIndx[0] = (0 << 1);
|
||||||
|
p->NS2BSIndx[1] = (1 << 1);
|
||||||
|
memset(p->NS2BSIndx + 2, (2 << 1), 9);
|
||||||
|
memset(p->NS2BSIndx + 11, (3 << 1), 256 - 11);
|
||||||
|
|
||||||
|
for (i = 0; i < 3; i++)
|
||||||
|
p->NS2Indx[i] = (Byte)i;
|
||||||
|
for (m = i, k = 1; i < 256; i++)
|
||||||
|
{
|
||||||
|
p->NS2Indx[i] = (Byte)m;
|
||||||
|
if (--k == 0)
|
||||||
|
k = (++m) - 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(p->HB2Flag, 0, 0x40);
|
||||||
|
memset(p->HB2Flag + 0x40, 8, 0x100 - 0x40);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Ppmd7_Free(CPpmd7 *p, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
alloc->Free(alloc, p->Base);
|
||||||
|
p->Size = 0;
|
||||||
|
p->Base = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
if (p->Base == 0 || p->Size != size)
|
||||||
|
{
|
||||||
|
Ppmd7_Free(p, alloc);
|
||||||
|
p->AlignOffset =
|
||||||
|
#ifdef PPMD_32BIT
|
||||||
|
(4 - size) & 3;
|
||||||
|
#else
|
||||||
|
4 - (size & 3);
|
||||||
|
#endif
|
||||||
|
if ((p->Base = (Byte *)alloc->Alloc(alloc, p->AlignOffset + size
|
||||||
|
#ifndef PPMD_32BIT
|
||||||
|
+ UNIT_SIZE
|
||||||
|
#endif
|
||||||
|
)) == 0)
|
||||||
|
return False;
|
||||||
|
p->Size = size;
|
||||||
|
}
|
||||||
|
return True;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void InsertNode(CPpmd7 *p, void *node, unsigned indx)
|
||||||
|
{
|
||||||
|
*((CPpmd_Void_Ref *)node) = p->FreeList[indx];
|
||||||
|
p->FreeList[indx] = REF(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *RemoveNode(CPpmd7 *p, unsigned indx)
|
||||||
|
{
|
||||||
|
CPpmd_Void_Ref *node = (CPpmd_Void_Ref *)Ppmd7_GetPtr(p, p->FreeList[indx]);
|
||||||
|
p->FreeList[indx] = *node;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SplitBlock(CPpmd7 *p, void *ptr, unsigned oldIndx, unsigned newIndx)
|
||||||
|
{
|
||||||
|
unsigned i, nu = I2U(oldIndx) - I2U(newIndx);
|
||||||
|
ptr = (Byte *)ptr + U2B(I2U(newIndx));
|
||||||
|
if (I2U(i = U2I(nu)) != nu)
|
||||||
|
{
|
||||||
|
unsigned k = I2U(--i);
|
||||||
|
InsertNode(p, ((Byte *)ptr) + U2B(k), nu - k - 1);
|
||||||
|
}
|
||||||
|
InsertNode(p, ptr, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GlueFreeBlocks(CPpmd7 *p)
|
||||||
|
{
|
||||||
|
#ifdef PPMD_32BIT
|
||||||
|
CPpmd7_Node headItem;
|
||||||
|
CPpmd7_Node_Ref head = &headItem;
|
||||||
|
#else
|
||||||
|
CPpmd7_Node_Ref head = p->AlignOffset + p->Size;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CPpmd7_Node_Ref n = head;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
p->GlueCount = 255;
|
||||||
|
|
||||||
|
/* create doubly-linked list of free blocks */
|
||||||
|
for (i = 0; i < PPMD_NUM_INDEXES; i++)
|
||||||
|
{
|
||||||
|
UInt16 nu = I2U(i);
|
||||||
|
CPpmd7_Node_Ref next = (CPpmd7_Node_Ref)p->FreeList[i];
|
||||||
|
p->FreeList[i] = 0;
|
||||||
|
while (next != 0)
|
||||||
|
{
|
||||||
|
CPpmd7_Node *node = NODE(next);
|
||||||
|
node->Next = n;
|
||||||
|
n = NODE(n)->Prev = next;
|
||||||
|
next = *(const CPpmd7_Node_Ref *)node;
|
||||||
|
node->Stamp = 0;
|
||||||
|
node->NU = (UInt16)nu;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NODE(head)->Stamp = 1;
|
||||||
|
NODE(head)->Next = n;
|
||||||
|
NODE(n)->Prev = head;
|
||||||
|
if (p->LoUnit != p->HiUnit)
|
||||||
|
((CPpmd7_Node *)p->LoUnit)->Stamp = 1;
|
||||||
|
|
||||||
|
/* Glue free blocks */
|
||||||
|
while (n != head)
|
||||||
|
{
|
||||||
|
CPpmd7_Node *node = NODE(n);
|
||||||
|
UInt32 nu = (UInt32)node->NU;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
CPpmd7_Node *node2 = NODE(n) + nu;
|
||||||
|
nu += node2->NU;
|
||||||
|
if (node2->Stamp != 0 || nu >= 0x10000)
|
||||||
|
break;
|
||||||
|
NODE(node2->Prev)->Next = node2->Next;
|
||||||
|
NODE(node2->Next)->Prev = node2->Prev;
|
||||||
|
node->NU = (UInt16)nu;
|
||||||
|
}
|
||||||
|
n = node->Next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fill lists of free blocks */
|
||||||
|
for (n = NODE(head)->Next; n != head;)
|
||||||
|
{
|
||||||
|
CPpmd7_Node *node = NODE(n);
|
||||||
|
unsigned nu;
|
||||||
|
CPpmd7_Node_Ref next = node->Next;
|
||||||
|
for (nu = node->NU; nu > 128; nu -= 128, node += 128)
|
||||||
|
InsertNode(p, node, PPMD_NUM_INDEXES - 1);
|
||||||
|
if (I2U(i = U2I(nu)) != nu)
|
||||||
|
{
|
||||||
|
unsigned k = I2U(--i);
|
||||||
|
InsertNode(p, node + k, nu - k - 1);
|
||||||
|
}
|
||||||
|
InsertNode(p, node, i);
|
||||||
|
n = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *AllocUnitsRare(CPpmd7 *p, unsigned indx)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
void *retVal;
|
||||||
|
if (p->GlueCount == 0)
|
||||||
|
{
|
||||||
|
GlueFreeBlocks(p);
|
||||||
|
if (p->FreeList[indx] != 0)
|
||||||
|
return RemoveNode(p, indx);
|
||||||
|
}
|
||||||
|
i = indx;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (++i == PPMD_NUM_INDEXES)
|
||||||
|
{
|
||||||
|
UInt32 numBytes = U2B(I2U(indx));
|
||||||
|
p->GlueCount--;
|
||||||
|
return ((UInt32)(p->UnitsStart - p->Text) > numBytes) ? (p->UnitsStart -= numBytes) : (NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (p->FreeList[i] == 0);
|
||||||
|
retVal = RemoveNode(p, i);
|
||||||
|
SplitBlock(p, retVal, i, indx);
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *AllocUnits(CPpmd7 *p, unsigned indx)
|
||||||
|
{
|
||||||
|
UInt32 numBytes;
|
||||||
|
if (p->FreeList[indx] != 0)
|
||||||
|
return RemoveNode(p, indx);
|
||||||
|
numBytes = U2B(I2U(indx));
|
||||||
|
if (numBytes <= (UInt32)(p->HiUnit - p->LoUnit))
|
||||||
|
{
|
||||||
|
void *retVal = p->LoUnit;
|
||||||
|
p->LoUnit += numBytes;
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
return AllocUnitsRare(p, indx);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MyMem12Cpy(dest, src, num) \
|
||||||
|
{ UInt32 *d = (UInt32 *)dest; const UInt32 *s = (const UInt32 *)src; UInt32 n = num; \
|
||||||
|
do { d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; s += 3; d += 3; } while(--n); }
|
||||||
|
|
||||||
|
static void *ShrinkUnits(CPpmd7 *p, void *oldPtr, unsigned oldNU, unsigned newNU)
|
||||||
|
{
|
||||||
|
unsigned i0 = U2I(oldNU);
|
||||||
|
unsigned i1 = U2I(newNU);
|
||||||
|
if (i0 == i1)
|
||||||
|
return oldPtr;
|
||||||
|
if (p->FreeList[i1] != 0)
|
||||||
|
{
|
||||||
|
void *ptr = RemoveNode(p, i1);
|
||||||
|
MyMem12Cpy(ptr, oldPtr, newNU);
|
||||||
|
InsertNode(p, oldPtr, i0);
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
SplitBlock(p, oldPtr, i0, i1);
|
||||||
|
return oldPtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SUCCESSOR(p) ((CPpmd_Void_Ref)((p)->SuccessorLow | ((UInt32)(p)->SuccessorHigh << 16)))
|
||||||
|
|
||||||
|
static void SetSuccessor(CPpmd_State *p, CPpmd_Void_Ref v)
|
||||||
|
{
|
||||||
|
(p)->SuccessorLow = (UInt16)((UInt32)(v) & 0xFFFF);
|
||||||
|
(p)->SuccessorHigh = (UInt16)(((UInt32)(v) >> 16) & 0xFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void RestartModel(CPpmd7 *p)
|
||||||
|
{
|
||||||
|
unsigned i, k, m;
|
||||||
|
|
||||||
|
memset(p->FreeList, 0, sizeof(p->FreeList));
|
||||||
|
p->Text = p->Base + p->AlignOffset;
|
||||||
|
p->HiUnit = p->Text + p->Size;
|
||||||
|
p->LoUnit = p->UnitsStart = p->HiUnit - p->Size / 8 / UNIT_SIZE * 7 * UNIT_SIZE;
|
||||||
|
p->GlueCount = 0;
|
||||||
|
|
||||||
|
p->OrderFall = p->MaxOrder;
|
||||||
|
p->RunLength = p->InitRL = -(Int32)((p->MaxOrder < 12) ? p->MaxOrder : 12) - 1;
|
||||||
|
p->PrevSuccess = 0;
|
||||||
|
|
||||||
|
p->MinContext = p->MaxContext = (CTX_PTR)(p->HiUnit -= UNIT_SIZE); /* AllocContext(p); */
|
||||||
|
p->MinContext->Suffix = 0;
|
||||||
|
p->MinContext->NumStats = 256;
|
||||||
|
p->MinContext->SummFreq = 256 + 1;
|
||||||
|
p->FoundState = (CPpmd_State *)p->LoUnit; /* AllocUnits(p, PPMD_NUM_INDEXES - 1); */
|
||||||
|
p->LoUnit += U2B(256 / 2);
|
||||||
|
p->MinContext->Stats = REF(p->FoundState);
|
||||||
|
for (i = 0; i < 256; i++)
|
||||||
|
{
|
||||||
|
CPpmd_State *s = &p->FoundState[i];
|
||||||
|
s->Symbol = (Byte)i;
|
||||||
|
s->Freq = 1;
|
||||||
|
SetSuccessor(s, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 128; i++)
|
||||||
|
for (k = 0; k < 8; k++)
|
||||||
|
{
|
||||||
|
UInt16 *dest = p->BinSumm[i] + k;
|
||||||
|
UInt16 val = (UInt16)(PPMD_BIN_SCALE - kInitBinEsc[k] / (i + 2));
|
||||||
|
for (m = 0; m < 64; m += 8)
|
||||||
|
dest[m] = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 25; i++)
|
||||||
|
for (k = 0; k < 16; k++)
|
||||||
|
{
|
||||||
|
CPpmd_See *s = &p->See[i][k];
|
||||||
|
s->Summ = (UInt16)((5 * i + 10) << (s->Shift = PPMD_PERIOD_BITS - 4));
|
||||||
|
s->Count = 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder)
|
||||||
|
{
|
||||||
|
p->MaxOrder = maxOrder;
|
||||||
|
RestartModel(p);
|
||||||
|
p->DummySee.Shift = PPMD_PERIOD_BITS;
|
||||||
|
p->DummySee.Summ = 0; /* unused */
|
||||||
|
p->DummySee.Count = 64; /* unused */
|
||||||
|
}
|
||||||
|
|
||||||
|
static CTX_PTR CreateSuccessors(CPpmd7 *p, Bool skip)
|
||||||
|
{
|
||||||
|
CPpmd_State upState;
|
||||||
|
CTX_PTR c = p->MinContext;
|
||||||
|
CPpmd_Byte_Ref upBranch = (CPpmd_Byte_Ref)SUCCESSOR(p->FoundState);
|
||||||
|
CPpmd_State *ps[PPMD7_MAX_ORDER];
|
||||||
|
unsigned numPs = 0;
|
||||||
|
|
||||||
|
if (!skip)
|
||||||
|
ps[numPs++] = p->FoundState;
|
||||||
|
|
||||||
|
while (c->Suffix)
|
||||||
|
{
|
||||||
|
CPpmd_Void_Ref successor;
|
||||||
|
CPpmd_State *s;
|
||||||
|
c = SUFFIX(c);
|
||||||
|
if (c->NumStats != 1)
|
||||||
|
{
|
||||||
|
for (s = STATS(c); s->Symbol != p->FoundState->Symbol; s++);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
s = ONE_STATE(c);
|
||||||
|
successor = SUCCESSOR(s);
|
||||||
|
if (successor != upBranch)
|
||||||
|
{
|
||||||
|
c = CTX(successor);
|
||||||
|
if (numPs == 0)
|
||||||
|
return c;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ps[numPs++] = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
upState.Symbol = *(const Byte *)Ppmd7_GetPtr(p, upBranch);
|
||||||
|
SetSuccessor(&upState, upBranch + 1);
|
||||||
|
|
||||||
|
if (c->NumStats == 1)
|
||||||
|
upState.Freq = ONE_STATE(c)->Freq;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UInt32 cf, s0;
|
||||||
|
CPpmd_State *s;
|
||||||
|
for (s = STATS(c); s->Symbol != upState.Symbol; s++);
|
||||||
|
cf = s->Freq - 1;
|
||||||
|
s0 = c->SummFreq - c->NumStats - cf;
|
||||||
|
upState.Freq = (Byte)(1 + ((2 * cf <= s0) ? (5 * cf > s0) : ((2 * cf + 3 * s0 - 1) / (2 * s0))));
|
||||||
|
}
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
/* Create Child */
|
||||||
|
CTX_PTR c1; /* = AllocContext(p); */
|
||||||
|
if (p->HiUnit != p->LoUnit)
|
||||||
|
c1 = (CTX_PTR)(p->HiUnit -= UNIT_SIZE);
|
||||||
|
else if (p->FreeList[0] != 0)
|
||||||
|
c1 = (CTX_PTR)RemoveNode(p, 0);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
c1 = (CTX_PTR)AllocUnitsRare(p, 0);
|
||||||
|
if (!c1)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
c1->NumStats = 1;
|
||||||
|
*ONE_STATE(c1) = upState;
|
||||||
|
c1->Suffix = REF(c);
|
||||||
|
SetSuccessor(ps[--numPs], REF(c1));
|
||||||
|
c = c1;
|
||||||
|
}
|
||||||
|
while (numPs != 0);
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SwapStates(CPpmd_State *t1, CPpmd_State *t2)
|
||||||
|
{
|
||||||
|
CPpmd_State tmp = *t1;
|
||||||
|
*t1 = *t2;
|
||||||
|
*t2 = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void UpdateModel(CPpmd7 *p)
|
||||||
|
{
|
||||||
|
CPpmd_Void_Ref successor, fSuccessor = SUCCESSOR(p->FoundState);
|
||||||
|
CTX_PTR c;
|
||||||
|
unsigned s0, ns;
|
||||||
|
|
||||||
|
if (p->FoundState->Freq < MAX_FREQ / 4 && p->MinContext->Suffix != 0)
|
||||||
|
{
|
||||||
|
c = SUFFIX(p->MinContext);
|
||||||
|
|
||||||
|
if (c->NumStats == 1)
|
||||||
|
{
|
||||||
|
CPpmd_State *s = ONE_STATE(c);
|
||||||
|
if (s->Freq < 32)
|
||||||
|
s->Freq++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CPpmd_State *s = STATS(c);
|
||||||
|
if (s->Symbol != p->FoundState->Symbol)
|
||||||
|
{
|
||||||
|
do { s++; } while (s->Symbol != p->FoundState->Symbol);
|
||||||
|
if (s[0].Freq >= s[-1].Freq)
|
||||||
|
{
|
||||||
|
SwapStates(&s[0], &s[-1]);
|
||||||
|
s--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (s->Freq < MAX_FREQ - 9)
|
||||||
|
{
|
||||||
|
s->Freq += 2;
|
||||||
|
c->SummFreq += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p->OrderFall == 0)
|
||||||
|
{
|
||||||
|
p->MinContext = p->MaxContext = CreateSuccessors(p, True);
|
||||||
|
if (p->MinContext == 0)
|
||||||
|
{
|
||||||
|
RestartModel(p);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SetSuccessor(p->FoundState, REF(p->MinContext));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
*p->Text++ = p->FoundState->Symbol;
|
||||||
|
successor = REF(p->Text);
|
||||||
|
if (p->Text >= p->UnitsStart)
|
||||||
|
{
|
||||||
|
RestartModel(p);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fSuccessor)
|
||||||
|
{
|
||||||
|
if (fSuccessor <= successor)
|
||||||
|
{
|
||||||
|
CTX_PTR cs = CreateSuccessors(p, False);
|
||||||
|
if (cs == NULL)
|
||||||
|
{
|
||||||
|
RestartModel(p);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fSuccessor = REF(cs);
|
||||||
|
}
|
||||||
|
if (--p->OrderFall == 0)
|
||||||
|
{
|
||||||
|
successor = fSuccessor;
|
||||||
|
p->Text -= (p->MaxContext != p->MinContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetSuccessor(p->FoundState, successor);
|
||||||
|
fSuccessor = REF(p->MinContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
s0 = p->MinContext->SummFreq - (ns = p->MinContext->NumStats) - (p->FoundState->Freq - 1);
|
||||||
|
|
||||||
|
for (c = p->MaxContext; c != p->MinContext; c = SUFFIX(c))
|
||||||
|
{
|
||||||
|
unsigned ns1;
|
||||||
|
UInt32 cf, sf;
|
||||||
|
if ((ns1 = c->NumStats) != 1)
|
||||||
|
{
|
||||||
|
if ((ns1 & 1) == 0)
|
||||||
|
{
|
||||||
|
/* Expand for one UNIT */
|
||||||
|
unsigned oldNU = ns1 >> 1;
|
||||||
|
unsigned i = U2I(oldNU);
|
||||||
|
if (i != U2I(oldNU + 1))
|
||||||
|
{
|
||||||
|
void *ptr = AllocUnits(p, i + 1);
|
||||||
|
void *oldPtr;
|
||||||
|
if (!ptr)
|
||||||
|
{
|
||||||
|
RestartModel(p);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
oldPtr = STATS(c);
|
||||||
|
MyMem12Cpy(ptr, oldPtr, oldNU);
|
||||||
|
InsertNode(p, oldPtr, i);
|
||||||
|
c->Stats = STATS_REF(ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c->SummFreq = (UInt16)(c->SummFreq + (2 * ns1 < ns) + 2 * ((4 * ns1 <= ns) & (c->SummFreq <= 8 * ns1)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CPpmd_State *s = (CPpmd_State*)AllocUnits(p, 0);
|
||||||
|
if (!s)
|
||||||
|
{
|
||||||
|
RestartModel(p);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*s = *ONE_STATE(c);
|
||||||
|
c->Stats = REF(s);
|
||||||
|
if (s->Freq < MAX_FREQ / 4 - 1)
|
||||||
|
s->Freq <<= 1;
|
||||||
|
else
|
||||||
|
s->Freq = MAX_FREQ - 4;
|
||||||
|
c->SummFreq = (UInt16)(s->Freq + p->InitEsc + (ns > 3));
|
||||||
|
}
|
||||||
|
cf = 2 * (UInt32)p->FoundState->Freq * (c->SummFreq + 6);
|
||||||
|
sf = (UInt32)s0 + c->SummFreq;
|
||||||
|
if (cf < 6 * sf)
|
||||||
|
{
|
||||||
|
cf = 1 + (cf > sf) + (cf >= 4 * sf);
|
||||||
|
c->SummFreq += 3;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cf = 4 + (cf >= 9 * sf) + (cf >= 12 * sf) + (cf >= 15 * sf);
|
||||||
|
c->SummFreq = (UInt16)(c->SummFreq + cf);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
CPpmd_State *s = STATS(c) + ns1;
|
||||||
|
SetSuccessor(s, successor);
|
||||||
|
s->Symbol = p->FoundState->Symbol;
|
||||||
|
s->Freq = (Byte)cf;
|
||||||
|
c->NumStats = (UInt16)(ns1 + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p->MaxContext = p->MinContext = CTX(fSuccessor);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Rescale(CPpmd7 *p)
|
||||||
|
{
|
||||||
|
unsigned i, adder, sumFreq, escFreq;
|
||||||
|
CPpmd_State *stats = STATS(p->MinContext);
|
||||||
|
CPpmd_State *s = p->FoundState;
|
||||||
|
{
|
||||||
|
CPpmd_State tmp = *s;
|
||||||
|
for (; s != stats; s--)
|
||||||
|
s[0] = s[-1];
|
||||||
|
*s = tmp;
|
||||||
|
}
|
||||||
|
escFreq = p->MinContext->SummFreq - s->Freq;
|
||||||
|
s->Freq += 4;
|
||||||
|
adder = (p->OrderFall != 0);
|
||||||
|
s->Freq = (Byte)((s->Freq + adder) >> 1);
|
||||||
|
sumFreq = s->Freq;
|
||||||
|
|
||||||
|
i = p->MinContext->NumStats - 1;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
escFreq -= (++s)->Freq;
|
||||||
|
s->Freq = (Byte)((s->Freq + adder) >> 1);
|
||||||
|
sumFreq += s->Freq;
|
||||||
|
if (s[0].Freq > s[-1].Freq)
|
||||||
|
{
|
||||||
|
CPpmd_State *s1 = s;
|
||||||
|
CPpmd_State tmp = *s1;
|
||||||
|
do
|
||||||
|
s1[0] = s1[-1];
|
||||||
|
while (--s1 != stats && tmp.Freq > s1[-1].Freq);
|
||||||
|
*s1 = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (--i);
|
||||||
|
|
||||||
|
if (s->Freq == 0)
|
||||||
|
{
|
||||||
|
unsigned numStats = p->MinContext->NumStats;
|
||||||
|
unsigned n0, n1;
|
||||||
|
do { i++; } while ((--s)->Freq == 0);
|
||||||
|
escFreq += i;
|
||||||
|
p->MinContext->NumStats = (UInt16)(p->MinContext->NumStats - i);
|
||||||
|
if (p->MinContext->NumStats == 1)
|
||||||
|
{
|
||||||
|
CPpmd_State tmp = *stats;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
tmp.Freq = (Byte)(tmp.Freq - (tmp.Freq >> 1));
|
||||||
|
escFreq >>= 1;
|
||||||
|
}
|
||||||
|
while (escFreq > 1);
|
||||||
|
InsertNode(p, stats, U2I(((numStats + 1) >> 1)));
|
||||||
|
*(p->FoundState = ONE_STATE(p->MinContext)) = tmp;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
n0 = (numStats + 1) >> 1;
|
||||||
|
n1 = (p->MinContext->NumStats + 1) >> 1;
|
||||||
|
if (n0 != n1)
|
||||||
|
p->MinContext->Stats = STATS_REF(ShrinkUnits(p, stats, n0, n1));
|
||||||
|
}
|
||||||
|
p->MinContext->SummFreq = (UInt16)(sumFreq + escFreq - (escFreq >> 1));
|
||||||
|
p->FoundState = STATS(p->MinContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *escFreq)
|
||||||
|
{
|
||||||
|
CPpmd_See *see;
|
||||||
|
unsigned nonMasked = p->MinContext->NumStats - numMasked;
|
||||||
|
if (p->MinContext->NumStats != 256)
|
||||||
|
{
|
||||||
|
see = p->See[p->NS2Indx[nonMasked - 1]] +
|
||||||
|
(nonMasked < (unsigned)SUFFIX(p->MinContext)->NumStats - p->MinContext->NumStats) +
|
||||||
|
2 * (p->MinContext->SummFreq < 11 * p->MinContext->NumStats) +
|
||||||
|
4 * (numMasked > nonMasked) +
|
||||||
|
p->HiBitsFlag;
|
||||||
|
{
|
||||||
|
unsigned r = (see->Summ >> see->Shift);
|
||||||
|
see->Summ = (UInt16)(see->Summ - r);
|
||||||
|
*escFreq = r + (r == 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
see = &p->DummySee;
|
||||||
|
*escFreq = 1;
|
||||||
|
}
|
||||||
|
return see;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void NextContext(CPpmd7 *p)
|
||||||
|
{
|
||||||
|
CTX_PTR c = CTX(SUCCESSOR(p->FoundState));
|
||||||
|
if (p->OrderFall == 0 && (Byte *)c > p->Text)
|
||||||
|
p->MinContext = p->MaxContext = c;
|
||||||
|
else
|
||||||
|
UpdateModel(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Ppmd7_Update1(CPpmd7 *p)
|
||||||
|
{
|
||||||
|
CPpmd_State *s = p->FoundState;
|
||||||
|
s->Freq += 4;
|
||||||
|
p->MinContext->SummFreq += 4;
|
||||||
|
if (s[0].Freq > s[-1].Freq)
|
||||||
|
{
|
||||||
|
SwapStates(&s[0], &s[-1]);
|
||||||
|
p->FoundState = --s;
|
||||||
|
if (s->Freq > MAX_FREQ)
|
||||||
|
Rescale(p);
|
||||||
|
}
|
||||||
|
NextContext(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Ppmd7_Update1_0(CPpmd7 *p)
|
||||||
|
{
|
||||||
|
p->PrevSuccess = (2 * p->FoundState->Freq > p->MinContext->SummFreq);
|
||||||
|
p->RunLength += p->PrevSuccess;
|
||||||
|
p->MinContext->SummFreq += 4;
|
||||||
|
if ((p->FoundState->Freq += 4) > MAX_FREQ)
|
||||||
|
Rescale(p);
|
||||||
|
NextContext(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Ppmd7_UpdateBin(CPpmd7 *p)
|
||||||
|
{
|
||||||
|
p->FoundState->Freq = (Byte)(p->FoundState->Freq + (p->FoundState->Freq < 128 ? 1: 0));
|
||||||
|
p->PrevSuccess = 1;
|
||||||
|
p->RunLength++;
|
||||||
|
NextContext(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Ppmd7_Update2(CPpmd7 *p)
|
||||||
|
{
|
||||||
|
p->MinContext->SummFreq += 4;
|
||||||
|
if ((p->FoundState->Freq += 4) > MAX_FREQ)
|
||||||
|
Rescale(p);
|
||||||
|
p->RunLength = p->InitRL;
|
||||||
|
UpdateModel(p);
|
||||||
|
}
|
||||||
@@ -0,0 +1,140 @@
|
|||||||
|
/* Ppmd7.h -- PPMdH compression codec
|
||||||
|
2010-03-12 : Igor Pavlov : Public domain
|
||||||
|
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
|
||||||
|
|
||||||
|
/* This code supports virtual RangeDecoder and includes the implementation
|
||||||
|
of RangeCoder from 7z, instead of RangeCoder from original PPMd var.H.
|
||||||
|
If you need the compatibility with original PPMd var.H, you can use external RangeDecoder */
|
||||||
|
|
||||||
|
#ifndef __PPMD7_H
|
||||||
|
#define __PPMD7_H
|
||||||
|
|
||||||
|
#include "Ppmd.h"
|
||||||
|
|
||||||
|
EXTERN_C_BEGIN
|
||||||
|
|
||||||
|
#define PPMD7_MIN_ORDER 2
|
||||||
|
#define PPMD7_MAX_ORDER 64
|
||||||
|
|
||||||
|
#define PPMD7_MIN_MEM_SIZE (1 << 11)
|
||||||
|
#define PPMD7_MAX_MEM_SIZE (0xFFFFFFFF - 12 * 3)
|
||||||
|
|
||||||
|
struct CPpmd7_Context_;
|
||||||
|
|
||||||
|
typedef
|
||||||
|
#ifdef PPMD_32BIT
|
||||||
|
struct CPpmd7_Context_ *
|
||||||
|
#else
|
||||||
|
UInt32
|
||||||
|
#endif
|
||||||
|
CPpmd7_Context_Ref;
|
||||||
|
|
||||||
|
typedef struct CPpmd7_Context_
|
||||||
|
{
|
||||||
|
UInt16 NumStats;
|
||||||
|
UInt16 SummFreq;
|
||||||
|
CPpmd_State_Ref Stats;
|
||||||
|
CPpmd7_Context_Ref Suffix;
|
||||||
|
} CPpmd7_Context;
|
||||||
|
|
||||||
|
#define Ppmd7Context_OneState(p) ((CPpmd_State *)&(p)->SummFreq)
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
CPpmd7_Context *MinContext, *MaxContext;
|
||||||
|
CPpmd_State *FoundState;
|
||||||
|
unsigned OrderFall, InitEsc, PrevSuccess, MaxOrder, HiBitsFlag;
|
||||||
|
Int32 RunLength, InitRL; /* must be 32-bit at least */
|
||||||
|
|
||||||
|
UInt32 Size;
|
||||||
|
UInt32 GlueCount;
|
||||||
|
Byte *Base, *LoUnit, *HiUnit, *Text, *UnitsStart;
|
||||||
|
UInt32 AlignOffset;
|
||||||
|
|
||||||
|
Byte Indx2Units[PPMD_NUM_INDEXES];
|
||||||
|
Byte Units2Indx[128];
|
||||||
|
CPpmd_Void_Ref FreeList[PPMD_NUM_INDEXES];
|
||||||
|
Byte NS2Indx[256], NS2BSIndx[256], HB2Flag[256];
|
||||||
|
CPpmd_See DummySee, See[25][16];
|
||||||
|
UInt16 BinSumm[128][64];
|
||||||
|
} CPpmd7;
|
||||||
|
|
||||||
|
void Ppmd7_Construct(CPpmd7 *p);
|
||||||
|
Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc);
|
||||||
|
void Ppmd7_Free(CPpmd7 *p, ISzAlloc *alloc);
|
||||||
|
void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder);
|
||||||
|
#define Ppmd7_WasAllocated(p) ((p)->Base != NULL)
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- Internal Functions ---------- */
|
||||||
|
|
||||||
|
extern const Byte PPMD7_kExpEscape[16];
|
||||||
|
|
||||||
|
#ifdef PPMD_32BIT
|
||||||
|
#define Ppmd7_GetPtr(p, ptr) (ptr)
|
||||||
|
#define Ppmd7_GetContext(p, ptr) (ptr)
|
||||||
|
#define Ppmd7_GetStats(p, ctx) ((ctx)->Stats)
|
||||||
|
#else
|
||||||
|
#define Ppmd7_GetPtr(p, offs) ((void *)((p)->Base + (offs)))
|
||||||
|
#define Ppmd7_GetContext(p, offs) ((CPpmd7_Context *)Ppmd7_GetPtr((p), (offs)))
|
||||||
|
#define Ppmd7_GetStats(p, ctx) ((CPpmd_State *)Ppmd7_GetPtr((p), ((ctx)->Stats)))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void Ppmd7_Update1(CPpmd7 *p);
|
||||||
|
void Ppmd7_Update1_0(CPpmd7 *p);
|
||||||
|
void Ppmd7_Update2(CPpmd7 *p);
|
||||||
|
void Ppmd7_UpdateBin(CPpmd7 *p);
|
||||||
|
|
||||||
|
#define Ppmd7_GetBinSumm(p) \
|
||||||
|
&p->BinSumm[Ppmd7Context_OneState(p->MinContext)->Freq - 1][p->PrevSuccess + \
|
||||||
|
p->NS2BSIndx[Ppmd7_GetContext(p, p->MinContext->Suffix)->NumStats - 1] + \
|
||||||
|
(p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]) + \
|
||||||
|
2 * p->HB2Flag[Ppmd7Context_OneState(p->MinContext)->Symbol] + \
|
||||||
|
((p->RunLength >> 26) & 0x20)]
|
||||||
|
|
||||||
|
CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *scale);
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- Decode ---------- */
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
UInt32 (*GetThreshold)(void *p, UInt32 total);
|
||||||
|
void (*Decode)(void *p, UInt32 start, UInt32 size);
|
||||||
|
UInt32 (*DecodeBit)(void *p, UInt32 size0);
|
||||||
|
} IPpmd7_RangeDec;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
IPpmd7_RangeDec p;
|
||||||
|
UInt32 Range;
|
||||||
|
UInt32 Code;
|
||||||
|
IByteIn *Stream;
|
||||||
|
} CPpmd7z_RangeDec;
|
||||||
|
|
||||||
|
void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p);
|
||||||
|
Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p);
|
||||||
|
#define Ppmd7z_RangeDec_IsFinishedOK(p) ((p)->Code == 0)
|
||||||
|
|
||||||
|
int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc);
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- Encode ---------- */
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
UInt64 Low;
|
||||||
|
UInt32 Range;
|
||||||
|
Byte Cache;
|
||||||
|
UInt64 CacheSize;
|
||||||
|
IByteOut *Stream;
|
||||||
|
} CPpmd7z_RangeEnc;
|
||||||
|
|
||||||
|
void Ppmd7z_RangeEnc_Init(CPpmd7z_RangeEnc *p);
|
||||||
|
void Ppmd7z_RangeEnc_FlushData(CPpmd7z_RangeEnc *p);
|
||||||
|
|
||||||
|
void Ppmd7_EncodeSymbol(CPpmd7 *p, CPpmd7z_RangeEnc *rc, int symbol);
|
||||||
|
|
||||||
|
EXTERN_C_END
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,187 @@
|
|||||||
|
/* Ppmd7Dec.c -- PPMdH Decoder
|
||||||
|
2010-03-12 : Igor Pavlov : Public domain
|
||||||
|
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
|
||||||
|
|
||||||
|
#include "Ppmd7.h"
|
||||||
|
|
||||||
|
#define kTopValue (1 << 24)
|
||||||
|
|
||||||
|
Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
p->Code = 0;
|
||||||
|
p->Range = 0xFFFFFFFF;
|
||||||
|
if (p->Stream->Read((void *)p->Stream) != 0)
|
||||||
|
return False;
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);
|
||||||
|
return (p->Code < 0xFFFFFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
static UInt32 Range_GetThreshold(void *pp, UInt32 total)
|
||||||
|
{
|
||||||
|
CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
|
||||||
|
return (p->Code) / (p->Range /= total);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Range_Normalize(CPpmd7z_RangeDec *p)
|
||||||
|
{
|
||||||
|
if (p->Range < kTopValue)
|
||||||
|
{
|
||||||
|
p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);
|
||||||
|
p->Range <<= 8;
|
||||||
|
if (p->Range < kTopValue)
|
||||||
|
{
|
||||||
|
p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);
|
||||||
|
p->Range <<= 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Range_Decode(void *pp, UInt32 start, UInt32 size)
|
||||||
|
{
|
||||||
|
CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
|
||||||
|
p->Code -= start * p->Range;
|
||||||
|
p->Range *= size;
|
||||||
|
Range_Normalize(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static UInt32 Range_DecodeBit(void *pp, UInt32 size0)
|
||||||
|
{
|
||||||
|
CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
|
||||||
|
UInt32 newBound = (p->Range >> 14) * size0;
|
||||||
|
UInt32 symbol;
|
||||||
|
if (p->Code < newBound)
|
||||||
|
{
|
||||||
|
symbol = 0;
|
||||||
|
p->Range = newBound;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
symbol = 1;
|
||||||
|
p->Code -= newBound;
|
||||||
|
p->Range -= newBound;
|
||||||
|
}
|
||||||
|
Range_Normalize(p);
|
||||||
|
return symbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p)
|
||||||
|
{
|
||||||
|
p->p.GetThreshold = Range_GetThreshold;
|
||||||
|
p->p.Decode = Range_Decode;
|
||||||
|
p->p.DecodeBit = Range_DecodeBit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define MASK(sym) ((signed char *)charMask)[sym]
|
||||||
|
|
||||||
|
int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc)
|
||||||
|
{
|
||||||
|
size_t charMask[256 / sizeof(size_t)];
|
||||||
|
if (p->MinContext->NumStats != 1)
|
||||||
|
{
|
||||||
|
CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext);
|
||||||
|
unsigned i;
|
||||||
|
UInt32 count, hiCnt;
|
||||||
|
if ((count = rc->GetThreshold(rc, p->MinContext->SummFreq)) < (hiCnt = s->Freq))
|
||||||
|
{
|
||||||
|
Byte symbol;
|
||||||
|
rc->Decode(rc, 0, s->Freq);
|
||||||
|
p->FoundState = s;
|
||||||
|
symbol = s->Symbol;
|
||||||
|
Ppmd7_Update1_0(p);
|
||||||
|
return symbol;
|
||||||
|
}
|
||||||
|
p->PrevSuccess = 0;
|
||||||
|
i = p->MinContext->NumStats - 1;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if ((hiCnt += (++s)->Freq) > count)
|
||||||
|
{
|
||||||
|
Byte symbol;
|
||||||
|
rc->Decode(rc, hiCnt - s->Freq, s->Freq);
|
||||||
|
p->FoundState = s;
|
||||||
|
symbol = s->Symbol;
|
||||||
|
Ppmd7_Update1(p);
|
||||||
|
return symbol;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (--i);
|
||||||
|
if (count >= p->MinContext->SummFreq)
|
||||||
|
return -2;
|
||||||
|
p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol];
|
||||||
|
rc->Decode(rc, hiCnt, p->MinContext->SummFreq - hiCnt);
|
||||||
|
PPMD_SetAllBitsIn256Bytes(charMask);
|
||||||
|
MASK(s->Symbol) = 0;
|
||||||
|
i = p->MinContext->NumStats - 1;
|
||||||
|
do { MASK((--s)->Symbol) = 0; } while (--i);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UInt16 *prob = Ppmd7_GetBinSumm(p);
|
||||||
|
if (rc->DecodeBit(rc, *prob) == 0)
|
||||||
|
{
|
||||||
|
Byte symbol;
|
||||||
|
*prob = (UInt16)PPMD_UPDATE_PROB_0(*prob);
|
||||||
|
symbol = (p->FoundState = Ppmd7Context_OneState(p->MinContext))->Symbol;
|
||||||
|
Ppmd7_UpdateBin(p);
|
||||||
|
return symbol;
|
||||||
|
}
|
||||||
|
*prob = (UInt16)PPMD_UPDATE_PROB_1(*prob);
|
||||||
|
p->InitEsc = PPMD7_kExpEscape[*prob >> 10];
|
||||||
|
PPMD_SetAllBitsIn256Bytes(charMask);
|
||||||
|
MASK(Ppmd7Context_OneState(p->MinContext)->Symbol) = 0;
|
||||||
|
p->PrevSuccess = 0;
|
||||||
|
}
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
CPpmd_State *ps[256], *s;
|
||||||
|
UInt32 freqSum, count, hiCnt;
|
||||||
|
CPpmd_See *see;
|
||||||
|
unsigned i, num, numMasked = p->MinContext->NumStats;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
p->OrderFall++;
|
||||||
|
if (!p->MinContext->Suffix)
|
||||||
|
return -1;
|
||||||
|
p->MinContext = Ppmd7_GetContext(p, p->MinContext->Suffix);
|
||||||
|
}
|
||||||
|
while (p->MinContext->NumStats == numMasked);
|
||||||
|
hiCnt = 0;
|
||||||
|
s = Ppmd7_GetStats(p, p->MinContext);
|
||||||
|
i = 0;
|
||||||
|
num = p->MinContext->NumStats - numMasked;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
int k = (int)(MASK(s->Symbol));
|
||||||
|
hiCnt += (s->Freq & k);
|
||||||
|
ps[i] = s++;
|
||||||
|
i -= k;
|
||||||
|
}
|
||||||
|
while (i != num);
|
||||||
|
|
||||||
|
see = Ppmd7_MakeEscFreq(p, numMasked, &freqSum);
|
||||||
|
freqSum += hiCnt;
|
||||||
|
count = rc->GetThreshold(rc, freqSum);
|
||||||
|
|
||||||
|
if (count < hiCnt)
|
||||||
|
{
|
||||||
|
Byte symbol;
|
||||||
|
CPpmd_State **pps = ps;
|
||||||
|
for (hiCnt = 0; (hiCnt += (*pps)->Freq) <= count; pps++);
|
||||||
|
s = *pps;
|
||||||
|
rc->Decode(rc, hiCnt - s->Freq, s->Freq);
|
||||||
|
Ppmd_See_Update(see);
|
||||||
|
p->FoundState = s;
|
||||||
|
symbol = s->Symbol;
|
||||||
|
Ppmd7_Update2(p);
|
||||||
|
return symbol;
|
||||||
|
}
|
||||||
|
if (count >= freqSum)
|
||||||
|
return -2;
|
||||||
|
rc->Decode(rc, hiCnt, freqSum - hiCnt);
|
||||||
|
see->Summ = (UInt16)(see->Summ + freqSum);
|
||||||
|
do { MASK(ps[--i]->Symbol) = 0; } while (i != 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,185 @@
|
|||||||
|
/* Ppmd7Enc.c -- PPMdH Encoder
|
||||||
|
2010-03-12 : Igor Pavlov : Public domain
|
||||||
|
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
|
||||||
|
|
||||||
|
#include "Ppmd7.h"
|
||||||
|
|
||||||
|
#define kTopValue (1 << 24)
|
||||||
|
|
||||||
|
void Ppmd7z_RangeEnc_Init(CPpmd7z_RangeEnc *p)
|
||||||
|
{
|
||||||
|
p->Low = 0;
|
||||||
|
p->Range = 0xFFFFFFFF;
|
||||||
|
p->Cache = 0;
|
||||||
|
p->CacheSize = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void RangeEnc_ShiftLow(CPpmd7z_RangeEnc *p)
|
||||||
|
{
|
||||||
|
if ((UInt32)p->Low < (UInt32)0xFF000000 || (unsigned)(p->Low >> 32) != 0)
|
||||||
|
{
|
||||||
|
Byte temp = p->Cache;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
p->Stream->Write(p->Stream, (Byte)(temp + (Byte)(p->Low >> 32)));
|
||||||
|
temp = 0xFF;
|
||||||
|
}
|
||||||
|
while(--p->CacheSize != 0);
|
||||||
|
p->Cache = (Byte)((UInt32)p->Low >> 24);
|
||||||
|
}
|
||||||
|
p->CacheSize++;
|
||||||
|
p->Low = (UInt32)p->Low << 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void RangeEnc_Encode(CPpmd7z_RangeEnc *p, UInt32 start, UInt32 size, UInt32 total)
|
||||||
|
{
|
||||||
|
p->Low += start * (p->Range /= total);
|
||||||
|
p->Range *= size;
|
||||||
|
while (p->Range < kTopValue)
|
||||||
|
{
|
||||||
|
p->Range <<= 8;
|
||||||
|
RangeEnc_ShiftLow(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void RangeEnc_EncodeBit_0(CPpmd7z_RangeEnc *p, UInt32 size0)
|
||||||
|
{
|
||||||
|
p->Range = (p->Range >> 14) * size0;
|
||||||
|
while (p->Range < kTopValue)
|
||||||
|
{
|
||||||
|
p->Range <<= 8;
|
||||||
|
RangeEnc_ShiftLow(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void RangeEnc_EncodeBit_1(CPpmd7z_RangeEnc *p, UInt32 size0)
|
||||||
|
{
|
||||||
|
UInt32 newBound = (p->Range >> 14) * size0;
|
||||||
|
p->Low += newBound;
|
||||||
|
p->Range -= newBound;
|
||||||
|
while (p->Range < kTopValue)
|
||||||
|
{
|
||||||
|
p->Range <<= 8;
|
||||||
|
RangeEnc_ShiftLow(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Ppmd7z_RangeEnc_FlushData(CPpmd7z_RangeEnc *p)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; i < 5; i++)
|
||||||
|
RangeEnc_ShiftLow(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define MASK(sym) ((signed char *)charMask)[sym]
|
||||||
|
|
||||||
|
void Ppmd7_EncodeSymbol(CPpmd7 *p, CPpmd7z_RangeEnc *rc, int symbol)
|
||||||
|
{
|
||||||
|
size_t charMask[256 / sizeof(size_t)];
|
||||||
|
if (p->MinContext->NumStats != 1)
|
||||||
|
{
|
||||||
|
CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext);
|
||||||
|
UInt32 sum;
|
||||||
|
unsigned i;
|
||||||
|
if (s->Symbol == symbol)
|
||||||
|
{
|
||||||
|
RangeEnc_Encode(rc, 0, s->Freq, p->MinContext->SummFreq);
|
||||||
|
p->FoundState = s;
|
||||||
|
Ppmd7_Update1_0(p);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
p->PrevSuccess = 0;
|
||||||
|
sum = s->Freq;
|
||||||
|
i = p->MinContext->NumStats - 1;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if ((++s)->Symbol == symbol)
|
||||||
|
{
|
||||||
|
RangeEnc_Encode(rc, sum, s->Freq, p->MinContext->SummFreq);
|
||||||
|
p->FoundState = s;
|
||||||
|
Ppmd7_Update1(p);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sum += s->Freq;
|
||||||
|
}
|
||||||
|
while (--i);
|
||||||
|
|
||||||
|
p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol];
|
||||||
|
PPMD_SetAllBitsIn256Bytes(charMask);
|
||||||
|
MASK(s->Symbol) = 0;
|
||||||
|
i = p->MinContext->NumStats - 1;
|
||||||
|
do { MASK((--s)->Symbol) = 0; } while (--i);
|
||||||
|
RangeEnc_Encode(rc, sum, p->MinContext->SummFreq - sum, p->MinContext->SummFreq);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UInt16 *prob = Ppmd7_GetBinSumm(p);
|
||||||
|
CPpmd_State *s = Ppmd7Context_OneState(p->MinContext);
|
||||||
|
if (s->Symbol == symbol)
|
||||||
|
{
|
||||||
|
RangeEnc_EncodeBit_0(rc, *prob);
|
||||||
|
*prob = (UInt16)PPMD_UPDATE_PROB_0(*prob);
|
||||||
|
p->FoundState = s;
|
||||||
|
Ppmd7_UpdateBin(p);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RangeEnc_EncodeBit_1(rc, *prob);
|
||||||
|
*prob = (UInt16)PPMD_UPDATE_PROB_1(*prob);
|
||||||
|
p->InitEsc = PPMD7_kExpEscape[*prob >> 10];
|
||||||
|
PPMD_SetAllBitsIn256Bytes(charMask);
|
||||||
|
MASK(s->Symbol) = 0;
|
||||||
|
p->PrevSuccess = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
UInt32 escFreq;
|
||||||
|
CPpmd_See *see;
|
||||||
|
CPpmd_State *s;
|
||||||
|
UInt32 sum;
|
||||||
|
unsigned i, numMasked = p->MinContext->NumStats;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
p->OrderFall++;
|
||||||
|
if (!p->MinContext->Suffix)
|
||||||
|
return; /* EndMarker (symbol = -1) */
|
||||||
|
p->MinContext = Ppmd7_GetContext(p, p->MinContext->Suffix);
|
||||||
|
}
|
||||||
|
while (p->MinContext->NumStats == numMasked);
|
||||||
|
|
||||||
|
see = Ppmd7_MakeEscFreq(p, numMasked, &escFreq);
|
||||||
|
s = Ppmd7_GetStats(p, p->MinContext);
|
||||||
|
sum = 0;
|
||||||
|
i = p->MinContext->NumStats;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
int cur = s->Symbol;
|
||||||
|
if (cur == symbol)
|
||||||
|
{
|
||||||
|
UInt32 low = sum;
|
||||||
|
CPpmd_State *s1 = s;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
sum += (s->Freq & (int)(MASK(s->Symbol)));
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
while (--i);
|
||||||
|
RangeEnc_Encode(rc, low, s1->Freq, sum + escFreq);
|
||||||
|
Ppmd_See_Update(see);
|
||||||
|
p->FoundState = s1;
|
||||||
|
Ppmd7_Update2(p);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sum += (s->Freq & (int)(MASK(cur)));
|
||||||
|
MASK(cur) = 0;
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
while (--i);
|
||||||
|
|
||||||
|
RangeEnc_Encode(rc, sum, escFreq, sum + escFreq);
|
||||||
|
see->Summ = (UInt16)(see->Summ + sum + escFreq);
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,133 @@
|
|||||||
|
/* Ppmd8.h -- PPMdI codec
|
||||||
|
2010-03-24 : Igor Pavlov : Public domain
|
||||||
|
This code is based on:
|
||||||
|
PPMd var.I (2002): Dmitry Shkarin : Public domain
|
||||||
|
Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
|
||||||
|
|
||||||
|
#ifndef __PPMD8_H
|
||||||
|
#define __PPMD8_H
|
||||||
|
|
||||||
|
#include "Ppmd.h"
|
||||||
|
|
||||||
|
EXTERN_C_BEGIN
|
||||||
|
|
||||||
|
#define PPMD8_MIN_ORDER 2
|
||||||
|
#define PPMD8_MAX_ORDER 16
|
||||||
|
|
||||||
|
struct CPpmd8_Context_;
|
||||||
|
|
||||||
|
typedef
|
||||||
|
#ifdef PPMD_32BIT
|
||||||
|
struct CPpmd8_Context_ *
|
||||||
|
#else
|
||||||
|
UInt32
|
||||||
|
#endif
|
||||||
|
CPpmd8_Context_Ref;
|
||||||
|
|
||||||
|
typedef struct CPpmd8_Context_
|
||||||
|
{
|
||||||
|
Byte NumStats;
|
||||||
|
Byte Flags;
|
||||||
|
UInt16 SummFreq;
|
||||||
|
CPpmd_State_Ref Stats;
|
||||||
|
CPpmd8_Context_Ref Suffix;
|
||||||
|
} CPpmd8_Context;
|
||||||
|
|
||||||
|
#define Ppmd8Context_OneState(p) ((CPpmd_State *)&(p)->SummFreq)
|
||||||
|
|
||||||
|
/* The BUG in Shkarin's code for FREEZE mode was fixed, but that fixed
|
||||||
|
code is not compatible with original code for some files compressed
|
||||||
|
in FREEZE mode. So we disable FREEZE mode support. */
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PPMD8_RESTORE_METHOD_RESTART,
|
||||||
|
PPMD8_RESTORE_METHOD_CUT_OFF
|
||||||
|
#ifdef PPMD8_FREEZE_SUPPORT
|
||||||
|
, PPMD8_RESTORE_METHOD_FREEZE
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
CPpmd8_Context *MinContext, *MaxContext;
|
||||||
|
CPpmd_State *FoundState;
|
||||||
|
unsigned OrderFall, InitEsc, PrevSuccess, MaxOrder;
|
||||||
|
Int32 RunLength, InitRL; /* must be 32-bit at least */
|
||||||
|
|
||||||
|
UInt32 Size;
|
||||||
|
UInt32 GlueCount;
|
||||||
|
Byte *Base, *LoUnit, *HiUnit, *Text, *UnitsStart;
|
||||||
|
UInt32 AlignOffset;
|
||||||
|
unsigned RestoreMethod;
|
||||||
|
|
||||||
|
/* Range Coder */
|
||||||
|
UInt32 Range;
|
||||||
|
UInt32 Code;
|
||||||
|
UInt32 Low;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
IByteIn *In;
|
||||||
|
IByteOut *Out;
|
||||||
|
} Stream;
|
||||||
|
|
||||||
|
Byte Indx2Units[PPMD_NUM_INDEXES];
|
||||||
|
Byte Units2Indx[128];
|
||||||
|
CPpmd_Void_Ref FreeList[PPMD_NUM_INDEXES];
|
||||||
|
UInt32 Stamps[PPMD_NUM_INDEXES];
|
||||||
|
|
||||||
|
Byte NS2BSIndx[256], NS2Indx[260];
|
||||||
|
CPpmd_See DummySee, See[24][32];
|
||||||
|
UInt16 BinSumm[25][64];
|
||||||
|
} CPpmd8;
|
||||||
|
|
||||||
|
void Ppmd8_Construct(CPpmd8 *p);
|
||||||
|
Bool Ppmd8_Alloc(CPpmd8 *p, UInt32 size, ISzAlloc *alloc);
|
||||||
|
void Ppmd8_Free(CPpmd8 *p, ISzAlloc *alloc);
|
||||||
|
void Ppmd8_Init(CPpmd8 *p, unsigned maxOrder, unsigned restoreMethod);
|
||||||
|
#define Ppmd8_WasAllocated(p) ((p)->Base != NULL)
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- Internal Functions ---------- */
|
||||||
|
|
||||||
|
extern const Byte PPMD8_kExpEscape[16];
|
||||||
|
|
||||||
|
#ifdef PPMD_32BIT
|
||||||
|
#define Ppmd8_GetPtr(p, ptr) (ptr)
|
||||||
|
#define Ppmd8_GetContext(p, ptr) (ptr)
|
||||||
|
#define Ppmd8_GetStats(p, ctx) ((ctx)->Stats)
|
||||||
|
#else
|
||||||
|
#define Ppmd8_GetPtr(p, offs) ((void *)((p)->Base + (offs)))
|
||||||
|
#define Ppmd8_GetContext(p, offs) ((CPpmd8_Context *)Ppmd8_GetPtr((p), (offs)))
|
||||||
|
#define Ppmd8_GetStats(p, ctx) ((CPpmd_State *)Ppmd8_GetPtr((p), ((ctx)->Stats)))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void Ppmd8_Update1(CPpmd8 *p);
|
||||||
|
void Ppmd8_Update1_0(CPpmd8 *p);
|
||||||
|
void Ppmd8_Update2(CPpmd8 *p);
|
||||||
|
void Ppmd8_UpdateBin(CPpmd8 *p);
|
||||||
|
|
||||||
|
#define Ppmd8_GetBinSumm(p) \
|
||||||
|
&p->BinSumm[p->NS2Indx[Ppmd8Context_OneState(p->MinContext)->Freq - 1]][ \
|
||||||
|
p->NS2BSIndx[Ppmd8_GetContext(p, p->MinContext->Suffix)->NumStats] + \
|
||||||
|
p->PrevSuccess + p->MinContext->Flags + ((p->RunLength >> 26) & 0x20)]
|
||||||
|
|
||||||
|
CPpmd_See *Ppmd8_MakeEscFreq(CPpmd8 *p, unsigned numMasked, UInt32 *scale);
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- Decode ---------- */
|
||||||
|
|
||||||
|
Bool Ppmd8_RangeDec_Init(CPpmd8 *p);
|
||||||
|
#define Ppmd8_RangeDec_IsFinishedOK(p) ((p)->Code == 0)
|
||||||
|
int Ppmd8_DecodeSymbol(CPpmd8 *p); /* returns: -1 as EndMarker, -2 as DataError */
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- Encode ---------- */
|
||||||
|
|
||||||
|
#define Ppmd8_RangeEnc_Init(p) { (p)->Low = 0; (p)->Range = 0xFFFFFFFF; }
|
||||||
|
void Ppmd8_RangeEnc_FlushData(CPpmd8 *p);
|
||||||
|
void Ppmd8_EncodeSymbol(CPpmd8 *p, int symbol); /* symbol = -1 means EndMarker */
|
||||||
|
|
||||||
|
EXTERN_C_END
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,155 @@
|
|||||||
|
/* Ppmd8Dec.c -- PPMdI Decoder
|
||||||
|
2010-03-12 : Igor Pavlov : Public domain
|
||||||
|
This code is based on:
|
||||||
|
PPMd var.I (2002): Dmitry Shkarin : Public domain
|
||||||
|
Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
|
||||||
|
|
||||||
|
#include "Ppmd8.h"
|
||||||
|
|
||||||
|
#define kTop (1 << 24)
|
||||||
|
#define kBot (1 << 15)
|
||||||
|
|
||||||
|
Bool Ppmd8_RangeDec_Init(CPpmd8 *p)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
p->Low = 0;
|
||||||
|
p->Range = 0xFFFFFFFF;
|
||||||
|
p->Code = 0;
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
p->Code = (p->Code << 8) | p->Stream.In->Read(p->Stream.In);
|
||||||
|
return (p->Code < 0xFFFFFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
static UInt32 RangeDec_GetThreshold(CPpmd8 *p, UInt32 total)
|
||||||
|
{
|
||||||
|
return p->Code / (p->Range /= total);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void RangeDec_Decode(CPpmd8 *p, UInt32 start, UInt32 size)
|
||||||
|
{
|
||||||
|
start *= p->Range;
|
||||||
|
p->Low += start;
|
||||||
|
p->Code -= start;
|
||||||
|
p->Range *= size;
|
||||||
|
|
||||||
|
while ((p->Low ^ (p->Low + p->Range)) < kTop ||
|
||||||
|
p->Range < kBot && ((p->Range = (0 - p->Low) & (kBot - 1)), 1))
|
||||||
|
{
|
||||||
|
p->Code = (p->Code << 8) | p->Stream.In->Read(p->Stream.In);
|
||||||
|
p->Range <<= 8;
|
||||||
|
p->Low <<= 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MASK(sym) ((signed char *)charMask)[sym]
|
||||||
|
|
||||||
|
int Ppmd8_DecodeSymbol(CPpmd8 *p)
|
||||||
|
{
|
||||||
|
size_t charMask[256 / sizeof(size_t)];
|
||||||
|
if (p->MinContext->NumStats != 0)
|
||||||
|
{
|
||||||
|
CPpmd_State *s = Ppmd8_GetStats(p, p->MinContext);
|
||||||
|
unsigned i;
|
||||||
|
UInt32 count, hiCnt;
|
||||||
|
if ((count = RangeDec_GetThreshold(p, p->MinContext->SummFreq)) < (hiCnt = s->Freq))
|
||||||
|
{
|
||||||
|
Byte symbol;
|
||||||
|
RangeDec_Decode(p, 0, s->Freq);
|
||||||
|
p->FoundState = s;
|
||||||
|
symbol = s->Symbol;
|
||||||
|
Ppmd8_Update1_0(p);
|
||||||
|
return symbol;
|
||||||
|
}
|
||||||
|
p->PrevSuccess = 0;
|
||||||
|
i = p->MinContext->NumStats;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if ((hiCnt += (++s)->Freq) > count)
|
||||||
|
{
|
||||||
|
Byte symbol;
|
||||||
|
RangeDec_Decode(p, hiCnt - s->Freq, s->Freq);
|
||||||
|
p->FoundState = s;
|
||||||
|
symbol = s->Symbol;
|
||||||
|
Ppmd8_Update1(p);
|
||||||
|
return symbol;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (--i);
|
||||||
|
if (count >= p->MinContext->SummFreq)
|
||||||
|
return -2;
|
||||||
|
RangeDec_Decode(p, hiCnt, p->MinContext->SummFreq - hiCnt);
|
||||||
|
PPMD_SetAllBitsIn256Bytes(charMask);
|
||||||
|
MASK(s->Symbol) = 0;
|
||||||
|
i = p->MinContext->NumStats;
|
||||||
|
do { MASK((--s)->Symbol) = 0; } while (--i);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UInt16 *prob = Ppmd8_GetBinSumm(p);
|
||||||
|
if (((p->Code / (p->Range >>= 14)) < *prob))
|
||||||
|
{
|
||||||
|
Byte symbol;
|
||||||
|
RangeDec_Decode(p, 0, *prob);
|
||||||
|
*prob = (UInt16)PPMD_UPDATE_PROB_0(*prob);
|
||||||
|
symbol = (p->FoundState = Ppmd8Context_OneState(p->MinContext))->Symbol;
|
||||||
|
Ppmd8_UpdateBin(p);
|
||||||
|
return symbol;
|
||||||
|
}
|
||||||
|
RangeDec_Decode(p, *prob, (1 << 14) - *prob);
|
||||||
|
*prob = (UInt16)PPMD_UPDATE_PROB_1(*prob);
|
||||||
|
p->InitEsc = PPMD8_kExpEscape[*prob >> 10];
|
||||||
|
PPMD_SetAllBitsIn256Bytes(charMask);
|
||||||
|
MASK(Ppmd8Context_OneState(p->MinContext)->Symbol) = 0;
|
||||||
|
p->PrevSuccess = 0;
|
||||||
|
}
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
CPpmd_State *ps[256], *s;
|
||||||
|
UInt32 freqSum, count, hiCnt;
|
||||||
|
CPpmd_See *see;
|
||||||
|
unsigned i, num, numMasked = p->MinContext->NumStats;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
p->OrderFall++;
|
||||||
|
if (!p->MinContext->Suffix)
|
||||||
|
return -1;
|
||||||
|
p->MinContext = Ppmd8_GetContext(p, p->MinContext->Suffix);
|
||||||
|
}
|
||||||
|
while (p->MinContext->NumStats == numMasked);
|
||||||
|
hiCnt = 0;
|
||||||
|
s = Ppmd8_GetStats(p, p->MinContext);
|
||||||
|
i = 0;
|
||||||
|
num = p->MinContext->NumStats - numMasked;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
int k = (int)(MASK(s->Symbol));
|
||||||
|
hiCnt += (s->Freq & k);
|
||||||
|
ps[i] = s++;
|
||||||
|
i -= k;
|
||||||
|
}
|
||||||
|
while (i != num);
|
||||||
|
|
||||||
|
see = Ppmd8_MakeEscFreq(p, numMasked, &freqSum);
|
||||||
|
freqSum += hiCnt;
|
||||||
|
count = RangeDec_GetThreshold(p, freqSum);
|
||||||
|
|
||||||
|
if (count < hiCnt)
|
||||||
|
{
|
||||||
|
Byte symbol;
|
||||||
|
CPpmd_State **pps = ps;
|
||||||
|
for (hiCnt = 0; (hiCnt += (*pps)->Freq) <= count; pps++);
|
||||||
|
s = *pps;
|
||||||
|
RangeDec_Decode(p, hiCnt - s->Freq, s->Freq);
|
||||||
|
Ppmd_See_Update(see);
|
||||||
|
p->FoundState = s;
|
||||||
|
symbol = s->Symbol;
|
||||||
|
Ppmd8_Update2(p);
|
||||||
|
return symbol;
|
||||||
|
}
|
||||||
|
if (count >= freqSum)
|
||||||
|
return -2;
|
||||||
|
RangeDec_Decode(p, hiCnt, freqSum - hiCnt);
|
||||||
|
see->Summ = (UInt16)(see->Summ + freqSum);
|
||||||
|
do { MASK(ps[--i]->Symbol) = 0; } while (i != 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,161 @@
|
|||||||
|
/* Ppmd8Enc.c -- PPMdI Encoder
|
||||||
|
2010-03-12 : Igor Pavlov : Public domain
|
||||||
|
This code is based on:
|
||||||
|
PPMd var.I (2002): Dmitry Shkarin : Public domain
|
||||||
|
Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
|
||||||
|
|
||||||
|
#include "Ppmd8.h"
|
||||||
|
|
||||||
|
#define kTop (1 << 24)
|
||||||
|
#define kBot (1 << 15)
|
||||||
|
|
||||||
|
void Ppmd8_RangeEnc_FlushData(CPpmd8 *p)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; i < 4; i++, p->Low <<= 8 )
|
||||||
|
p->Stream.Out->Write(p->Stream.Out, (Byte)(p->Low >> 24));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void RangeEnc_Normalize(CPpmd8 *p)
|
||||||
|
{
|
||||||
|
while ((p->Low ^ (p->Low + p->Range)) < kTop ||
|
||||||
|
p->Range < kBot && ((p->Range = (0 - p->Low) & (kBot - 1)), 1))
|
||||||
|
{
|
||||||
|
p->Stream.Out->Write(p->Stream.Out, (Byte)(p->Low >> 24));
|
||||||
|
p->Range <<= 8;
|
||||||
|
p->Low <<= 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void RangeEnc_Encode(CPpmd8 *p, UInt32 start, UInt32 size, UInt32 total)
|
||||||
|
{
|
||||||
|
p->Low += start * (p->Range /= total);
|
||||||
|
p->Range *= size;
|
||||||
|
RangeEnc_Normalize(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void RangeEnc_EncodeBit_0(CPpmd8 *p, UInt32 size0)
|
||||||
|
{
|
||||||
|
p->Range >>= 14;
|
||||||
|
p->Range *= size0;
|
||||||
|
RangeEnc_Normalize(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void RangeEnc_EncodeBit_1(CPpmd8 *p, UInt32 size0)
|
||||||
|
{
|
||||||
|
p->Low += size0 * (p->Range >>= 14);
|
||||||
|
p->Range *= ((1 << 14) - size0);
|
||||||
|
RangeEnc_Normalize(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define MASK(sym) ((signed char *)charMask)[sym]
|
||||||
|
|
||||||
|
void Ppmd8_EncodeSymbol(CPpmd8 *p, int symbol)
|
||||||
|
{
|
||||||
|
size_t charMask[256 / sizeof(size_t)];
|
||||||
|
if (p->MinContext->NumStats != 0)
|
||||||
|
{
|
||||||
|
CPpmd_State *s = Ppmd8_GetStats(p, p->MinContext);
|
||||||
|
UInt32 sum;
|
||||||
|
unsigned i;
|
||||||
|
if (s->Symbol == symbol)
|
||||||
|
{
|
||||||
|
RangeEnc_Encode(p, 0, s->Freq, p->MinContext->SummFreq);
|
||||||
|
p->FoundState = s;
|
||||||
|
Ppmd8_Update1_0(p);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
p->PrevSuccess = 0;
|
||||||
|
sum = s->Freq;
|
||||||
|
i = p->MinContext->NumStats;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if ((++s)->Symbol == symbol)
|
||||||
|
{
|
||||||
|
RangeEnc_Encode(p, sum, s->Freq, p->MinContext->SummFreq);
|
||||||
|
p->FoundState = s;
|
||||||
|
Ppmd8_Update1(p);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sum += s->Freq;
|
||||||
|
}
|
||||||
|
while (--i);
|
||||||
|
|
||||||
|
PPMD_SetAllBitsIn256Bytes(charMask);
|
||||||
|
MASK(s->Symbol) = 0;
|
||||||
|
i = p->MinContext->NumStats;
|
||||||
|
do { MASK((--s)->Symbol) = 0; } while (--i);
|
||||||
|
RangeEnc_Encode(p, sum, p->MinContext->SummFreq - sum, p->MinContext->SummFreq);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UInt16 *prob = Ppmd8_GetBinSumm(p);
|
||||||
|
CPpmd_State *s = Ppmd8Context_OneState(p->MinContext);
|
||||||
|
if (s->Symbol == symbol)
|
||||||
|
{
|
||||||
|
RangeEnc_EncodeBit_0(p, *prob);
|
||||||
|
*prob = (UInt16)PPMD_UPDATE_PROB_0(*prob);
|
||||||
|
p->FoundState = s;
|
||||||
|
Ppmd8_UpdateBin(p);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RangeEnc_EncodeBit_1(p, *prob);
|
||||||
|
*prob = (UInt16)PPMD_UPDATE_PROB_1(*prob);
|
||||||
|
p->InitEsc = PPMD8_kExpEscape[*prob >> 10];
|
||||||
|
PPMD_SetAllBitsIn256Bytes(charMask);
|
||||||
|
MASK(s->Symbol) = 0;
|
||||||
|
p->PrevSuccess = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
UInt32 escFreq;
|
||||||
|
CPpmd_See *see;
|
||||||
|
CPpmd_State *s;
|
||||||
|
UInt32 sum;
|
||||||
|
unsigned i, numMasked = p->MinContext->NumStats;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
p->OrderFall++;
|
||||||
|
if (!p->MinContext->Suffix)
|
||||||
|
return; /* EndMarker (symbol = -1) */
|
||||||
|
p->MinContext = Ppmd8_GetContext(p, p->MinContext->Suffix);
|
||||||
|
}
|
||||||
|
while (p->MinContext->NumStats == numMasked);
|
||||||
|
|
||||||
|
see = Ppmd8_MakeEscFreq(p, numMasked, &escFreq);
|
||||||
|
s = Ppmd8_GetStats(p, p->MinContext);
|
||||||
|
sum = 0;
|
||||||
|
i = p->MinContext->NumStats + 1;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
int cur = s->Symbol;
|
||||||
|
if (cur == symbol)
|
||||||
|
{
|
||||||
|
UInt32 low = sum;
|
||||||
|
CPpmd_State *s1 = s;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
sum += (s->Freq & (int)(MASK(s->Symbol)));
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
while (--i);
|
||||||
|
RangeEnc_Encode(p, low, s1->Freq, sum + escFreq);
|
||||||
|
Ppmd_See_Update(see);
|
||||||
|
p->FoundState = s1;
|
||||||
|
Ppmd8_Update2(p);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sum += (s->Freq & (int)(MASK(cur)));
|
||||||
|
MASK(cur) = 0;
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
while (--i);
|
||||||
|
|
||||||
|
RangeEnc_Encode(p, sum, escFreq, sum + escFreq);
|
||||||
|
see->Summ = (UInt16)(see->Summ + sum + escFreq);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
/* RotateDefs.h -- Rotate functions
|
||||||
|
2009-02-07 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#ifndef __ROTATE_DEFS_H
|
||||||
|
#define __ROTATE_DEFS_H
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#define rotlFixed(x, n) _rotl((x), (n))
|
||||||
|
#define rotrFixed(x, n) _rotr((x), (n))
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define rotlFixed(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
|
||||||
|
#define rotrFixed(x, n) (((x) >> (n)) | ((x) << (32 - (n))))
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,204 @@
|
|||||||
|
/* Crypto/Sha256.c -- SHA-256 Hash function
|
||||||
|
2008-11-06 : Igor Pavlov : Public domain
|
||||||
|
This code is based on public domain code from Wei Dai's Crypto++ library. */
|
||||||
|
|
||||||
|
#include "Sha256.h"
|
||||||
|
#include "RotateDefs.h"
|
||||||
|
|
||||||
|
/* define it for speed optimization */
|
||||||
|
/* #define _SHA256_UNROLL */
|
||||||
|
/* #define _SHA256_UNROLL2 */
|
||||||
|
|
||||||
|
void Sha256_Init(CSha256 *p)
|
||||||
|
{
|
||||||
|
p->state[0] = 0x6a09e667;
|
||||||
|
p->state[1] = 0xbb67ae85;
|
||||||
|
p->state[2] = 0x3c6ef372;
|
||||||
|
p->state[3] = 0xa54ff53a;
|
||||||
|
p->state[4] = 0x510e527f;
|
||||||
|
p->state[5] = 0x9b05688c;
|
||||||
|
p->state[6] = 0x1f83d9ab;
|
||||||
|
p->state[7] = 0x5be0cd19;
|
||||||
|
p->count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define S0(x) (rotrFixed(x, 2) ^ rotrFixed(x,13) ^ rotrFixed(x, 22))
|
||||||
|
#define S1(x) (rotrFixed(x, 6) ^ rotrFixed(x,11) ^ rotrFixed(x, 25))
|
||||||
|
#define s0(x) (rotrFixed(x, 7) ^ rotrFixed(x,18) ^ (x >> 3))
|
||||||
|
#define s1(x) (rotrFixed(x,17) ^ rotrFixed(x,19) ^ (x >> 10))
|
||||||
|
|
||||||
|
#define blk0(i) (W[i] = data[i])
|
||||||
|
#define blk2(i) (W[i&15] += s1(W[(i-2)&15]) + W[(i-7)&15] + s0(W[(i-15)&15]))
|
||||||
|
|
||||||
|
#define Ch(x,y,z) (z^(x&(y^z)))
|
||||||
|
#define Maj(x,y,z) ((x&y)|(z&(x|y)))
|
||||||
|
|
||||||
|
#define a(i) T[(0-(i))&7]
|
||||||
|
#define b(i) T[(1-(i))&7]
|
||||||
|
#define c(i) T[(2-(i))&7]
|
||||||
|
#define d(i) T[(3-(i))&7]
|
||||||
|
#define e(i) T[(4-(i))&7]
|
||||||
|
#define f(i) T[(5-(i))&7]
|
||||||
|
#define g(i) T[(6-(i))&7]
|
||||||
|
#define h(i) T[(7-(i))&7]
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _SHA256_UNROLL2
|
||||||
|
|
||||||
|
#define R(a,b,c,d,e,f,g,h, i) h += S1(e) + Ch(e,f,g) + K[i+j] + (j?blk2(i):blk0(i));\
|
||||||
|
d += h; h += S0(a) + Maj(a, b, c)
|
||||||
|
|
||||||
|
#define RX_8(i) \
|
||||||
|
R(a,b,c,d,e,f,g,h, i); \
|
||||||
|
R(h,a,b,c,d,e,f,g, i+1); \
|
||||||
|
R(g,h,a,b,c,d,e,f, i+2); \
|
||||||
|
R(f,g,h,a,b,c,d,e, i+3); \
|
||||||
|
R(e,f,g,h,a,b,c,d, i+4); \
|
||||||
|
R(d,e,f,g,h,a,b,c, i+5); \
|
||||||
|
R(c,d,e,f,g,h,a,b, i+6); \
|
||||||
|
R(b,c,d,e,f,g,h,a, i+7)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define R(i) h(i) += S1(e(i)) + Ch(e(i),f(i),g(i)) + K[i+j] + (j?blk2(i):blk0(i));\
|
||||||
|
d(i) += h(i); h(i) += S0(a(i)) + Maj(a(i), b(i), c(i))
|
||||||
|
|
||||||
|
#ifdef _SHA256_UNROLL
|
||||||
|
|
||||||
|
#define RX_8(i) R(i+0); R(i+1); R(i+2); R(i+3); R(i+4); R(i+5); R(i+6); R(i+7);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const UInt32 K[64] = {
|
||||||
|
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
|
||||||
|
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
||||||
|
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
|
||||||
|
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
||||||
|
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
|
||||||
|
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
||||||
|
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
|
||||||
|
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
||||||
|
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
|
||||||
|
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
||||||
|
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
|
||||||
|
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
||||||
|
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
|
||||||
|
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
||||||
|
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
|
||||||
|
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
||||||
|
};
|
||||||
|
|
||||||
|
static void Sha256_Transform(UInt32 *state, const UInt32 *data)
|
||||||
|
{
|
||||||
|
UInt32 W[16];
|
||||||
|
unsigned j;
|
||||||
|
#ifdef _SHA256_UNROLL2
|
||||||
|
UInt32 a,b,c,d,e,f,g,h;
|
||||||
|
a = state[0];
|
||||||
|
b = state[1];
|
||||||
|
c = state[2];
|
||||||
|
d = state[3];
|
||||||
|
e = state[4];
|
||||||
|
f = state[5];
|
||||||
|
g = state[6];
|
||||||
|
h = state[7];
|
||||||
|
#else
|
||||||
|
UInt32 T[8];
|
||||||
|
for (j = 0; j < 8; j++)
|
||||||
|
T[j] = state[j];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (j = 0; j < 64; j += 16)
|
||||||
|
{
|
||||||
|
#if defined(_SHA256_UNROLL) || defined(_SHA256_UNROLL2)
|
||||||
|
RX_8(0); RX_8(8);
|
||||||
|
#else
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; i < 16; i++) { R(i); }
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _SHA256_UNROLL2
|
||||||
|
state[0] += a;
|
||||||
|
state[1] += b;
|
||||||
|
state[2] += c;
|
||||||
|
state[3] += d;
|
||||||
|
state[4] += e;
|
||||||
|
state[5] += f;
|
||||||
|
state[6] += g;
|
||||||
|
state[7] += h;
|
||||||
|
#else
|
||||||
|
for (j = 0; j < 8; j++)
|
||||||
|
state[j] += T[j];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Wipe variables */
|
||||||
|
/* memset(W, 0, sizeof(W)); */
|
||||||
|
/* memset(T, 0, sizeof(T)); */
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef S0
|
||||||
|
#undef S1
|
||||||
|
#undef s0
|
||||||
|
#undef s1
|
||||||
|
|
||||||
|
static void Sha256_WriteByteBlock(CSha256 *p)
|
||||||
|
{
|
||||||
|
UInt32 data32[16];
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
data32[i] =
|
||||||
|
((UInt32)(p->buffer[i * 4 ]) << 24) +
|
||||||
|
((UInt32)(p->buffer[i * 4 + 1]) << 16) +
|
||||||
|
((UInt32)(p->buffer[i * 4 + 2]) << 8) +
|
||||||
|
((UInt32)(p->buffer[i * 4 + 3]));
|
||||||
|
Sha256_Transform(p->state, data32);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sha256_Update(CSha256 *p, const Byte *data, size_t size)
|
||||||
|
{
|
||||||
|
UInt32 curBufferPos = (UInt32)p->count & 0x3F;
|
||||||
|
while (size > 0)
|
||||||
|
{
|
||||||
|
p->buffer[curBufferPos++] = *data++;
|
||||||
|
p->count++;
|
||||||
|
size--;
|
||||||
|
if (curBufferPos == 64)
|
||||||
|
{
|
||||||
|
curBufferPos = 0;
|
||||||
|
Sha256_WriteByteBlock(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sha256_Final(CSha256 *p, Byte *digest)
|
||||||
|
{
|
||||||
|
UInt64 lenInBits = (p->count << 3);
|
||||||
|
UInt32 curBufferPos = (UInt32)p->count & 0x3F;
|
||||||
|
unsigned i;
|
||||||
|
p->buffer[curBufferPos++] = 0x80;
|
||||||
|
while (curBufferPos != (64 - 8))
|
||||||
|
{
|
||||||
|
curBufferPos &= 0x3F;
|
||||||
|
if (curBufferPos == 0)
|
||||||
|
Sha256_WriteByteBlock(p);
|
||||||
|
p->buffer[curBufferPos++] = 0;
|
||||||
|
}
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
p->buffer[curBufferPos++] = (Byte)(lenInBits >> 56);
|
||||||
|
lenInBits <<= 8;
|
||||||
|
}
|
||||||
|
Sha256_WriteByteBlock(p);
|
||||||
|
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
*digest++ = (Byte)(p->state[i] >> 24);
|
||||||
|
*digest++ = (Byte)(p->state[i] >> 16);
|
||||||
|
*digest++ = (Byte)(p->state[i] >> 8);
|
||||||
|
*digest++ = (Byte)(p->state[i]);
|
||||||
|
}
|
||||||
|
Sha256_Init(p);
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
/* Sha256.h -- SHA-256 Hash
|
||||||
|
2009-02-07 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#ifndef __CRYPTO_SHA256_H
|
||||||
|
#define __CRYPTO_SHA256_H
|
||||||
|
|
||||||
|
#include "Types.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SHA256_DIGEST_SIZE 32
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
UInt32 state[8];
|
||||||
|
UInt64 count;
|
||||||
|
Byte buffer[64];
|
||||||
|
} CSha256;
|
||||||
|
|
||||||
|
void Sha256_Init(CSha256 *p);
|
||||||
|
void Sha256_Update(CSha256 *p, const Byte *data, size_t size);
|
||||||
|
void Sha256_Final(CSha256 *p, Byte *digest);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
/* Threads.c -- multithreading library
|
||||||
|
2009-09-20 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#ifndef _WIN32_WCE
|
||||||
|
#include <process.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "Threads.h"
|
||||||
|
|
||||||
|
static WRes GetError()
|
||||||
|
{
|
||||||
|
DWORD res = GetLastError();
|
||||||
|
return (res) ? (WRes)(res) : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
WRes HandleToWRes(HANDLE h) { return (h != 0) ? 0 : GetError(); }
|
||||||
|
WRes BOOLToWRes(BOOL v) { return v ? 0 : GetError(); }
|
||||||
|
|
||||||
|
WRes HandlePtr_Close(HANDLE *p)
|
||||||
|
{
|
||||||
|
if (*p != NULL)
|
||||||
|
if (!CloseHandle(*p))
|
||||||
|
return GetError();
|
||||||
|
*p = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
WRes Handle_WaitObject(HANDLE h) { return (WRes)WaitForSingleObject(h, INFINITE); }
|
||||||
|
|
||||||
|
WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param)
|
||||||
|
{
|
||||||
|
unsigned threadId; /* Windows Me/98/95: threadId parameter may not be NULL in _beginthreadex/CreateThread functions */
|
||||||
|
*p =
|
||||||
|
#ifdef UNDER_CE
|
||||||
|
CreateThread(0, 0, func, param, 0, &threadId);
|
||||||
|
#else
|
||||||
|
(HANDLE)_beginthreadex(NULL, 0, func, param, 0, &threadId);
|
||||||
|
#endif
|
||||||
|
/* maybe we must use errno here, but probably GetLastError() is also OK. */
|
||||||
|
return HandleToWRes(*p);
|
||||||
|
}
|
||||||
|
|
||||||
|
WRes Event_Create(CEvent *p, BOOL manualReset, int signaled)
|
||||||
|
{
|
||||||
|
*p = CreateEvent(NULL, manualReset, (signaled ? TRUE : FALSE), NULL);
|
||||||
|
return HandleToWRes(*p);
|
||||||
|
}
|
||||||
|
|
||||||
|
WRes Event_Set(CEvent *p) { return BOOLToWRes(SetEvent(*p)); }
|
||||||
|
WRes Event_Reset(CEvent *p) { return BOOLToWRes(ResetEvent(*p)); }
|
||||||
|
|
||||||
|
WRes ManualResetEvent_Create(CManualResetEvent *p, int signaled) { return Event_Create(p, TRUE, signaled); }
|
||||||
|
WRes AutoResetEvent_Create(CAutoResetEvent *p, int signaled) { return Event_Create(p, FALSE, signaled); }
|
||||||
|
WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p) { return ManualResetEvent_Create(p, 0); }
|
||||||
|
WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p) { return AutoResetEvent_Create(p, 0); }
|
||||||
|
|
||||||
|
|
||||||
|
WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount)
|
||||||
|
{
|
||||||
|
*p = CreateSemaphore(NULL, (LONG)initCount, (LONG)maxCount, NULL);
|
||||||
|
return HandleToWRes(*p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static WRes Semaphore_Release(CSemaphore *p, LONG releaseCount, LONG *previousCount)
|
||||||
|
{ return BOOLToWRes(ReleaseSemaphore(*p, releaseCount, previousCount)); }
|
||||||
|
WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num)
|
||||||
|
{ return Semaphore_Release(p, (LONG)num, NULL); }
|
||||||
|
WRes Semaphore_Release1(CSemaphore *p) { return Semaphore_ReleaseN(p, 1); }
|
||||||
|
|
||||||
|
WRes CriticalSection_Init(CCriticalSection *p)
|
||||||
|
{
|
||||||
|
/* InitializeCriticalSection can raise only STATUS_NO_MEMORY exception */
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
__try
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
InitializeCriticalSection(p);
|
||||||
|
/* InitializeCriticalSectionAndSpinCount(p, 0); */
|
||||||
|
}
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
__except (EXCEPTION_EXECUTE_HANDLER) { return 1; }
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
/* Threads.h -- multithreading library
|
||||||
|
2009-03-27 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#ifndef __7Z_THREADS_H
|
||||||
|
#define __7Z_THREADS_H
|
||||||
|
|
||||||
|
#include "Types.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
WRes HandlePtr_Close(HANDLE *h);
|
||||||
|
WRes Handle_WaitObject(HANDLE h);
|
||||||
|
|
||||||
|
typedef HANDLE CThread;
|
||||||
|
#define Thread_Construct(p) *(p) = NULL
|
||||||
|
#define Thread_WasCreated(p) (*(p) != NULL)
|
||||||
|
#define Thread_Close(p) HandlePtr_Close(p)
|
||||||
|
#define Thread_Wait(p) Handle_WaitObject(*(p))
|
||||||
|
typedef unsigned THREAD_FUNC_RET_TYPE;
|
||||||
|
#define THREAD_FUNC_CALL_TYPE MY_STD_CALL
|
||||||
|
#define THREAD_FUNC_DECL THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE
|
||||||
|
typedef THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE * THREAD_FUNC_TYPE)(void *);
|
||||||
|
WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param);
|
||||||
|
|
||||||
|
typedef HANDLE CEvent;
|
||||||
|
typedef CEvent CAutoResetEvent;
|
||||||
|
typedef CEvent CManualResetEvent;
|
||||||
|
#define Event_Construct(p) *(p) = NULL
|
||||||
|
#define Event_IsCreated(p) (*(p) != NULL)
|
||||||
|
#define Event_Close(p) HandlePtr_Close(p)
|
||||||
|
#define Event_Wait(p) Handle_WaitObject(*(p))
|
||||||
|
WRes Event_Set(CEvent *p);
|
||||||
|
WRes Event_Reset(CEvent *p);
|
||||||
|
WRes ManualResetEvent_Create(CManualResetEvent *p, int signaled);
|
||||||
|
WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p);
|
||||||
|
WRes AutoResetEvent_Create(CAutoResetEvent *p, int signaled);
|
||||||
|
WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p);
|
||||||
|
|
||||||
|
typedef HANDLE CSemaphore;
|
||||||
|
#define Semaphore_Construct(p) (*p) = NULL
|
||||||
|
#define Semaphore_Close(p) HandlePtr_Close(p)
|
||||||
|
#define Semaphore_Wait(p) Handle_WaitObject(*(p))
|
||||||
|
WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount);
|
||||||
|
WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num);
|
||||||
|
WRes Semaphore_Release1(CSemaphore *p);
|
||||||
|
|
||||||
|
typedef CRITICAL_SECTION CCriticalSection;
|
||||||
|
WRes CriticalSection_Init(CCriticalSection *p);
|
||||||
|
#define CriticalSection_Delete(p) DeleteCriticalSection(p)
|
||||||
|
#define CriticalSection_Enter(p) EnterCriticalSection(p)
|
||||||
|
#define CriticalSection_Leave(p) LeaveCriticalSection(p)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,251 @@
|
|||||||
|
/* Types.h -- Basic types
|
||||||
|
2010-03-11 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#ifndef __7Z_TYPES_H
|
||||||
|
#define __7Z_TYPES_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef EXTERN_C_BEGIN
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#define EXTERN_C_BEGIN extern "C" {
|
||||||
|
#define EXTERN_C_END }
|
||||||
|
#else
|
||||||
|
#define EXTERN_C_BEGIN
|
||||||
|
#define EXTERN_C_END
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//#ifdef __cplusplus
|
||||||
|
#if defined(_WIN32) && defined(_MSC_VER)
|
||||||
|
# if !defined(SZIP_STATIC)
|
||||||
|
# if defined(SZIP_EXPORT)
|
||||||
|
# define SZIP_API __declspec(dllexport)
|
||||||
|
# else
|
||||||
|
# define SZIP_API __declspec(dllimport)
|
||||||
|
# endif
|
||||||
|
# else
|
||||||
|
# define SZIP_API
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# define SZIP_API
|
||||||
|
#endif
|
||||||
|
|
||||||
|
EXTERN_C_BEGIN
|
||||||
|
|
||||||
|
#define SZ_OK 0
|
||||||
|
|
||||||
|
#define SZ_ERROR_DATA 1
|
||||||
|
#define SZ_ERROR_MEM 2
|
||||||
|
#define SZ_ERROR_CRC 3
|
||||||
|
#define SZ_ERROR_UNSUPPORTED 4
|
||||||
|
#define SZ_ERROR_PARAM 5
|
||||||
|
#define SZ_ERROR_INPUT_EOF 6
|
||||||
|
#define SZ_ERROR_OUTPUT_EOF 7
|
||||||
|
#define SZ_ERROR_READ 8
|
||||||
|
#define SZ_ERROR_WRITE 9
|
||||||
|
#define SZ_ERROR_PROGRESS 10
|
||||||
|
#define SZ_ERROR_FAIL 11
|
||||||
|
#define SZ_ERROR_THREAD 12
|
||||||
|
|
||||||
|
#define SZ_ERROR_ARCHIVE 16
|
||||||
|
#define SZ_ERROR_NO_ARCHIVE 17
|
||||||
|
|
||||||
|
typedef int SRes;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
typedef DWORD WRes;
|
||||||
|
#else
|
||||||
|
typedef int WRes;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef RINOK
|
||||||
|
#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef unsigned char Byte;
|
||||||
|
typedef short Int16;
|
||||||
|
typedef unsigned short UInt16;
|
||||||
|
|
||||||
|
#ifdef _LZMA_UINT32_IS_ULONG
|
||||||
|
typedef long Int32;
|
||||||
|
typedef unsigned long UInt32;
|
||||||
|
#else
|
||||||
|
typedef int Int32;
|
||||||
|
typedef unsigned int UInt32;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _SZ_NO_INT_64
|
||||||
|
|
||||||
|
/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers.
|
||||||
|
NOTES: Some code will work incorrectly in that case! */
|
||||||
|
|
||||||
|
typedef long Int64;
|
||||||
|
typedef unsigned long UInt64;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||||||
|
typedef __int64 Int64;
|
||||||
|
typedef unsigned __int64 UInt64;
|
||||||
|
#else
|
||||||
|
typedef long long int Int64;
|
||||||
|
typedef unsigned long long int UInt64;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _LZMA_NO_SYSTEM_SIZE_T
|
||||||
|
typedef UInt32 SizeT;
|
||||||
|
#else
|
||||||
|
typedef size_t SizeT;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef int Bool;
|
||||||
|
#define True 1
|
||||||
|
#define False 0
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define MY_STD_CALL __stdcall
|
||||||
|
#else
|
||||||
|
#define MY_STD_CALL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
|
||||||
|
#if _MSC_VER >= 1300
|
||||||
|
#define MY_NO_INLINE __declspec(noinline)
|
||||||
|
#else
|
||||||
|
#define MY_NO_INLINE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MY_CDECL __cdecl
|
||||||
|
#define MY_FAST_CALL __fastcall
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define MY_CDECL
|
||||||
|
#define MY_FAST_CALL
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* The following interfaces use first parameter as pointer to structure */
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */
|
||||||
|
} IByteIn;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
void (*Write)(void *p, Byte b);
|
||||||
|
} IByteOut;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
SRes (*Read)(void *p, void *buf, size_t *size);
|
||||||
|
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
|
||||||
|
(output(*size) < input(*size)) is allowed */
|
||||||
|
} ISeqInStream;
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
size_t (*Write)(void *p, const void *buf, size_t size);
|
||||||
|
/* Returns: result - the number of actually written bytes.
|
||||||
|
(result < size) means error */
|
||||||
|
} ISeqOutStream;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
SZ_SEEK_SET = 0,
|
||||||
|
SZ_SEEK_CUR = 1,
|
||||||
|
SZ_SEEK_END = 2
|
||||||
|
} ESzSeek;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */
|
||||||
|
SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
|
||||||
|
} ISeekInStream;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
SRes (*Look)(void *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);
|
||||||
|
/* offset must be <= output(*size) of Look */
|
||||||
|
|
||||||
|
SRes (*Read)(void *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 LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size);
|
||||||
|
SRes LookInStream_SeekTo(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);
|
||||||
|
|
||||||
|
#define LookToRead_BUF_SIZE (1 << 14)
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ILookInStream s;
|
||||||
|
ISeekInStream *realStream;
|
||||||
|
size_t pos;
|
||||||
|
size_t size;
|
||||||
|
Byte buf[LookToRead_BUF_SIZE];
|
||||||
|
} CLookToRead;
|
||||||
|
|
||||||
|
SZIP_API void LookToRead_CreateVTable(CLookToRead *p, int lookahead);
|
||||||
|
SZIP_API void LookToRead_Init(CLookToRead *p);
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ISeqInStream s;
|
||||||
|
ILookInStream *realStream;
|
||||||
|
} CSecToLook;
|
||||||
|
|
||||||
|
void SecToLook_CreateVTable(CSecToLook *p);
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ISeqInStream s;
|
||||||
|
ILookInStream *realStream;
|
||||||
|
} CSecToRead;
|
||||||
|
|
||||||
|
void SecToRead_CreateVTable(CSecToRead *p);
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize);
|
||||||
|
/* Returns: result. (result != SZ_OK) means break.
|
||||||
|
Value (UInt64)(Int64)-1 for size means unknown value. */
|
||||||
|
} ICompressProgress;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
void *(*Alloc)(void *p, size_t size);
|
||||||
|
void (*Free)(void *p, void *address); /* address can be 0 */
|
||||||
|
} ISzAlloc;
|
||||||
|
|
||||||
|
#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
|
||||||
|
#define IAlloc_Free(p, a) (p)->Free((p), a)
|
||||||
|
|
||||||
|
EXTERN_C_END
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
/* Xz.c - Xz
|
||||||
|
2009-04-15 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#include "7zCrc.h"
|
||||||
|
#include "CpuArch.h"
|
||||||
|
#include "Xz.h"
|
||||||
|
#include "XzCrc64.h"
|
||||||
|
|
||||||
|
Byte XZ_SIG[XZ_SIG_SIZE] = { 0xFD, '7', 'z', 'X', 'Z', 0 };
|
||||||
|
Byte XZ_FOOTER_SIG[XZ_FOOTER_SIG_SIZE] = { 'Y', 'Z' };
|
||||||
|
|
||||||
|
unsigned Xz_WriteVarInt(Byte *buf, UInt64 v)
|
||||||
|
{
|
||||||
|
unsigned i = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
buf[i++] = (Byte)((v & 0x7F) | 0x80);
|
||||||
|
v >>= 7;
|
||||||
|
}
|
||||||
|
while (v != 0);
|
||||||
|
buf[i - 1] &= 0x7F;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Xz_Construct(CXzStream *p)
|
||||||
|
{
|
||||||
|
p->numBlocks = p->numBlocksAllocated = 0;
|
||||||
|
p->blocks = 0;
|
||||||
|
p->flags = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Xz_Free(CXzStream *p, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
alloc->Free(alloc, p->blocks);
|
||||||
|
p->numBlocks = p->numBlocksAllocated = 0;
|
||||||
|
p->blocks = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned XzFlags_GetCheckSize(CXzStreamFlags f)
|
||||||
|
{
|
||||||
|
int t = XzFlags_GetCheckType(f);
|
||||||
|
return (t == 0) ? 0 : (4 << ((t - 1) / 3));
|
||||||
|
}
|
||||||
|
|
||||||
|
void XzCheck_Init(CXzCheck *p, int mode)
|
||||||
|
{
|
||||||
|
p->mode = mode;
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case XZ_CHECK_CRC32: p->crc = CRC_INIT_VAL; break;
|
||||||
|
case XZ_CHECK_CRC64: p->crc64 = CRC64_INIT_VAL; break;
|
||||||
|
case XZ_CHECK_SHA256: Sha256_Init(&p->sha); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void XzCheck_Update(CXzCheck *p, const void *data, size_t size)
|
||||||
|
{
|
||||||
|
switch (p->mode)
|
||||||
|
{
|
||||||
|
case XZ_CHECK_CRC32: p->crc = CrcUpdate(p->crc, data, size); break;
|
||||||
|
case XZ_CHECK_CRC64: p->crc64 = Crc64Update(p->crc64, data, size); break;
|
||||||
|
case XZ_CHECK_SHA256: Sha256_Update(&p->sha, (const Byte *)data, size); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int XzCheck_Final(CXzCheck *p, Byte *digest)
|
||||||
|
{
|
||||||
|
switch (p->mode)
|
||||||
|
{
|
||||||
|
case XZ_CHECK_CRC32:
|
||||||
|
SetUi32(digest, CRC_GET_DIGEST(p->crc));
|
||||||
|
break;
|
||||||
|
case XZ_CHECK_CRC64:
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
UInt64 v = CRC64_GET_DIGEST(p->crc64);
|
||||||
|
for (i = 0; i < 8; i++, v >>= 8)
|
||||||
|
digest[i] = (Byte)(v & 0xFF);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case XZ_CHECK_SHA256:
|
||||||
|
Sha256_Final(&p->sha, digest);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
@@ -0,0 +1,256 @@
|
|||||||
|
/* Xz.h - Xz interface
|
||||||
|
2009-04-15 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#ifndef __XZ_H
|
||||||
|
#define __XZ_H
|
||||||
|
|
||||||
|
#include "Sha256.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define XZ_ID_Subblock 1
|
||||||
|
#define XZ_ID_Delta 3
|
||||||
|
#define XZ_ID_X86 4
|
||||||
|
#define XZ_ID_PPC 5
|
||||||
|
#define XZ_ID_IA64 6
|
||||||
|
#define XZ_ID_ARM 7
|
||||||
|
#define XZ_ID_ARMT 8
|
||||||
|
#define XZ_ID_SPARC 9
|
||||||
|
#define XZ_ID_LZMA2 0x21
|
||||||
|
|
||||||
|
unsigned Xz_ReadVarInt(const Byte *p, size_t maxSize, UInt64 *value);
|
||||||
|
unsigned Xz_WriteVarInt(Byte *buf, UInt64 v);
|
||||||
|
|
||||||
|
/* ---------- xz block ---------- */
|
||||||
|
|
||||||
|
#define XZ_BLOCK_HEADER_SIZE_MAX 1024
|
||||||
|
|
||||||
|
#define XZ_NUM_FILTERS_MAX 4
|
||||||
|
#define XZ_BF_NUM_FILTERS_MASK 3
|
||||||
|
#define XZ_BF_PACK_SIZE (1 << 6)
|
||||||
|
#define XZ_BF_UNPACK_SIZE (1 << 7)
|
||||||
|
|
||||||
|
#define XZ_FILTER_PROPS_SIZE_MAX 20
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
UInt64 id;
|
||||||
|
UInt32 propsSize;
|
||||||
|
Byte props[XZ_FILTER_PROPS_SIZE_MAX];
|
||||||
|
} CXzFilter;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
UInt64 packSize;
|
||||||
|
UInt64 unpackSize;
|
||||||
|
Byte flags;
|
||||||
|
CXzFilter filters[XZ_NUM_FILTERS_MAX];
|
||||||
|
} CXzBlock;
|
||||||
|
|
||||||
|
#define XzBlock_GetNumFilters(p) (((p)->flags & XZ_BF_NUM_FILTERS_MASK) + 1)
|
||||||
|
#define XzBlock_HasPackSize(p) (((p)->flags & XZ_BF_PACK_SIZE) != 0)
|
||||||
|
#define XzBlock_HasUnpackSize(p) (((p)->flags & XZ_BF_UNPACK_SIZE) != 0)
|
||||||
|
|
||||||
|
SRes XzBlock_Parse(CXzBlock *p, const Byte *header);
|
||||||
|
SRes XzBlock_ReadHeader(CXzBlock *p, ISeqInStream *inStream, Bool *isIndex, UInt32 *headerSizeRes);
|
||||||
|
|
||||||
|
/* ---------- xz stream ---------- */
|
||||||
|
|
||||||
|
#define XZ_SIG_SIZE 6
|
||||||
|
#define XZ_FOOTER_SIG_SIZE 2
|
||||||
|
|
||||||
|
extern Byte XZ_SIG[XZ_SIG_SIZE];
|
||||||
|
extern Byte XZ_FOOTER_SIG[XZ_FOOTER_SIG_SIZE];
|
||||||
|
|
||||||
|
#define XZ_STREAM_FLAGS_SIZE 2
|
||||||
|
#define XZ_STREAM_CRC_SIZE 4
|
||||||
|
|
||||||
|
#define XZ_STREAM_HEADER_SIZE (XZ_SIG_SIZE + XZ_STREAM_FLAGS_SIZE + XZ_STREAM_CRC_SIZE)
|
||||||
|
#define XZ_STREAM_FOOTER_SIZE (XZ_FOOTER_SIG_SIZE + XZ_STREAM_FLAGS_SIZE + XZ_STREAM_CRC_SIZE + 4)
|
||||||
|
|
||||||
|
#define XZ_CHECK_MASK 0xF
|
||||||
|
#define XZ_CHECK_NO 0
|
||||||
|
#define XZ_CHECK_CRC32 1
|
||||||
|
#define XZ_CHECK_CRC64 4
|
||||||
|
#define XZ_CHECK_SHA256 10
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int mode;
|
||||||
|
UInt32 crc;
|
||||||
|
UInt64 crc64;
|
||||||
|
CSha256 sha;
|
||||||
|
} CXzCheck;
|
||||||
|
|
||||||
|
void XzCheck_Init(CXzCheck *p, int mode);
|
||||||
|
void XzCheck_Update(CXzCheck *p, const void *data, size_t size);
|
||||||
|
int XzCheck_Final(CXzCheck *p, Byte *digest);
|
||||||
|
|
||||||
|
typedef UInt16 CXzStreamFlags;
|
||||||
|
|
||||||
|
#define XzFlags_IsSupported(f) ((f) <= XZ_CHECK_MASK)
|
||||||
|
#define XzFlags_GetCheckType(f) ((f) & XZ_CHECK_MASK)
|
||||||
|
#define XzFlags_HasDataCrc32(f) (Xz_GetCheckType(f) == XZ_CHECK_CRC32)
|
||||||
|
unsigned XzFlags_GetCheckSize(CXzStreamFlags f);
|
||||||
|
|
||||||
|
SRes Xz_ParseHeader(CXzStreamFlags *p, const Byte *buf);
|
||||||
|
SRes Xz_ReadHeader(CXzStreamFlags *p, ISeqInStream *inStream);
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
UInt64 unpackSize;
|
||||||
|
UInt64 totalSize;
|
||||||
|
} CXzBlockSizes;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
CXzStreamFlags flags;
|
||||||
|
size_t numBlocks;
|
||||||
|
size_t numBlocksAllocated;
|
||||||
|
CXzBlockSizes *blocks;
|
||||||
|
UInt64 startOffset;
|
||||||
|
} CXzStream;
|
||||||
|
|
||||||
|
void Xz_Construct(CXzStream *p);
|
||||||
|
void Xz_Free(CXzStream *p, ISzAlloc *alloc);
|
||||||
|
|
||||||
|
#define XZ_SIZE_OVERFLOW ((UInt64)(Int64)-1)
|
||||||
|
|
||||||
|
UInt64 Xz_GetUnpackSize(const CXzStream *p);
|
||||||
|
UInt64 Xz_GetPackSize(const CXzStream *p);
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
size_t num;
|
||||||
|
size_t numAllocated;
|
||||||
|
CXzStream *streams;
|
||||||
|
} CXzs;
|
||||||
|
|
||||||
|
void Xzs_Construct(CXzs *p);
|
||||||
|
void Xzs_Free(CXzs *p, ISzAlloc *alloc);
|
||||||
|
SRes Xzs_ReadBackward(CXzs *p, ILookInStream *inStream, Int64 *startOffset, ICompressProgress *progress, ISzAlloc *alloc);
|
||||||
|
|
||||||
|
UInt64 Xzs_GetNumBlocks(const CXzs *p);
|
||||||
|
UInt64 Xzs_GetUnpackSize(const CXzs *p);
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
CODER_STATUS_NOT_SPECIFIED, /* use main error code instead */
|
||||||
|
CODER_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */
|
||||||
|
CODER_STATUS_NOT_FINISHED, /* stream was not finished */
|
||||||
|
CODER_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */
|
||||||
|
} ECoderStatus;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
CODER_FINISH_ANY, /* finish at any point */
|
||||||
|
CODER_FINISH_END /* block must be finished at the end */
|
||||||
|
} ECoderFinishMode;
|
||||||
|
|
||||||
|
typedef struct _IStateCoder
|
||||||
|
{
|
||||||
|
void *p;
|
||||||
|
void (*Free)(void *p, ISzAlloc *alloc);
|
||||||
|
SRes (*SetProps)(void *p, const Byte *props, size_t propSize, ISzAlloc *alloc);
|
||||||
|
void (*Init)(void *p);
|
||||||
|
SRes (*Code)(void *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
||||||
|
int srcWasFinished, ECoderFinishMode finishMode, int *wasFinished);
|
||||||
|
} IStateCoder;
|
||||||
|
|
||||||
|
#define MIXCODER_NUM_FILTERS_MAX 4
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ISzAlloc *alloc;
|
||||||
|
Byte *buf;
|
||||||
|
int numCoders;
|
||||||
|
int finished[MIXCODER_NUM_FILTERS_MAX - 1];
|
||||||
|
size_t pos[MIXCODER_NUM_FILTERS_MAX - 1];
|
||||||
|
size_t size[MIXCODER_NUM_FILTERS_MAX - 1];
|
||||||
|
UInt64 ids[MIXCODER_NUM_FILTERS_MAX];
|
||||||
|
IStateCoder coders[MIXCODER_NUM_FILTERS_MAX];
|
||||||
|
} CMixCoder;
|
||||||
|
|
||||||
|
void MixCoder_Construct(CMixCoder *p, ISzAlloc *alloc);
|
||||||
|
void MixCoder_Free(CMixCoder *p);
|
||||||
|
void MixCoder_Init(CMixCoder *p);
|
||||||
|
SRes MixCoder_SetFromMethod(CMixCoder *p, int coderIndex, UInt64 methodId);
|
||||||
|
SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen,
|
||||||
|
const Byte *src, SizeT *srcLen, int srcWasFinished,
|
||||||
|
ECoderFinishMode finishMode, ECoderStatus *status);
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
XZ_STATE_STREAM_HEADER,
|
||||||
|
XZ_STATE_STREAM_INDEX,
|
||||||
|
XZ_STATE_STREAM_INDEX_CRC,
|
||||||
|
XZ_STATE_STREAM_FOOTER,
|
||||||
|
XZ_STATE_STREAM_PADDING,
|
||||||
|
XZ_STATE_BLOCK_HEADER,
|
||||||
|
XZ_STATE_BLOCK,
|
||||||
|
XZ_STATE_BLOCK_FOOTER
|
||||||
|
} EXzState;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
EXzState state;
|
||||||
|
UInt32 pos;
|
||||||
|
unsigned alignPos;
|
||||||
|
unsigned indexPreSize;
|
||||||
|
|
||||||
|
CXzStreamFlags streamFlags;
|
||||||
|
|
||||||
|
UInt32 blockHeaderSize;
|
||||||
|
UInt64 packSize;
|
||||||
|
UInt64 unpackSize;
|
||||||
|
|
||||||
|
UInt64 numBlocks;
|
||||||
|
UInt64 indexSize;
|
||||||
|
UInt64 indexPos;
|
||||||
|
UInt64 padSize;
|
||||||
|
|
||||||
|
UInt64 numStreams;
|
||||||
|
|
||||||
|
UInt32 crc;
|
||||||
|
CMixCoder decoder;
|
||||||
|
CXzBlock block;
|
||||||
|
CXzCheck check;
|
||||||
|
CSha256 sha;
|
||||||
|
Byte shaDigest[SHA256_DIGEST_SIZE];
|
||||||
|
Byte buf[XZ_BLOCK_HEADER_SIZE_MAX];
|
||||||
|
} CXzUnpacker;
|
||||||
|
|
||||||
|
SRes XzUnpacker_Create(CXzUnpacker *p, ISzAlloc *alloc);
|
||||||
|
void XzUnpacker_Free(CXzUnpacker *p);
|
||||||
|
|
||||||
|
/*
|
||||||
|
finishMode:
|
||||||
|
It has meaning only if the decoding reaches output limit (*destLen).
|
||||||
|
LZMA_FINISH_ANY - use smallest number of input bytes
|
||||||
|
LZMA_FINISH_END - read EndOfStream marker after decoding
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
SZ_OK
|
||||||
|
status:
|
||||||
|
LZMA_STATUS_FINISHED_WITH_MARK
|
||||||
|
LZMA_STATUS_NOT_FINISHED
|
||||||
|
SZ_ERROR_DATA - Data error
|
||||||
|
SZ_ERROR_MEM - Memory allocation error
|
||||||
|
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
||||||
|
SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,
|
||||||
|
const Byte *src, SizeT *srcLen, /* int srcWasFinished, */ int finishMode,
|
||||||
|
ECoderStatus *status);
|
||||||
|
|
||||||
|
Bool XzUnpacker_IsStreamWasFinished(CXzUnpacker *p);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
/* XzCrc64.c -- CRC64 calculation
|
||||||
|
2009-04-15 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#include "XzCrc64.h"
|
||||||
|
|
||||||
|
#define kCrc64Poly 0xC96C5795D7870F42
|
||||||
|
UInt64 g_Crc64Table[256];
|
||||||
|
|
||||||
|
void MY_FAST_CALL Crc64GenerateTable(void)
|
||||||
|
{
|
||||||
|
UInt32 i;
|
||||||
|
for (i = 0; i < 256; i++)
|
||||||
|
{
|
||||||
|
UInt64 r = i;
|
||||||
|
int j;
|
||||||
|
for (j = 0; j < 8; j++)
|
||||||
|
r = (r >> 1) ^ ((UInt64)kCrc64Poly & ~((r & 1) - 1));
|
||||||
|
g_Crc64Table[i] = r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt64 MY_FAST_CALL Crc64Update(UInt64 v, const void *data, size_t size)
|
||||||
|
{
|
||||||
|
const Byte *p = (const Byte *)data;
|
||||||
|
for (; size > 0 ; size--, p++)
|
||||||
|
v = CRC64_UPDATE_BYTE(v, *p);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt64 MY_FAST_CALL Crc64Calc(const void *data, size_t size)
|
||||||
|
{
|
||||||
|
return CRC64_GET_DIGEST(Crc64Update(CRC64_INIT_VAL, data, size));
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
/* XzCrc64.c -- CRC64 calculation
|
||||||
|
2009-04-15 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#ifndef __XZ_CRC64_H
|
||||||
|
#define __XZ_CRC64_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include "Types.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern UInt64 g_Crc64Table[];
|
||||||
|
|
||||||
|
void MY_FAST_CALL Crc64GenerateTable(void);
|
||||||
|
|
||||||
|
#define CRC64_INIT_VAL 0xFFFFFFFFFFFFFFFF
|
||||||
|
#define CRC64_GET_DIGEST(crc) ((crc) ^ 0xFFFFFFFFFFFFFFFF)
|
||||||
|
#define CRC64_UPDATE_BYTE(crc, b) (g_Crc64Table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
|
||||||
|
|
||||||
|
UInt64 MY_FAST_CALL Crc64Update(UInt64 crc, const void *data, size_t size);
|
||||||
|
UInt64 MY_FAST_CALL Crc64Calc(const void *data, size_t size);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,873 @@
|
|||||||
|
/* XzDec.c -- Xz Decode
|
||||||
|
2009-06-08 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
/* #define XZ_DUMP */
|
||||||
|
|
||||||
|
#ifdef XZ_DUMP
|
||||||
|
#include <stdio.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "7zCrc.h"
|
||||||
|
#include "Alloc.h"
|
||||||
|
#include "Bra.h"
|
||||||
|
#include "CpuArch.h"
|
||||||
|
#include "Delta.h"
|
||||||
|
#include "Lzma2Dec.h"
|
||||||
|
|
||||||
|
#ifdef USE_SUBBLOCK
|
||||||
|
#include "SbDec.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "Xz.h"
|
||||||
|
|
||||||
|
#define XZ_CHECK_SIZE_MAX 64
|
||||||
|
|
||||||
|
#define CODER_BUF_SIZE (1 << 17)
|
||||||
|
|
||||||
|
unsigned Xz_ReadVarInt(const Byte *p, size_t maxSize, UInt64 *value)
|
||||||
|
{
|
||||||
|
int i, limit;
|
||||||
|
*value = 0;
|
||||||
|
limit = (maxSize > 9) ? 9 : (int)maxSize;
|
||||||
|
|
||||||
|
for (i = 0; i < limit;)
|
||||||
|
{
|
||||||
|
Byte b = p[i];
|
||||||
|
*value |= (UInt64)(b & 0x7F) << (7 * i++);
|
||||||
|
if ((b & 0x80) == 0)
|
||||||
|
return (b == 0 && i != 1) ? 0 : i;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------- BraState ---------- */
|
||||||
|
|
||||||
|
#define BRA_BUF_SIZE (1 << 14)
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
size_t bufPos;
|
||||||
|
size_t bufConv;
|
||||||
|
size_t bufTotal;
|
||||||
|
|
||||||
|
UInt32 methodId;
|
||||||
|
int encodeMode;
|
||||||
|
UInt32 delta;
|
||||||
|
UInt32 ip;
|
||||||
|
UInt32 x86State;
|
||||||
|
Byte deltaState[DELTA_STATE_SIZE];
|
||||||
|
|
||||||
|
Byte buf[BRA_BUF_SIZE];
|
||||||
|
} CBraState;
|
||||||
|
|
||||||
|
void BraState_Free(void *pp, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
alloc->Free(alloc, pp);
|
||||||
|
}
|
||||||
|
|
||||||
|
SRes BraState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
CBraState *p = ((CBraState *)pp);
|
||||||
|
alloc = alloc;
|
||||||
|
p->encodeMode = 0;
|
||||||
|
p->ip = 0;
|
||||||
|
if (p->methodId == XZ_ID_Delta)
|
||||||
|
{
|
||||||
|
if (propSize != 1)
|
||||||
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
|
p->delta = (unsigned)props[0] + 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (propSize == 4)
|
||||||
|
{
|
||||||
|
UInt32 v = GetUi32(props);
|
||||||
|
switch(p->methodId)
|
||||||
|
{
|
||||||
|
case XZ_ID_PPC:
|
||||||
|
case XZ_ID_ARM:
|
||||||
|
case XZ_ID_SPARC:
|
||||||
|
if ((v & 3) != 0)
|
||||||
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
|
break;
|
||||||
|
case XZ_ID_ARMT:
|
||||||
|
if ((v & 1) != 0)
|
||||||
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
|
break;
|
||||||
|
case XZ_ID_IA64:
|
||||||
|
if ((v & 0xF) != 0)
|
||||||
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
p->ip = v;
|
||||||
|
}
|
||||||
|
else if (propSize != 0)
|
||||||
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BraState_Init(void *pp)
|
||||||
|
{
|
||||||
|
CBraState *p = ((CBraState *)pp);
|
||||||
|
p->bufPos = p->bufConv = p->bufTotal = 0;
|
||||||
|
x86_Convert_Init(p->x86State);
|
||||||
|
if (p->methodId == XZ_ID_Delta)
|
||||||
|
Delta_Init(p->deltaState);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CASE_BRA_CONV(isa) case XZ_ID_ ## isa: p->bufConv = isa ## _Convert(p->buf, p->bufTotal, p->ip, p->encodeMode); break;
|
||||||
|
|
||||||
|
static SRes BraState_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
||||||
|
int srcWasFinished, ECoderFinishMode finishMode, int *wasFinished)
|
||||||
|
{
|
||||||
|
CBraState *p = ((CBraState *)pp);
|
||||||
|
SizeT destLenOrig = *destLen;
|
||||||
|
SizeT srcLenOrig = *srcLen;
|
||||||
|
*destLen = 0;
|
||||||
|
*srcLen = 0;
|
||||||
|
finishMode = finishMode;
|
||||||
|
*wasFinished = 0;
|
||||||
|
while (destLenOrig > 0)
|
||||||
|
{
|
||||||
|
if (p->bufPos != p->bufConv)
|
||||||
|
{
|
||||||
|
size_t curSize = p->bufConv - p->bufPos;
|
||||||
|
if (curSize > destLenOrig)
|
||||||
|
curSize = destLenOrig;
|
||||||
|
memcpy(dest, p->buf + p->bufPos, curSize);
|
||||||
|
p->bufPos += curSize;
|
||||||
|
*destLen += curSize;
|
||||||
|
dest += curSize;
|
||||||
|
destLenOrig -= curSize;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
p->bufTotal -= p->bufPos;
|
||||||
|
memmove(p->buf, p->buf + p->bufPos, p->bufTotal);
|
||||||
|
p->bufPos = 0;
|
||||||
|
p->bufConv = 0;
|
||||||
|
{
|
||||||
|
size_t curSize = BRA_BUF_SIZE - p->bufTotal;
|
||||||
|
if (curSize > srcLenOrig)
|
||||||
|
curSize = srcLenOrig;
|
||||||
|
memcpy(p->buf + p->bufTotal, src, curSize);
|
||||||
|
*srcLen += curSize;
|
||||||
|
src += curSize;
|
||||||
|
srcLenOrig -= curSize;
|
||||||
|
p->bufTotal += curSize;
|
||||||
|
}
|
||||||
|
if (p->bufTotal == 0)
|
||||||
|
break;
|
||||||
|
switch(p->methodId)
|
||||||
|
{
|
||||||
|
case XZ_ID_Delta:
|
||||||
|
if (p->encodeMode)
|
||||||
|
Delta_Encode(p->deltaState, p->delta, p->buf, p->bufTotal);
|
||||||
|
else
|
||||||
|
Delta_Decode(p->deltaState, p->delta, p->buf, p->bufTotal);
|
||||||
|
p->bufConv = p->bufTotal;
|
||||||
|
break;
|
||||||
|
case XZ_ID_X86:
|
||||||
|
p->bufConv = x86_Convert(p->buf, p->bufTotal, p->ip, &p->x86State, p->encodeMode);
|
||||||
|
break;
|
||||||
|
CASE_BRA_CONV(PPC)
|
||||||
|
CASE_BRA_CONV(IA64)
|
||||||
|
CASE_BRA_CONV(ARM)
|
||||||
|
CASE_BRA_CONV(ARMT)
|
||||||
|
CASE_BRA_CONV(SPARC)
|
||||||
|
default:
|
||||||
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
p->ip += (UInt32)p->bufConv;
|
||||||
|
|
||||||
|
if (p->bufConv == 0)
|
||||||
|
{
|
||||||
|
if (!srcWasFinished)
|
||||||
|
break;
|
||||||
|
p->bufConv = p->bufTotal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (p->bufTotal == p->bufPos && srcLenOrig == 0 && srcWasFinished)
|
||||||
|
*wasFinished = 1;
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
CBraState *decoder;
|
||||||
|
if (id != XZ_ID_Delta &&
|
||||||
|
id != XZ_ID_X86 &&
|
||||||
|
id != XZ_ID_PPC &&
|
||||||
|
id != XZ_ID_IA64 &&
|
||||||
|
id != XZ_ID_ARM &&
|
||||||
|
id != XZ_ID_ARMT &&
|
||||||
|
id != XZ_ID_SPARC)
|
||||||
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
|
p->p = 0;
|
||||||
|
decoder = alloc->Alloc(alloc, sizeof(CBraState));
|
||||||
|
if (decoder == 0)
|
||||||
|
return SZ_ERROR_MEM;
|
||||||
|
decoder->methodId = (UInt32)id;
|
||||||
|
p->p = decoder;
|
||||||
|
p->Free = BraState_Free;
|
||||||
|
p->SetProps = BraState_SetProps;
|
||||||
|
p->Init = BraState_Init;
|
||||||
|
p->Code = BraState_Code;
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------- SbState ---------- */
|
||||||
|
|
||||||
|
#ifdef USE_SUBBLOCK
|
||||||
|
|
||||||
|
static void SbState_Free(void *pp, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
CSubblockDec *p = (CSubblockDec *)pp;
|
||||||
|
SubblockDec_Free(p, alloc);
|
||||||
|
alloc->Free(alloc, pp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static SRes SbState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
pp = pp;
|
||||||
|
props = props;
|
||||||
|
alloc = alloc;
|
||||||
|
return (propSize == 0) ? SZ_OK : SZ_ERROR_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SbState_Init(void *pp)
|
||||||
|
{
|
||||||
|
SubblockDec_Init((CSubblockDec *)pp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static SRes SbState_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
||||||
|
int srcWasFinished, ECoderFinishMode finishMode, int *wasFinished)
|
||||||
|
{
|
||||||
|
ECoderStatus status;
|
||||||
|
SRes res = SubblockDec_Decode((CSubblockDec *)pp, dest, destLen, src, srcLen, finishMode, &status);
|
||||||
|
srcWasFinished = srcWasFinished;
|
||||||
|
*wasFinished = (status == LZMA_STATUS_FINISHED_WITH_MARK);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
SRes SbState_SetFromMethod(IStateCoder *p, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
CSubblockDec *decoder;
|
||||||
|
p->p = 0;
|
||||||
|
decoder = alloc->Alloc(alloc, sizeof(CSubblockDec));
|
||||||
|
if (decoder == 0)
|
||||||
|
return SZ_ERROR_MEM;
|
||||||
|
p->p = decoder;
|
||||||
|
p->Free = SbState_Free;
|
||||||
|
p->SetProps = SbState_SetProps;
|
||||||
|
p->Init = SbState_Init;
|
||||||
|
p->Code = SbState_Code;
|
||||||
|
SubblockDec_Construct(decoder);
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ---------- Lzma2State ---------- */
|
||||||
|
|
||||||
|
static void Lzma2State_Free(void *pp, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
Lzma2Dec_Free((CLzma2Dec *)pp, alloc);
|
||||||
|
alloc->Free(alloc, pp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static SRes Lzma2State_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
if (propSize != 1)
|
||||||
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
|
return Lzma2Dec_Allocate((CLzma2Dec *)pp, props[0], alloc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Lzma2State_Init(void *pp)
|
||||||
|
{
|
||||||
|
Lzma2Dec_Init((CLzma2Dec *)pp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static SRes Lzma2State_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
||||||
|
int srcWasFinished, ECoderFinishMode finishMode, int *wasFinished)
|
||||||
|
{
|
||||||
|
ELzmaStatus status;
|
||||||
|
/* ELzmaFinishMode fm = (finishMode == LZMA_FINISH_ANY) ? LZMA_FINISH_ANY : LZMA_FINISH_END; */
|
||||||
|
SRes res = Lzma2Dec_DecodeToBuf((CLzma2Dec *)pp, dest, destLen, src, srcLen, finishMode, &status);
|
||||||
|
srcWasFinished = srcWasFinished;
|
||||||
|
*wasFinished = (status == LZMA_STATUS_FINISHED_WITH_MARK);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SRes Lzma2State_SetFromMethod(IStateCoder *p, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
CLzma2Dec *decoder = alloc->Alloc(alloc, sizeof(CLzma2Dec));
|
||||||
|
p->p = decoder;
|
||||||
|
if (decoder == 0)
|
||||||
|
return SZ_ERROR_MEM;
|
||||||
|
p->Free = Lzma2State_Free;
|
||||||
|
p->SetProps = Lzma2State_SetProps;
|
||||||
|
p->Init = Lzma2State_Init;
|
||||||
|
p->Code = Lzma2State_Code;
|
||||||
|
Lzma2Dec_Construct(decoder);
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MixCoder_Construct(CMixCoder *p, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
p->alloc = alloc;
|
||||||
|
p->buf = 0;
|
||||||
|
p->numCoders = 0;
|
||||||
|
for (i = 0; i < MIXCODER_NUM_FILTERS_MAX; i++)
|
||||||
|
p->coders[i].p = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MixCoder_Free(CMixCoder *p)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < p->numCoders; i++)
|
||||||
|
{
|
||||||
|
IStateCoder *sc = &p->coders[i];
|
||||||
|
if (p->alloc && sc->p)
|
||||||
|
sc->Free(sc->p, p->alloc);
|
||||||
|
}
|
||||||
|
p->numCoders = 0;
|
||||||
|
if (p->buf)
|
||||||
|
p->alloc->Free(p->alloc, p->buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MixCoder_Init(CMixCoder *p)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < p->numCoders - 1; i++)
|
||||||
|
{
|
||||||
|
p->size[i] = 0;
|
||||||
|
p->pos[i] = 0;
|
||||||
|
p->finished[i] = 0;
|
||||||
|
}
|
||||||
|
for (i = 0; i < p->numCoders; i++)
|
||||||
|
{
|
||||||
|
IStateCoder *coder = &p->coders[i];
|
||||||
|
coder->Init(coder->p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SRes MixCoder_SetFromMethod(CMixCoder *p, int coderIndex, UInt64 methodId)
|
||||||
|
{
|
||||||
|
IStateCoder *sc = &p->coders[coderIndex];
|
||||||
|
p->ids[coderIndex] = methodId;
|
||||||
|
switch(methodId)
|
||||||
|
{
|
||||||
|
case XZ_ID_LZMA2: return Lzma2State_SetFromMethod(sc, p->alloc);
|
||||||
|
#ifdef USE_SUBBLOCK
|
||||||
|
case XZ_ID_Subblock: return SbState_SetFromMethod(sc, p->alloc);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (coderIndex == 0)
|
||||||
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
|
return BraState_SetFromMethod(sc, methodId, p->alloc);
|
||||||
|
}
|
||||||
|
|
||||||
|
SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen,
|
||||||
|
const Byte *src, SizeT *srcLen, int srcWasFinished,
|
||||||
|
ECoderFinishMode finishMode, ECoderStatus *status)
|
||||||
|
{
|
||||||
|
SizeT destLenOrig = *destLen;
|
||||||
|
SizeT srcLenOrig = *srcLen;
|
||||||
|
Bool allFinished = True;
|
||||||
|
*destLen = 0;
|
||||||
|
*srcLen = 0;
|
||||||
|
*status = CODER_STATUS_NOT_FINISHED;
|
||||||
|
|
||||||
|
if (p->buf == 0)
|
||||||
|
{
|
||||||
|
p->buf = p->alloc->Alloc(p->alloc, CODER_BUF_SIZE * (MIXCODER_NUM_FILTERS_MAX - 1));
|
||||||
|
if (p->buf == 0)
|
||||||
|
return SZ_ERROR_MEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p->numCoders != 1)
|
||||||
|
finishMode = CODER_FINISH_ANY;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
Bool processed = False;
|
||||||
|
int i;
|
||||||
|
/*
|
||||||
|
if (p->numCoders == 1 && *destLen == destLenOrig && finishMode == LZMA_FINISH_ANY)
|
||||||
|
break;
|
||||||
|
*/
|
||||||
|
|
||||||
|
for (i = 0; i < p->numCoders; i++)
|
||||||
|
{
|
||||||
|
SRes res;
|
||||||
|
IStateCoder *coder = &p->coders[i];
|
||||||
|
Byte *destCur;
|
||||||
|
SizeT destLenCur, srcLenCur;
|
||||||
|
const Byte *srcCur;
|
||||||
|
int srcFinishedCur;
|
||||||
|
int encodingWasFinished;
|
||||||
|
|
||||||
|
if (i == 0)
|
||||||
|
{
|
||||||
|
srcCur = src;
|
||||||
|
srcLenCur = srcLenOrig - *srcLen;
|
||||||
|
srcFinishedCur = srcWasFinished;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
srcCur = p->buf + (CODER_BUF_SIZE * (i - 1)) + p->pos[i - 1];
|
||||||
|
srcLenCur = p->size[i - 1] - p->pos[i - 1];
|
||||||
|
srcFinishedCur = p->finished[i - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == p->numCoders - 1)
|
||||||
|
{
|
||||||
|
destCur = dest;
|
||||||
|
destLenCur = destLenOrig - *destLen;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (p->pos[i] != p->size[i])
|
||||||
|
continue;
|
||||||
|
destCur = p->buf + (CODER_BUF_SIZE * i);
|
||||||
|
destLenCur = CODER_BUF_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = coder->Code(coder->p, destCur, &destLenCur, srcCur, &srcLenCur, srcFinishedCur, finishMode, &encodingWasFinished);
|
||||||
|
|
||||||
|
if (!encodingWasFinished)
|
||||||
|
allFinished = False;
|
||||||
|
|
||||||
|
if (i == 0)
|
||||||
|
{
|
||||||
|
*srcLen += srcLenCur;
|
||||||
|
src += srcLenCur;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p->pos[i - 1] += srcLenCur;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == p->numCoders - 1)
|
||||||
|
{
|
||||||
|
*destLen += destLenCur;
|
||||||
|
dest += destLenCur;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p->size[i] = destLenCur;
|
||||||
|
p->pos[i] = 0;
|
||||||
|
p->finished[i] = encodingWasFinished;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res != SZ_OK)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
if (destLenCur != 0 || srcLenCur != 0)
|
||||||
|
processed = True;
|
||||||
|
}
|
||||||
|
if (!processed)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (allFinished)
|
||||||
|
*status = CODER_STATUS_FINISHED_WITH_MARK;
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
SRes Xz_ParseHeader(CXzStreamFlags *p, const Byte *buf)
|
||||||
|
{
|
||||||
|
*p = (CXzStreamFlags)GetBe16(buf + XZ_SIG_SIZE);
|
||||||
|
if (CrcCalc(buf + XZ_SIG_SIZE, XZ_STREAM_FLAGS_SIZE) !=
|
||||||
|
GetUi32(buf + XZ_SIG_SIZE + XZ_STREAM_FLAGS_SIZE))
|
||||||
|
return SZ_ERROR_NO_ARCHIVE;
|
||||||
|
return XzFlags_IsSupported(*p) ? SZ_OK : SZ_ERROR_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Bool Xz_CheckFooter(CXzStreamFlags flags, UInt64 indexSize, const Byte *buf)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
indexSize == (((UInt64)GetUi32(buf + 4) + 1) << 2) &&
|
||||||
|
(GetUi32(buf) == CrcCalc(buf + 4, 6) &&
|
||||||
|
flags == GetBe16(buf + 8) &&
|
||||||
|
memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define READ_VARINT_AND_CHECK(buf, pos, size, res) \
|
||||||
|
{ unsigned s = Xz_ReadVarInt(buf + pos, size - pos, res); \
|
||||||
|
if (s == 0) return SZ_ERROR_ARCHIVE; pos += s; }
|
||||||
|
|
||||||
|
|
||||||
|
SRes XzBlock_Parse(CXzBlock *p, const Byte *header)
|
||||||
|
{
|
||||||
|
unsigned pos;
|
||||||
|
int numFilters, i;
|
||||||
|
UInt32 headerSize = (UInt32)header[0] << 2;
|
||||||
|
|
||||||
|
if (CrcCalc(header, headerSize) != GetUi32(header + headerSize))
|
||||||
|
return SZ_ERROR_ARCHIVE;
|
||||||
|
|
||||||
|
pos = 1;
|
||||||
|
if (pos == headerSize)
|
||||||
|
return SZ_ERROR_ARCHIVE;
|
||||||
|
p->flags = header[pos++];
|
||||||
|
|
||||||
|
if (XzBlock_HasPackSize(p))
|
||||||
|
{
|
||||||
|
READ_VARINT_AND_CHECK(header, pos, headerSize, &p->packSize);
|
||||||
|
if (p->packSize == 0 || p->packSize + headerSize >= (UInt64)1 << 63)
|
||||||
|
return SZ_ERROR_ARCHIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (XzBlock_HasUnpackSize(p))
|
||||||
|
READ_VARINT_AND_CHECK(header, pos, headerSize, &p->unpackSize);
|
||||||
|
|
||||||
|
numFilters = XzBlock_GetNumFilters(p);
|
||||||
|
for (i = 0; i < numFilters; i++)
|
||||||
|
{
|
||||||
|
CXzFilter *filter = p->filters + i;
|
||||||
|
UInt64 size;
|
||||||
|
READ_VARINT_AND_CHECK(header, pos, headerSize, &filter->id);
|
||||||
|
READ_VARINT_AND_CHECK(header, pos, headerSize, &size);
|
||||||
|
if (size > headerSize - pos || size > XZ_FILTER_PROPS_SIZE_MAX)
|
||||||
|
return SZ_ERROR_ARCHIVE;
|
||||||
|
filter->propsSize = (UInt32)size;
|
||||||
|
memcpy(filter->props, header + pos, (size_t)size);
|
||||||
|
pos += (unsigned)size;
|
||||||
|
|
||||||
|
#ifdef XZ_DUMP
|
||||||
|
printf("\nf[%d] = %2X: ", i, filter->id);
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < size; i++)
|
||||||
|
printf(" %2X", filter->props[i]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
while (pos < headerSize)
|
||||||
|
if (header[pos++] != 0)
|
||||||
|
return SZ_ERROR_ARCHIVE;
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
SRes XzDec_Init(CMixCoder *p, const CXzBlock *block)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
Bool needReInit = True;
|
||||||
|
int numFilters = XzBlock_GetNumFilters(block);
|
||||||
|
if (numFilters == p->numCoders)
|
||||||
|
{
|
||||||
|
for (i = 0; i < numFilters; i++)
|
||||||
|
if (p->ids[i] != block->filters[numFilters - 1 - i].id)
|
||||||
|
break;
|
||||||
|
needReInit = (i != numFilters);
|
||||||
|
}
|
||||||
|
if (needReInit)
|
||||||
|
{
|
||||||
|
MixCoder_Free(p);
|
||||||
|
p->numCoders = numFilters;
|
||||||
|
for (i = 0; i < numFilters; i++)
|
||||||
|
{
|
||||||
|
const CXzFilter *f = &block->filters[numFilters - 1 - i];
|
||||||
|
RINOK(MixCoder_SetFromMethod(p, i, f->id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i = 0; i < numFilters; i++)
|
||||||
|
{
|
||||||
|
const CXzFilter *f = &block->filters[numFilters - 1 - i];
|
||||||
|
IStateCoder *sc = &p->coders[i];
|
||||||
|
RINOK(sc->SetProps(sc->p, f->props, f->propsSize, p->alloc));
|
||||||
|
}
|
||||||
|
MixCoder_Init(p);
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
SRes XzUnpacker_Create(CXzUnpacker *p, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
MixCoder_Construct(&p->decoder, alloc);
|
||||||
|
p->state = XZ_STATE_STREAM_HEADER;
|
||||||
|
p->pos = 0;
|
||||||
|
p->numStreams = 0;
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void XzUnpacker_Free(CXzUnpacker *p)
|
||||||
|
{
|
||||||
|
MixCoder_Free(&p->decoder);
|
||||||
|
}
|
||||||
|
|
||||||
|
SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,
|
||||||
|
const Byte *src, SizeT *srcLen, int finishMode, ECoderStatus *status)
|
||||||
|
{
|
||||||
|
SizeT destLenOrig = *destLen;
|
||||||
|
SizeT srcLenOrig = *srcLen;
|
||||||
|
*destLen = 0;
|
||||||
|
*srcLen = 0;
|
||||||
|
*status = CODER_STATUS_NOT_SPECIFIED;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
SizeT srcRem = srcLenOrig - *srcLen;
|
||||||
|
|
||||||
|
if (p->state == XZ_STATE_BLOCK)
|
||||||
|
{
|
||||||
|
SizeT destLen2 = destLenOrig - *destLen;
|
||||||
|
SizeT srcLen2 = srcLenOrig - *srcLen;
|
||||||
|
SRes res;
|
||||||
|
if (srcLen2 == 0 && destLen2 == 0)
|
||||||
|
{
|
||||||
|
*status = CODER_STATUS_NOT_FINISHED;
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = MixCoder_Code(&p->decoder, dest, &destLen2, src, &srcLen2, False, finishMode, status);
|
||||||
|
XzCheck_Update(&p->check, dest, destLen2);
|
||||||
|
|
||||||
|
(*srcLen) += srcLen2;
|
||||||
|
src += srcLen2;
|
||||||
|
p->packSize += srcLen2;
|
||||||
|
|
||||||
|
(*destLen) += destLen2;
|
||||||
|
dest += destLen2;
|
||||||
|
p->unpackSize += destLen2;
|
||||||
|
|
||||||
|
RINOK(res);
|
||||||
|
|
||||||
|
if (*status == CODER_STATUS_FINISHED_WITH_MARK)
|
||||||
|
{
|
||||||
|
Byte temp[32];
|
||||||
|
unsigned num = Xz_WriteVarInt(temp, p->packSize + p->blockHeaderSize + XzFlags_GetCheckSize(p->streamFlags));
|
||||||
|
num += Xz_WriteVarInt(temp + num, p->unpackSize);
|
||||||
|
Sha256_Update(&p->sha, temp, num);
|
||||||
|
p->indexSize += num;
|
||||||
|
p->numBlocks++;
|
||||||
|
|
||||||
|
p->state = XZ_STATE_BLOCK_FOOTER;
|
||||||
|
p->pos = 0;
|
||||||
|
p->alignPos = 0;
|
||||||
|
}
|
||||||
|
else if (srcLen2 == 0 && destLen2 == 0)
|
||||||
|
return SZ_OK;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (srcRem == 0)
|
||||||
|
{
|
||||||
|
*status = CODER_STATUS_NEEDS_MORE_INPUT;
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(p->state)
|
||||||
|
{
|
||||||
|
case XZ_STATE_STREAM_HEADER:
|
||||||
|
{
|
||||||
|
if (p->pos < XZ_STREAM_HEADER_SIZE)
|
||||||
|
{
|
||||||
|
if (p->pos < XZ_SIG_SIZE && *src != XZ_SIG[p->pos])
|
||||||
|
return SZ_ERROR_NO_ARCHIVE;
|
||||||
|
p->buf[p->pos++] = *src++;
|
||||||
|
(*srcLen)++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RINOK(Xz_ParseHeader(&p->streamFlags, p->buf));
|
||||||
|
p->state = XZ_STATE_BLOCK_HEADER;
|
||||||
|
Sha256_Init(&p->sha);
|
||||||
|
p->indexSize = 0;
|
||||||
|
p->numBlocks = 0;
|
||||||
|
p->pos = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case XZ_STATE_BLOCK_HEADER:
|
||||||
|
{
|
||||||
|
if (p->pos == 0)
|
||||||
|
{
|
||||||
|
p->buf[p->pos++] = *src++;
|
||||||
|
(*srcLen)++;
|
||||||
|
if (p->buf[0] == 0)
|
||||||
|
{
|
||||||
|
p->indexPreSize = 1 + Xz_WriteVarInt(p->buf + 1, p->numBlocks);
|
||||||
|
p->indexPos = p->indexPreSize;
|
||||||
|
p->indexSize += p->indexPreSize;
|
||||||
|
Sha256_Final(&p->sha, p->shaDigest);
|
||||||
|
Sha256_Init(&p->sha);
|
||||||
|
p->crc = CrcUpdate(CRC_INIT_VAL, p->buf, p->indexPreSize);
|
||||||
|
p->state = XZ_STATE_STREAM_INDEX;
|
||||||
|
}
|
||||||
|
p->blockHeaderSize = ((UInt32)p->buf[0] << 2) + 4;
|
||||||
|
}
|
||||||
|
else if (p->pos != p->blockHeaderSize)
|
||||||
|
{
|
||||||
|
UInt32 cur = p->blockHeaderSize - p->pos;
|
||||||
|
if (cur > srcRem)
|
||||||
|
cur = (UInt32)srcRem;
|
||||||
|
memcpy(p->buf + p->pos, src, cur);
|
||||||
|
p->pos += cur;
|
||||||
|
(*srcLen) += cur;
|
||||||
|
src += cur;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RINOK(XzBlock_Parse(&p->block, p->buf));
|
||||||
|
p->state = XZ_STATE_BLOCK;
|
||||||
|
p->packSize = 0;
|
||||||
|
p->unpackSize = 0;
|
||||||
|
XzCheck_Init(&p->check, XzFlags_GetCheckType(p->streamFlags));
|
||||||
|
RINOK(XzDec_Init(&p->decoder, &p->block));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case XZ_STATE_BLOCK_FOOTER:
|
||||||
|
{
|
||||||
|
if (((p->packSize + p->alignPos) & 3) != 0)
|
||||||
|
{
|
||||||
|
(*srcLen)++;
|
||||||
|
p->alignPos++;
|
||||||
|
if (*src++ != 0)
|
||||||
|
return SZ_ERROR_CRC;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UInt32 checkSize = XzFlags_GetCheckSize(p->streamFlags);
|
||||||
|
UInt32 cur = checkSize - p->pos;
|
||||||
|
if (cur != 0)
|
||||||
|
{
|
||||||
|
if (cur > srcRem)
|
||||||
|
cur = (UInt32)srcRem;
|
||||||
|
memcpy(p->buf + p->pos, src, cur);
|
||||||
|
p->pos += cur;
|
||||||
|
(*srcLen) += cur;
|
||||||
|
src += cur;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Byte digest[XZ_CHECK_SIZE_MAX];
|
||||||
|
p->state = XZ_STATE_BLOCK_HEADER;
|
||||||
|
p->pos = 0;
|
||||||
|
if (XzCheck_Final(&p->check, digest) && memcmp(digest, p->buf, checkSize) != 0)
|
||||||
|
return SZ_ERROR_CRC;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case XZ_STATE_STREAM_INDEX:
|
||||||
|
{
|
||||||
|
if (p->pos < p->indexPreSize)
|
||||||
|
{
|
||||||
|
(*srcLen)++;
|
||||||
|
if (*src++ != p->buf[p->pos++])
|
||||||
|
return SZ_ERROR_CRC;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (p->indexPos < p->indexSize)
|
||||||
|
{
|
||||||
|
UInt64 cur = p->indexSize - p->indexPos;
|
||||||
|
if (srcRem > cur)
|
||||||
|
srcRem = (SizeT)cur;
|
||||||
|
p->crc = CrcUpdate(p->crc, src, srcRem);
|
||||||
|
Sha256_Update(&p->sha, src, srcRem);
|
||||||
|
(*srcLen) += srcRem;
|
||||||
|
src += srcRem;
|
||||||
|
p->indexPos += srcRem;
|
||||||
|
}
|
||||||
|
else if ((p->indexPos & 3) != 0)
|
||||||
|
{
|
||||||
|
Byte b = *src++;
|
||||||
|
p->crc = CRC_UPDATE_BYTE(p->crc, b);
|
||||||
|
(*srcLen)++;
|
||||||
|
p->indexPos++;
|
||||||
|
p->indexSize++;
|
||||||
|
if (b != 0)
|
||||||
|
return SZ_ERROR_CRC;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Byte digest[SHA256_DIGEST_SIZE];
|
||||||
|
p->state = XZ_STATE_STREAM_INDEX_CRC;
|
||||||
|
p->indexSize += 4;
|
||||||
|
p->pos = 0;
|
||||||
|
Sha256_Final(&p->sha, digest);
|
||||||
|
if (memcmp(digest, p->shaDigest, SHA256_DIGEST_SIZE) != 0)
|
||||||
|
return SZ_ERROR_CRC;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case XZ_STATE_STREAM_INDEX_CRC:
|
||||||
|
{
|
||||||
|
if (p->pos < 4)
|
||||||
|
{
|
||||||
|
(*srcLen)++;
|
||||||
|
p->buf[p->pos++] = *src++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p->state = XZ_STATE_STREAM_FOOTER;
|
||||||
|
p->pos = 0;
|
||||||
|
if (CRC_GET_DIGEST(p->crc) != GetUi32(p->buf))
|
||||||
|
return SZ_ERROR_CRC;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case XZ_STATE_STREAM_FOOTER:
|
||||||
|
{
|
||||||
|
UInt32 cur = XZ_STREAM_FOOTER_SIZE - p->pos;
|
||||||
|
if (cur > srcRem)
|
||||||
|
cur = (UInt32)srcRem;
|
||||||
|
memcpy(p->buf + p->pos, src, cur);
|
||||||
|
p->pos += cur;
|
||||||
|
(*srcLen) += cur;
|
||||||
|
src += cur;
|
||||||
|
if (p->pos == XZ_STREAM_FOOTER_SIZE)
|
||||||
|
{
|
||||||
|
p->state = XZ_STATE_STREAM_PADDING;
|
||||||
|
p->numStreams++;
|
||||||
|
p->padSize = 0;
|
||||||
|
if (!Xz_CheckFooter(p->streamFlags, p->indexSize, p->buf))
|
||||||
|
return SZ_ERROR_CRC;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case XZ_STATE_STREAM_PADDING:
|
||||||
|
{
|
||||||
|
if (*src != 0)
|
||||||
|
{
|
||||||
|
if (((UInt32)p->padSize & 3) != 0)
|
||||||
|
return SZ_ERROR_NO_ARCHIVE;
|
||||||
|
p->pos = 0;
|
||||||
|
p->state = XZ_STATE_STREAM_HEADER;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
(*srcLen)++;
|
||||||
|
src++;
|
||||||
|
p->padSize++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
if (p->state == XZ_STATE_FINISHED)
|
||||||
|
*status = CODER_STATUS_FINISHED_WITH_MARK;
|
||||||
|
return SZ_OK;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
Bool XzUnpacker_IsStreamWasFinished(CXzUnpacker *p)
|
||||||
|
{
|
||||||
|
return (p->state == XZ_STATE_STREAM_PADDING) && (((UInt32)p->padSize & 3) == 0);
|
||||||
|
}
|
||||||
@@ -0,0 +1,497 @@
|
|||||||
|
/* XzEnc.c -- Xz Encode
|
||||||
|
2009-06-04 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "7zCrc.h"
|
||||||
|
#include "Alloc.h"
|
||||||
|
#include "Bra.h"
|
||||||
|
#include "CpuArch.h"
|
||||||
|
#ifdef USE_SUBBLOCK
|
||||||
|
#include "SbEnc.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "XzEnc.h"
|
||||||
|
|
||||||
|
static void *SzBigAlloc(void *p, size_t size) { p = p; return BigAlloc(size); }
|
||||||
|
static void SzBigFree(void *p, void *address) { p = p; BigFree(address); }
|
||||||
|
static ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree };
|
||||||
|
|
||||||
|
static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }
|
||||||
|
static void SzFree(void *p, void *address) { p = p; MyFree(address); }
|
||||||
|
static ISzAlloc g_Alloc = { SzAlloc, SzFree };
|
||||||
|
|
||||||
|
#define XzBlock_ClearFlags(p) (p)->flags = 0;
|
||||||
|
#define XzBlock_SetNumFilters(p, n) (p)->flags |= ((n) - 1);
|
||||||
|
#define XzBlock_SetHasPackSize(p) (p)->flags |= XZ_BF_PACK_SIZE;
|
||||||
|
#define XzBlock_SetHasUnpackSize(p) (p)->flags |= XZ_BF_UNPACK_SIZE;
|
||||||
|
|
||||||
|
static SRes WriteBytes(ISeqOutStream *s, const void *buf, UInt32 size)
|
||||||
|
{
|
||||||
|
return (s->Write(s, buf, size) == size) ? SZ_OK : SZ_ERROR_WRITE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SRes WriteBytesAndCrc(ISeqOutStream *s, const void *buf, UInt32 size, UInt32 *crc)
|
||||||
|
{
|
||||||
|
*crc = CrcUpdate(*crc, buf, size);
|
||||||
|
return WriteBytes(s, buf, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
SRes Xz_WriteHeader(CXzStreamFlags f, ISeqOutStream *s)
|
||||||
|
{
|
||||||
|
UInt32 crc;
|
||||||
|
Byte header[XZ_STREAM_HEADER_SIZE];
|
||||||
|
memcpy(header, XZ_SIG, XZ_SIG_SIZE);
|
||||||
|
header[XZ_SIG_SIZE] = (Byte)(f >> 8);
|
||||||
|
header[XZ_SIG_SIZE + 1] = (Byte)(f & 0xFF);
|
||||||
|
crc = CrcCalc(header + XZ_SIG_SIZE, XZ_STREAM_FLAGS_SIZE);
|
||||||
|
SetUi32(header + XZ_SIG_SIZE + XZ_STREAM_FLAGS_SIZE, crc);
|
||||||
|
return WriteBytes(s, header, XZ_STREAM_HEADER_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
SRes XzBlock_WriteHeader(const CXzBlock *p, ISeqOutStream *s)
|
||||||
|
{
|
||||||
|
Byte header[XZ_BLOCK_HEADER_SIZE_MAX];
|
||||||
|
|
||||||
|
unsigned pos = 1;
|
||||||
|
int numFilters, i;
|
||||||
|
header[pos++] = p->flags;
|
||||||
|
|
||||||
|
if (XzBlock_HasPackSize(p)) pos += Xz_WriteVarInt(header + pos, p->packSize);
|
||||||
|
if (XzBlock_HasUnpackSize(p)) pos += Xz_WriteVarInt(header + pos, p->unpackSize);
|
||||||
|
numFilters = XzBlock_GetNumFilters(p);
|
||||||
|
for (i = 0; i < numFilters; i++)
|
||||||
|
{
|
||||||
|
const CXzFilter *f = &p->filters[i];
|
||||||
|
pos += Xz_WriteVarInt(header + pos, f->id);
|
||||||
|
pos += Xz_WriteVarInt(header + pos, f->propsSize);
|
||||||
|
memcpy(header + pos, f->props, f->propsSize);
|
||||||
|
pos += f->propsSize;
|
||||||
|
}
|
||||||
|
while((pos & 3) != 0)
|
||||||
|
header[pos++] = 0;
|
||||||
|
header[0] = (Byte)(pos >> 2);
|
||||||
|
SetUi32(header + pos, CrcCalc(header, pos));
|
||||||
|
return WriteBytes(s, header, pos + 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
SRes Xz_WriteFooter(CXzStream *p, ISeqOutStream *s)
|
||||||
|
{
|
||||||
|
Byte buf[32];
|
||||||
|
UInt64 globalPos;
|
||||||
|
{
|
||||||
|
UInt32 crc = CRC_INIT_VAL;
|
||||||
|
unsigned pos = 1 + Xz_WriteVarInt(buf + 1, p->numBlocks);
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
globalPos = pos;
|
||||||
|
buf[0] = 0;
|
||||||
|
RINOK(WriteBytesAndCrc(s, buf, pos, &crc));
|
||||||
|
for (i = 0; i < p->numBlocks; i++)
|
||||||
|
{
|
||||||
|
const CXzBlockSizes *block = &p->blocks[i];
|
||||||
|
pos = Xz_WriteVarInt(buf, block->totalSize);
|
||||||
|
pos += Xz_WriteVarInt(buf + pos, block->unpackSize);
|
||||||
|
globalPos += pos;
|
||||||
|
RINOK(WriteBytesAndCrc(s, buf, pos, &crc));
|
||||||
|
}
|
||||||
|
pos = ((unsigned)globalPos & 3);
|
||||||
|
if (pos != 0)
|
||||||
|
{
|
||||||
|
buf[0] = buf[1] = buf[2] = 0;
|
||||||
|
RINOK(WriteBytesAndCrc(s, buf, 4 - pos, &crc));
|
||||||
|
globalPos += 4 - pos;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
SetUi32(buf, CRC_GET_DIGEST(crc));
|
||||||
|
RINOK(WriteBytes(s, buf, 4));
|
||||||
|
globalPos += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
UInt32 indexSize = (UInt32)((globalPos >> 2) - 1);
|
||||||
|
SetUi32(buf + 4, indexSize);
|
||||||
|
buf[8] = (Byte)(p->flags >> 8);
|
||||||
|
buf[9] = (Byte)(p->flags & 0xFF);
|
||||||
|
SetUi32(buf, CrcCalc(buf + 4, 6));
|
||||||
|
memcpy(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE);
|
||||||
|
return WriteBytes(s, buf, 12);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SRes Xz_AddIndexRecord(CXzStream *p, UInt64 unpackSize, UInt64 totalSize, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
if (p->blocks == 0 || p->numBlocksAllocated == p->numBlocks)
|
||||||
|
{
|
||||||
|
size_t num = (p->numBlocks + 1) * 2;
|
||||||
|
size_t newSize = sizeof(CXzBlockSizes) * num;
|
||||||
|
CXzBlockSizes *blocks;
|
||||||
|
if (newSize / sizeof(CXzBlockSizes) != num)
|
||||||
|
return SZ_ERROR_MEM;
|
||||||
|
blocks = alloc->Alloc(alloc, newSize);
|
||||||
|
if (blocks == 0)
|
||||||
|
return SZ_ERROR_MEM;
|
||||||
|
if (p->numBlocks != 0)
|
||||||
|
{
|
||||||
|
memcpy(blocks, p->blocks, p->numBlocks * sizeof(CXzBlockSizes));
|
||||||
|
Xz_Free(p, alloc);
|
||||||
|
}
|
||||||
|
p->blocks = blocks;
|
||||||
|
p->numBlocksAllocated = num;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
CXzBlockSizes *block = &p->blocks[p->numBlocks++];
|
||||||
|
block->totalSize = totalSize;
|
||||||
|
block->unpackSize = unpackSize;
|
||||||
|
}
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------- CSeqCheckInStream ---------- */
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ISeqInStream p;
|
||||||
|
ISeqInStream *realStream;
|
||||||
|
UInt64 processed;
|
||||||
|
CXzCheck check;
|
||||||
|
} CSeqCheckInStream;
|
||||||
|
|
||||||
|
void SeqCheckInStream_Init(CSeqCheckInStream *p, int mode)
|
||||||
|
{
|
||||||
|
p->processed = 0;
|
||||||
|
XzCheck_Init(&p->check, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SeqCheckInStream_GetDigest(CSeqCheckInStream *p, Byte *digest)
|
||||||
|
{
|
||||||
|
XzCheck_Final(&p->check, digest);
|
||||||
|
}
|
||||||
|
|
||||||
|
static SRes SeqCheckInStream_Read(void *pp, void *data, size_t *size)
|
||||||
|
{
|
||||||
|
CSeqCheckInStream *p = (CSeqCheckInStream *)pp;
|
||||||
|
SRes res = p->realStream->Read(p->realStream, data, size);
|
||||||
|
XzCheck_Update(&p->check, data, *size);
|
||||||
|
p->processed += *size;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------- CSeqSizeOutStream ---------- */
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ISeqOutStream p;
|
||||||
|
ISeqOutStream *realStream;
|
||||||
|
UInt64 processed;
|
||||||
|
} CSeqSizeOutStream;
|
||||||
|
|
||||||
|
static size_t MyWrite(void *pp, const void *data, size_t size)
|
||||||
|
{
|
||||||
|
CSeqSizeOutStream *p = (CSeqSizeOutStream *)pp;
|
||||||
|
size = p->realStream->Write(p->realStream, data, size);
|
||||||
|
p->processed += size;
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------- CSeqInFilter ---------- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
typedef struct _IFilter
|
||||||
|
{
|
||||||
|
void *p;
|
||||||
|
void (*Free)(void *p, ISzAlloc *alloc);
|
||||||
|
SRes (*SetProps)(void *p, const Byte *props, size_t propSize, ISzAlloc *alloc);
|
||||||
|
void (*Init)(void *p);
|
||||||
|
size_t (*Filter)(void *p, Byte *data, SizeT destLen);
|
||||||
|
} IFilter;
|
||||||
|
|
||||||
|
#define FILT_BUF_SIZE (1 << 19)
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ISeqInStream p;
|
||||||
|
ISeqInStream *realStream;
|
||||||
|
UInt32 x86State;
|
||||||
|
UInt32 ip;
|
||||||
|
UInt64 processed;
|
||||||
|
CXzCheck check;
|
||||||
|
Byte buf[FILT_BUF_SIZE];
|
||||||
|
UInt32 bufferPos;
|
||||||
|
UInt32 convertedPosBegin;
|
||||||
|
UInt32 convertedPosEnd;
|
||||||
|
IFilter *filter;
|
||||||
|
} CSeqInFilter;
|
||||||
|
|
||||||
|
static SRes SeqInFilter_Read(void *pp, void *data, size_t *size)
|
||||||
|
{
|
||||||
|
CSeqInFilter *p = (CSeqInFilter *)pp;
|
||||||
|
size_t remSize = *size;
|
||||||
|
*size = 0;
|
||||||
|
|
||||||
|
while (remSize > 0)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
if (p->convertedPosBegin != p->convertedPosEnd)
|
||||||
|
{
|
||||||
|
UInt32 sizeTemp = p->convertedPosEnd - p->convertedPosBegin;
|
||||||
|
if (remSize < sizeTemp)
|
||||||
|
sizeTemp = (UInt32)remSize;
|
||||||
|
memmove(data, p->buf + p->convertedPosBegin, sizeTemp);
|
||||||
|
p->convertedPosBegin += sizeTemp;
|
||||||
|
data = (void *)((Byte *)data + sizeTemp);
|
||||||
|
remSize -= sizeTemp;
|
||||||
|
*size += sizeTemp;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for (i = 0; p->convertedPosEnd + i < p->bufferPos; i++)
|
||||||
|
p->buf[i] = p->buf[i + p->convertedPosEnd];
|
||||||
|
p->bufferPos = i;
|
||||||
|
p->convertedPosBegin = p->convertedPosEnd = 0;
|
||||||
|
{
|
||||||
|
size_t processedSizeTemp = FILT_BUF_SIZE - p->bufferPos;
|
||||||
|
RINOK(p->realStream->Read(p->realStream, p->buf + p->bufferPos, &processedSizeTemp));
|
||||||
|
p->bufferPos = p->bufferPos + (UInt32)processedSizeTemp;
|
||||||
|
}
|
||||||
|
p->convertedPosEnd = (UInt32)p->filter->Filter(p->filter->p, p->buf, p->bufferPos);
|
||||||
|
if (p->convertedPosEnd == 0)
|
||||||
|
{
|
||||||
|
if (p->bufferPos == 0)
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p->convertedPosEnd = p->bufferPos;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (p->convertedPosEnd > p->bufferPos)
|
||||||
|
{
|
||||||
|
for (; p->bufferPos < p->convertedPosEnd; p->bufferPos++)
|
||||||
|
p->buf[p->bufferPos] = 0;
|
||||||
|
p->convertedPosEnd = (UInt32)p->filter->Filter(p->filter->p, p->buf, p->bufferPos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ISeqInStream p;
|
||||||
|
ISeqInStream *realStream;
|
||||||
|
CMixCoder mixCoder;
|
||||||
|
Byte buf[FILT_BUF_SIZE];
|
||||||
|
UInt32 bufPos;
|
||||||
|
UInt32 bufSize;
|
||||||
|
} CMixCoderSeqInStream;
|
||||||
|
|
||||||
|
static SRes CMixCoderSeqInStream_Read(void *pp, void *data, size_t *size)
|
||||||
|
{
|
||||||
|
CMixCoderSeqInStream *p = (CMixCoderSeqInStream *)pp;
|
||||||
|
SRes res = SZ_OK;
|
||||||
|
size_t remSize = *size;
|
||||||
|
*size = 0;
|
||||||
|
while (remSize > 0)
|
||||||
|
{
|
||||||
|
if (p->bufPos == p->bufSize)
|
||||||
|
{
|
||||||
|
size_t curSize;
|
||||||
|
p->bufPos = p->bufSize = 0;
|
||||||
|
if (*size != 0)
|
||||||
|
break;
|
||||||
|
curSize = FILT_BUF_SIZE;
|
||||||
|
RINOK(p->realStream->Read(p->realStream, p->buf, &curSize));
|
||||||
|
p->bufSize = (UInt32)curSize;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
SizeT destLen = remSize;
|
||||||
|
SizeT srcLen = p->bufSize - p->bufPos;
|
||||||
|
res = MixCoder_Code(&p->mixCoder, data, &destLen, p->buf + p->bufPos, &srcLen, 0);
|
||||||
|
data = (void *)((Byte *)data + destLen);
|
||||||
|
remSize -= destLen;
|
||||||
|
*size += destLen;
|
||||||
|
p->bufPos += srcLen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef USE_SUBBLOCK
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ISeqInStream p;
|
||||||
|
CSubblockEnc sb;
|
||||||
|
UInt64 processed;
|
||||||
|
} CSbEncInStream;
|
||||||
|
|
||||||
|
void SbEncInStream_Init(CSbEncInStream *p)
|
||||||
|
{
|
||||||
|
p->processed = 0;
|
||||||
|
SubblockEnc_Init(&p->sb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static SRes SbEncInStream_Read(void *pp, void *data, size_t *size)
|
||||||
|
{
|
||||||
|
CSbEncInStream *p = (CSbEncInStream *)pp;
|
||||||
|
SRes res = SubblockEnc_Read(&p->sb, data, size);
|
||||||
|
p->processed += *size;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
/* CMixCoderSeqInStream inStream; */
|
||||||
|
CLzma2EncHandle lzma2;
|
||||||
|
#ifdef USE_SUBBLOCK
|
||||||
|
CSbEncInStream sb;
|
||||||
|
#endif
|
||||||
|
ISzAlloc *alloc;
|
||||||
|
ISzAlloc *bigAlloc;
|
||||||
|
} CLzma2WithFilters;
|
||||||
|
|
||||||
|
|
||||||
|
static void Lzma2WithFilters_Construct(CLzma2WithFilters *p, ISzAlloc *alloc, ISzAlloc *bigAlloc)
|
||||||
|
{
|
||||||
|
p->alloc = alloc;
|
||||||
|
p->bigAlloc = bigAlloc;
|
||||||
|
p->lzma2 = NULL;
|
||||||
|
#ifdef USE_SUBBLOCK
|
||||||
|
p->sb.p.Read = SbEncInStream_Read;
|
||||||
|
SubblockEnc_Construct(&p->sb.sb, p->alloc);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static SRes Lzma2WithFilters_Create(CLzma2WithFilters *p)
|
||||||
|
{
|
||||||
|
p->lzma2 = Lzma2Enc_Create(p->alloc, p->bigAlloc);
|
||||||
|
if (p->lzma2 == 0)
|
||||||
|
return SZ_ERROR_MEM;
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Lzma2WithFilters_Free(CLzma2WithFilters *p)
|
||||||
|
{
|
||||||
|
#ifdef USE_SUBBLOCK
|
||||||
|
SubblockEnc_Free(&p->sb.sb);
|
||||||
|
#endif
|
||||||
|
if (p->lzma2)
|
||||||
|
{
|
||||||
|
Lzma2Enc_Destroy(p->lzma2);
|
||||||
|
p->lzma2 = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static SRes Xz_Compress(CXzStream *xz,
|
||||||
|
CLzma2WithFilters *lzmaf,
|
||||||
|
ISeqOutStream *outStream,
|
||||||
|
ISeqInStream *inStream,
|
||||||
|
const CLzma2EncProps *lzma2Props,
|
||||||
|
Bool useSubblock,
|
||||||
|
ICompressProgress *progress)
|
||||||
|
{
|
||||||
|
xz->flags = XZ_CHECK_CRC32;
|
||||||
|
|
||||||
|
RINOK(Lzma2Enc_SetProps(lzmaf->lzma2, lzma2Props));
|
||||||
|
RINOK(Xz_WriteHeader(xz->flags, outStream));
|
||||||
|
|
||||||
|
{
|
||||||
|
CSeqCheckInStream checkInStream;
|
||||||
|
CSeqSizeOutStream seqSizeOutStream;
|
||||||
|
CXzBlock block;
|
||||||
|
int filterIndex = 0;
|
||||||
|
|
||||||
|
XzBlock_ClearFlags(&block);
|
||||||
|
XzBlock_SetNumFilters(&block, 1 + (useSubblock ? 1 : 0));
|
||||||
|
|
||||||
|
if (useSubblock)
|
||||||
|
{
|
||||||
|
CXzFilter *f = &block.filters[filterIndex++];
|
||||||
|
f->id = XZ_ID_Subblock;
|
||||||
|
f->propsSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
CXzFilter *f = &block.filters[filterIndex++];
|
||||||
|
f->id = XZ_ID_LZMA2;
|
||||||
|
f->propsSize = 1;
|
||||||
|
f->props[0] = Lzma2Enc_WriteProperties(lzmaf->lzma2);
|
||||||
|
}
|
||||||
|
|
||||||
|
seqSizeOutStream.p.Write = MyWrite;
|
||||||
|
seqSizeOutStream.realStream = outStream;
|
||||||
|
seqSizeOutStream.processed = 0;
|
||||||
|
|
||||||
|
RINOK(XzBlock_WriteHeader(&block, &seqSizeOutStream.p));
|
||||||
|
|
||||||
|
checkInStream.p.Read = SeqCheckInStream_Read;
|
||||||
|
checkInStream.realStream = inStream;
|
||||||
|
SeqCheckInStream_Init(&checkInStream, XzFlags_GetCheckType(xz->flags));
|
||||||
|
|
||||||
|
#ifdef USE_SUBBLOCK
|
||||||
|
if (useSubblock)
|
||||||
|
{
|
||||||
|
lzmaf->sb.sb.inStream = &checkInStream.p;
|
||||||
|
SubblockEnc_Init(&lzmaf->sb.sb);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
{
|
||||||
|
UInt64 packPos = seqSizeOutStream.processed;
|
||||||
|
SRes res = Lzma2Enc_Encode(lzmaf->lzma2, &seqSizeOutStream.p,
|
||||||
|
#ifdef USE_SUBBLOCK
|
||||||
|
useSubblock ? &lzmaf->sb.p:
|
||||||
|
#endif
|
||||||
|
&checkInStream.p,
|
||||||
|
progress);
|
||||||
|
RINOK(res);
|
||||||
|
block.unpackSize = checkInStream.processed;
|
||||||
|
block.packSize = seqSizeOutStream.processed - packPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
unsigned padSize = 0;
|
||||||
|
Byte buf[128];
|
||||||
|
while((((unsigned)block.packSize + padSize) & 3) != 0)
|
||||||
|
buf[padSize++] = 0;
|
||||||
|
SeqCheckInStream_GetDigest(&checkInStream, buf + padSize);
|
||||||
|
RINOK(WriteBytes(&seqSizeOutStream.p, buf, padSize + XzFlags_GetCheckSize(xz->flags)));
|
||||||
|
RINOK(Xz_AddIndexRecord(xz, block.unpackSize, seqSizeOutStream.processed - padSize, &g_Alloc));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Xz_WriteFooter(xz, outStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
SRes Xz_Encode(ISeqOutStream *outStream, ISeqInStream *inStream,
|
||||||
|
const CLzma2EncProps *lzma2Props, Bool useSubblock,
|
||||||
|
ICompressProgress *progress)
|
||||||
|
{
|
||||||
|
SRes res;
|
||||||
|
CXzStream xz;
|
||||||
|
CLzma2WithFilters lzmaf;
|
||||||
|
Xz_Construct(&xz);
|
||||||
|
Lzma2WithFilters_Construct(&lzmaf, &g_Alloc, &g_BigAlloc);
|
||||||
|
res = Lzma2WithFilters_Create(&lzmaf);
|
||||||
|
if (res == SZ_OK)
|
||||||
|
res = Xz_Compress(&xz, &lzmaf, outStream, inStream,
|
||||||
|
lzma2Props, useSubblock, progress);
|
||||||
|
Lzma2WithFilters_Free(&lzmaf);
|
||||||
|
Xz_Free(&xz, &g_Alloc);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
SRes Xz_EncodeEmpty(ISeqOutStream *outStream)
|
||||||
|
{
|
||||||
|
SRes res;
|
||||||
|
CXzStream xz;
|
||||||
|
Xz_Construct(&xz);
|
||||||
|
res = Xz_WriteHeader(xz.flags, outStream);
|
||||||
|
if (res == SZ_OK)
|
||||||
|
res = Xz_WriteFooter(&xz, outStream);
|
||||||
|
Xz_Free(&xz, &g_Alloc);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
/* XzEnc.h -- Xz Encode
|
||||||
|
2009-04-15 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#ifndef __XZ_ENC_H
|
||||||
|
#define __XZ_ENC_H
|
||||||
|
|
||||||
|
#include "Lzma2Enc.h"
|
||||||
|
|
||||||
|
#include "Xz.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SRes Xz_Encode(ISeqOutStream *outStream, ISeqInStream *inStream,
|
||||||
|
const CLzma2EncProps *lzma2Props, Bool useSubblock,
|
||||||
|
ICompressProgress *progress);
|
||||||
|
|
||||||
|
SRes Xz_EncodeEmpty(ISeqOutStream *outStream);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,306 @@
|
|||||||
|
/* XzIn.c - Xz input
|
||||||
|
2009-06-19 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "7zCrc.h"
|
||||||
|
#include "CpuArch.h"
|
||||||
|
#include "Xz.h"
|
||||||
|
|
||||||
|
SRes Xz_ReadHeader(CXzStreamFlags *p, ISeqInStream *inStream)
|
||||||
|
{
|
||||||
|
Byte sig[XZ_STREAM_HEADER_SIZE];
|
||||||
|
RINOK(SeqInStream_Read2(inStream, sig, XZ_STREAM_HEADER_SIZE, SZ_ERROR_NO_ARCHIVE));
|
||||||
|
if (memcmp(sig, XZ_SIG, XZ_SIG_SIZE) != 0)
|
||||||
|
return SZ_ERROR_NO_ARCHIVE;
|
||||||
|
return Xz_ParseHeader(p, sig);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define READ_VARINT_AND_CHECK(buf, pos, size, res) \
|
||||||
|
{ unsigned s = Xz_ReadVarInt(buf + pos, size - pos, res); \
|
||||||
|
if (s == 0) return SZ_ERROR_ARCHIVE; pos += s; }
|
||||||
|
|
||||||
|
SRes XzBlock_ReadHeader(CXzBlock *p, ISeqInStream *inStream, Bool *isIndex, UInt32 *headerSizeRes)
|
||||||
|
{
|
||||||
|
Byte header[XZ_BLOCK_HEADER_SIZE_MAX];
|
||||||
|
unsigned headerSize;
|
||||||
|
*headerSizeRes = 0;
|
||||||
|
RINOK(SeqInStream_ReadByte(inStream, &header[0]));
|
||||||
|
headerSize = ((unsigned)header[0] << 2) + 4;
|
||||||
|
if (headerSize == 0)
|
||||||
|
{
|
||||||
|
*headerSizeRes = 1;
|
||||||
|
*isIndex = True;
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
*isIndex = False;
|
||||||
|
*headerSizeRes = headerSize;
|
||||||
|
RINOK(SeqInStream_Read(inStream, header + 1, headerSize - 1));
|
||||||
|
return XzBlock_Parse(p, header);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ADD_SIZE_CHECH(size, val) \
|
||||||
|
{ UInt64 newSize = size + (val); if (newSize < size) return XZ_SIZE_OVERFLOW; size = newSize; }
|
||||||
|
|
||||||
|
UInt64 Xz_GetUnpackSize(const CXzStream *p)
|
||||||
|
{
|
||||||
|
UInt64 size = 0;
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < p->numBlocks; i++)
|
||||||
|
ADD_SIZE_CHECH(size, p->blocks[i].unpackSize);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt64 Xz_GetPackSize(const CXzStream *p)
|
||||||
|
{
|
||||||
|
UInt64 size = 0;
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < p->numBlocks; i++)
|
||||||
|
ADD_SIZE_CHECH(size, (p->blocks[i].totalSize + 3) & ~(UInt64)3);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
SRes XzBlock_ReadFooter(CXzBlock *p, CXzStreamFlags f, ISeqInStream *inStream)
|
||||||
|
{
|
||||||
|
return SeqInStream_Read(inStream, p->check, XzFlags_GetCheckSize(f));
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
static SRes Xz_ReadIndex2(CXzStream *p, const Byte *buf, size_t size, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
size_t i, numBlocks, crcStartPos, pos = 1;
|
||||||
|
UInt32 crc;
|
||||||
|
|
||||||
|
if (size < 5 || buf[0] != 0)
|
||||||
|
return SZ_ERROR_ARCHIVE;
|
||||||
|
|
||||||
|
size -= 4;
|
||||||
|
crc = CrcCalc(buf, size);
|
||||||
|
if (crc != GetUi32(buf + size))
|
||||||
|
return SZ_ERROR_ARCHIVE;
|
||||||
|
|
||||||
|
{
|
||||||
|
UInt64 numBlocks64;
|
||||||
|
READ_VARINT_AND_CHECK(buf, pos, size, &numBlocks64);
|
||||||
|
numBlocks = (size_t)numBlocks64;
|
||||||
|
if (numBlocks != numBlocks64 || numBlocks * 2 > size)
|
||||||
|
return SZ_ERROR_ARCHIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
crcStartPos = pos;
|
||||||
|
Xz_Free(p, alloc);
|
||||||
|
if (numBlocks != 0)
|
||||||
|
{
|
||||||
|
p->numBlocks = numBlocks;
|
||||||
|
p->numBlocksAllocated = numBlocks;
|
||||||
|
p->blocks = alloc->Alloc(alloc, sizeof(CXzBlockSizes) * numBlocks);
|
||||||
|
if (p->blocks == 0)
|
||||||
|
return SZ_ERROR_MEM;
|
||||||
|
for (i = 0; i < numBlocks; i++)
|
||||||
|
{
|
||||||
|
CXzBlockSizes *block = &p->blocks[i];
|
||||||
|
READ_VARINT_AND_CHECK(buf, pos, size, &block->totalSize);
|
||||||
|
READ_VARINT_AND_CHECK(buf, pos, size, &block->unpackSize);
|
||||||
|
if (block->totalSize == 0)
|
||||||
|
return SZ_ERROR_ARCHIVE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while ((pos & 3) != 0)
|
||||||
|
if (buf[pos++] != 0)
|
||||||
|
return SZ_ERROR_ARCHIVE;
|
||||||
|
return (pos == size) ? SZ_OK : SZ_ERROR_ARCHIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SRes Xz_ReadIndex(CXzStream *p, ILookInStream *stream, UInt64 indexSize, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
SRes res;
|
||||||
|
size_t size;
|
||||||
|
Byte *buf;
|
||||||
|
if (indexSize > ((UInt32)1 << 31))
|
||||||
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
|
size = (size_t)indexSize;
|
||||||
|
if (size != indexSize)
|
||||||
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
|
buf = alloc->Alloc(alloc, size);
|
||||||
|
if (buf == 0)
|
||||||
|
return SZ_ERROR_MEM;
|
||||||
|
res = LookInStream_Read2(stream, buf, size, SZ_ERROR_UNSUPPORTED);
|
||||||
|
if (res == SZ_OK)
|
||||||
|
res = Xz_ReadIndex2(p, buf, size, alloc);
|
||||||
|
alloc->Free(alloc, buf);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SRes SeekFromCur(ILookInStream *inStream, Int64 *res)
|
||||||
|
{
|
||||||
|
return inStream->Seek(inStream, res, SZ_SEEK_CUR);
|
||||||
|
}
|
||||||
|
|
||||||
|
static SRes Xz_ReadBackward(CXzStream *p, ILookInStream *stream, Int64 *startOffset, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
UInt64 indexSize;
|
||||||
|
Byte buf[XZ_STREAM_FOOTER_SIZE];
|
||||||
|
|
||||||
|
if ((*startOffset & 3) != 0 || *startOffset < XZ_STREAM_FOOTER_SIZE)
|
||||||
|
return SZ_ERROR_NO_ARCHIVE;
|
||||||
|
*startOffset = -XZ_STREAM_FOOTER_SIZE;
|
||||||
|
RINOK(SeekFromCur(stream, startOffset));
|
||||||
|
|
||||||
|
RINOK(LookInStream_Read2(stream, buf, XZ_STREAM_FOOTER_SIZE, SZ_ERROR_NO_ARCHIVE));
|
||||||
|
|
||||||
|
if (memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) != 0)
|
||||||
|
{
|
||||||
|
Int64 i = 0;
|
||||||
|
*startOffset += XZ_STREAM_FOOTER_SIZE;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
int j;
|
||||||
|
size_t processedSize;
|
||||||
|
#define TEMP_BUF_SIZE (1 << 10)
|
||||||
|
Byte tempBuf[TEMP_BUF_SIZE];
|
||||||
|
if (*startOffset < XZ_STREAM_FOOTER_SIZE || i > (1 << 16))
|
||||||
|
return SZ_ERROR_NO_ARCHIVE;
|
||||||
|
processedSize = (*startOffset > TEMP_BUF_SIZE) ? TEMP_BUF_SIZE : (size_t)*startOffset;
|
||||||
|
i += processedSize;
|
||||||
|
*startOffset = -(Int64)processedSize;
|
||||||
|
RINOK(SeekFromCur(stream, startOffset));
|
||||||
|
RINOK(LookInStream_Read2(stream, tempBuf, processedSize, SZ_ERROR_NO_ARCHIVE));
|
||||||
|
for (j = (int)processedSize; j >= 0; j--)
|
||||||
|
if (tempBuf[j -1] != 0)
|
||||||
|
break;
|
||||||
|
if (j != 0)
|
||||||
|
{
|
||||||
|
if ((j & 3) != 0)
|
||||||
|
return SZ_ERROR_NO_ARCHIVE;
|
||||||
|
*startOffset += j;
|
||||||
|
if (*startOffset < XZ_STREAM_FOOTER_SIZE)
|
||||||
|
return SZ_ERROR_NO_ARCHIVE;
|
||||||
|
*startOffset -= XZ_STREAM_FOOTER_SIZE;
|
||||||
|
RINOK(stream->Seek(stream, startOffset, SZ_SEEK_SET));
|
||||||
|
RINOK(LookInStream_Read2(stream, buf, XZ_STREAM_FOOTER_SIZE, SZ_ERROR_NO_ARCHIVE));
|
||||||
|
if (memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) != 0)
|
||||||
|
return SZ_ERROR_NO_ARCHIVE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p->flags = (CXzStreamFlags)GetBe16(buf + 8);
|
||||||
|
|
||||||
|
if (!XzFlags_IsSupported(p->flags))
|
||||||
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
|
|
||||||
|
if (GetUi32(buf) != CrcCalc(buf + 4, 6))
|
||||||
|
return SZ_ERROR_ARCHIVE;
|
||||||
|
|
||||||
|
indexSize = ((UInt64)GetUi32(buf + 4) + 1) << 2;
|
||||||
|
|
||||||
|
*startOffset = -(Int64)(indexSize + XZ_STREAM_FOOTER_SIZE);
|
||||||
|
RINOK(SeekFromCur(stream, startOffset));
|
||||||
|
|
||||||
|
RINOK(Xz_ReadIndex(p, stream, indexSize, alloc));
|
||||||
|
|
||||||
|
{
|
||||||
|
UInt64 totalSize = Xz_GetPackSize(p);
|
||||||
|
UInt64 sum = XZ_STREAM_HEADER_SIZE + totalSize + indexSize;
|
||||||
|
if (totalSize == XZ_SIZE_OVERFLOW ||
|
||||||
|
sum >= ((UInt64)1 << 63) ||
|
||||||
|
totalSize >= ((UInt64)1 << 63))
|
||||||
|
return SZ_ERROR_ARCHIVE;
|
||||||
|
*startOffset = -(Int64)sum;
|
||||||
|
RINOK(SeekFromCur(stream, startOffset));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
CXzStreamFlags headerFlags;
|
||||||
|
CSecToRead secToRead;
|
||||||
|
SecToRead_CreateVTable(&secToRead);
|
||||||
|
secToRead.realStream = stream;
|
||||||
|
|
||||||
|
RINOK(Xz_ReadHeader(&headerFlags, &secToRead.s));
|
||||||
|
return (p->flags == headerFlags) ? SZ_OK : SZ_ERROR_ARCHIVE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- Xz Streams ---------- */
|
||||||
|
|
||||||
|
void Xzs_Construct(CXzs *p)
|
||||||
|
{
|
||||||
|
p->num = p->numAllocated = 0;
|
||||||
|
p->streams = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Xzs_Free(CXzs *p, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < p->num; i++)
|
||||||
|
Xz_Free(&p->streams[i], alloc);
|
||||||
|
alloc->Free(alloc, p->streams);
|
||||||
|
p->num = p->numAllocated = 0;
|
||||||
|
p->streams = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt64 Xzs_GetNumBlocks(const CXzs *p)
|
||||||
|
{
|
||||||
|
UInt64 num = 0;
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < p->num; i++)
|
||||||
|
num += p->streams[i].numBlocks;
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt64 Xzs_GetUnpackSize(const CXzs *p)
|
||||||
|
{
|
||||||
|
UInt64 size = 0;
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < p->num; i++)
|
||||||
|
ADD_SIZE_CHECH(size, Xz_GetUnpackSize(&p->streams[i]));
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
UInt64 Xzs_GetPackSize(const CXzs *p)
|
||||||
|
{
|
||||||
|
UInt64 size = 0;
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < p->num; i++)
|
||||||
|
ADD_SIZE_CHECH(size, Xz_GetTotalSize(&p->streams[i]));
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
SRes Xzs_ReadBackward(CXzs *p, ILookInStream *stream, Int64 *startOffset, ICompressProgress *progress, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
Int64 endOffset = 0;
|
||||||
|
RINOK(stream->Seek(stream, &endOffset, SZ_SEEK_END));
|
||||||
|
*startOffset = endOffset;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
CXzStream st;
|
||||||
|
SRes res;
|
||||||
|
Xz_Construct(&st);
|
||||||
|
res = Xz_ReadBackward(&st, stream, startOffset, alloc);
|
||||||
|
st.startOffset = *startOffset;
|
||||||
|
RINOK(res);
|
||||||
|
if (p->num == p->numAllocated)
|
||||||
|
{
|
||||||
|
size_t newNum = p->num + p->num / 4 + 1;
|
||||||
|
Byte *data = (Byte *)alloc->Alloc(alloc, newNum * sizeof(CXzStream));
|
||||||
|
if (data == 0)
|
||||||
|
return SZ_ERROR_MEM;
|
||||||
|
p->numAllocated = newNum;
|
||||||
|
memcpy(data, p->streams, p->num * sizeof(CXzStream));
|
||||||
|
alloc->Free(alloc, p->streams);
|
||||||
|
p->streams = (CXzStream *)data;
|
||||||
|
}
|
||||||
|
p->streams[p->num++] = st;
|
||||||
|
if (*startOffset == 0)
|
||||||
|
break;
|
||||||
|
RINOK(stream->Seek(stream, startOffset, SZ_SEEK_SET));
|
||||||
|
if (progress && progress->Progress(progress, endOffset - *startOffset, (UInt64)(Int64)-1) != SZ_OK)
|
||||||
|
return SZ_ERROR_PROGRESS;
|
||||||
|
}
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
utf8 cpp library
|
||||||
|
Release 2.3
|
||||||
|
|
||||||
|
This is a relatively minor feature release based on reports from users of the library. There are also improvements in documentation: exception classes are documented.
|
||||||
|
|
||||||
|
Changes from version 2.2.4
|
||||||
|
- Feature request [2857462]: Proposed minor extension: safe version of is_bom.
|
||||||
|
- Feature request [2885695]: "Group" utf8 exceptions.
|
||||||
|
- Bug fix [2906315]: < instead != in utf8to32.
|
||||||
|
- Bug fix [2915657]: 64bit portability issue.
|
||||||
|
- Bug fix [2960112]: is_bom wording fix.
|
||||||
|
|
||||||
|
Files included in the release: utf8.h, core.h, checked.h, unchecked.h, utf8cpp.html, ReleaseNotes
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,34 @@
|
|||||||
|
// Copyright 2006 Nemanja Trifunovic
|
||||||
|
|
||||||
|
/*
|
||||||
|
Permission is hereby granted, free of charge, to any person or organization
|
||||||
|
obtaining a copy of the software and accompanying documentation covered by
|
||||||
|
this license (the "Software") to use, reproduce, display, distribute,
|
||||||
|
execute, and transmit the Software, and to prepare derivative works of the
|
||||||
|
Software, and to permit third-parties to whom the Software is furnished to
|
||||||
|
do so, all subject to the following:
|
||||||
|
|
||||||
|
The copyright notices in the Software and this entire statement, including
|
||||||
|
the above license grant, this restriction and the following disclaimer,
|
||||||
|
must be included in all copies of the Software, in whole or in part, and
|
||||||
|
all derivative works of the Software, unless such copies or derivative
|
||||||
|
works are solely in the form of machine-executable object code generated by
|
||||||
|
a source language processor.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||||
|
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||||
|
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||||
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||||
|
#define UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||||
|
|
||||||
|
#include "utf8/checked.h"
|
||||||
|
#include "utf8/unchecked.h"
|
||||||
|
|
||||||
|
#endif // header guard
|
||||||
@@ -0,0 +1,323 @@
|
|||||||
|
// Copyright 2006 Nemanja Trifunovic
|
||||||
|
|
||||||
|
/*
|
||||||
|
Permission is hereby granted, free of charge, to any person or organization
|
||||||
|
obtaining a copy of the software and accompanying documentation covered by
|
||||||
|
this license (the "Software") to use, reproduce, display, distribute,
|
||||||
|
execute, and transmit the Software, and to prepare derivative works of the
|
||||||
|
Software, and to permit third-parties to whom the Software is furnished to
|
||||||
|
do so, all subject to the following:
|
||||||
|
|
||||||
|
The copyright notices in the Software and this entire statement, including
|
||||||
|
the above license grant, this restriction and the following disclaimer,
|
||||||
|
must be included in all copies of the Software, in whole or in part, and
|
||||||
|
all derivative works of the Software, unless such copies or derivative
|
||||||
|
works are solely in the form of machine-executable object code generated by
|
||||||
|
a source language processor.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||||
|
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||||
|
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||||
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||||
|
#define UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||||
|
|
||||||
|
#include "core.h"
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
namespace utf8
|
||||||
|
{
|
||||||
|
// Base for the exceptions that may be thrown from the library
|
||||||
|
class exception : public std::exception {
|
||||||
|
};
|
||||||
|
|
||||||
|
// Exceptions that may be thrown from the library functions.
|
||||||
|
class invalid_code_point : public exception {
|
||||||
|
uint32_t cp;
|
||||||
|
public:
|
||||||
|
invalid_code_point(uint32_t cp) : cp(cp) {}
|
||||||
|
virtual const char* what() const throw() { return "Invalid code point"; }
|
||||||
|
uint32_t code_point() const {return cp;}
|
||||||
|
};
|
||||||
|
|
||||||
|
class invalid_utf8 : public exception {
|
||||||
|
uint8_t u8;
|
||||||
|
public:
|
||||||
|
invalid_utf8 (uint8_t u) : u8(u) {}
|
||||||
|
virtual const char* what() const throw() { return "Invalid UTF-8"; }
|
||||||
|
uint8_t utf8_octet() const {return u8;}
|
||||||
|
};
|
||||||
|
|
||||||
|
class invalid_utf16 : public exception {
|
||||||
|
uint16_t u16;
|
||||||
|
public:
|
||||||
|
invalid_utf16 (uint16_t u) : u16(u) {}
|
||||||
|
virtual const char* what() const throw() { return "Invalid UTF-16"; }
|
||||||
|
uint16_t utf16_word() const {return u16;}
|
||||||
|
};
|
||||||
|
|
||||||
|
class not_enough_room : public exception {
|
||||||
|
public:
|
||||||
|
virtual const char* what() const throw() { return "Not enough space"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
/// The library API - functions intended to be called by the users
|
||||||
|
|
||||||
|
template <typename octet_iterator, typename output_iterator>
|
||||||
|
output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out, uint32_t replacement)
|
||||||
|
{
|
||||||
|
while (start != end) {
|
||||||
|
octet_iterator sequence_start = start;
|
||||||
|
internal::utf_error err_code = internal::validate_next(start, end);
|
||||||
|
switch (err_code) {
|
||||||
|
case internal::UTF8_OK :
|
||||||
|
for (octet_iterator it = sequence_start; it != start; ++it)
|
||||||
|
*out++ = *it;
|
||||||
|
break;
|
||||||
|
case internal::NOT_ENOUGH_ROOM:
|
||||||
|
throw not_enough_room();
|
||||||
|
case internal::INVALID_LEAD:
|
||||||
|
append (replacement, out);
|
||||||
|
++start;
|
||||||
|
break;
|
||||||
|
case internal::INCOMPLETE_SEQUENCE:
|
||||||
|
case internal::OVERLONG_SEQUENCE:
|
||||||
|
case internal::INVALID_CODE_POINT:
|
||||||
|
append (replacement, out);
|
||||||
|
++start;
|
||||||
|
// just one replacement mark for the sequence
|
||||||
|
while (internal::is_trail(*start) && start != end)
|
||||||
|
++start;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator, typename output_iterator>
|
||||||
|
inline output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out)
|
||||||
|
{
|
||||||
|
static const uint32_t replacement_marker = internal::mask16(0xfffd);
|
||||||
|
return replace_invalid(start, end, out, replacement_marker);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
octet_iterator append(uint32_t cp, octet_iterator result)
|
||||||
|
{
|
||||||
|
if (!internal::is_code_point_valid(cp))
|
||||||
|
throw invalid_code_point(cp);
|
||||||
|
|
||||||
|
if (cp < 0x80) // one octet
|
||||||
|
*(result++) = static_cast<uint8_t>(cp);
|
||||||
|
else if (cp < 0x800) { // two octets
|
||||||
|
*(result++) = static_cast<uint8_t>((cp >> 6) | 0xc0);
|
||||||
|
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
|
||||||
|
}
|
||||||
|
else if (cp < 0x10000) { // three octets
|
||||||
|
*(result++) = static_cast<uint8_t>((cp >> 12) | 0xe0);
|
||||||
|
*(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
|
||||||
|
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
|
||||||
|
}
|
||||||
|
else { // four octets
|
||||||
|
*(result++) = static_cast<uint8_t>((cp >> 18) | 0xf0);
|
||||||
|
*(result++) = static_cast<uint8_t>(((cp >> 12) & 0x3f) | 0x80);
|
||||||
|
*(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
|
||||||
|
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
uint32_t next(octet_iterator& it, octet_iterator end)
|
||||||
|
{
|
||||||
|
uint32_t cp = 0;
|
||||||
|
internal::utf_error err_code = internal::validate_next(it, end, &cp);
|
||||||
|
switch (err_code) {
|
||||||
|
case internal::UTF8_OK :
|
||||||
|
break;
|
||||||
|
case internal::NOT_ENOUGH_ROOM :
|
||||||
|
throw not_enough_room();
|
||||||
|
case internal::INVALID_LEAD :
|
||||||
|
case internal::INCOMPLETE_SEQUENCE :
|
||||||
|
case internal::OVERLONG_SEQUENCE :
|
||||||
|
throw invalid_utf8(*it);
|
||||||
|
case internal::INVALID_CODE_POINT :
|
||||||
|
throw invalid_code_point(cp);
|
||||||
|
}
|
||||||
|
return cp;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
uint32_t peek_next(octet_iterator it, octet_iterator end)
|
||||||
|
{
|
||||||
|
return next(it, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
uint32_t prior(octet_iterator& it, octet_iterator start)
|
||||||
|
{
|
||||||
|
octet_iterator end = it;
|
||||||
|
while (internal::is_trail(*(--it)))
|
||||||
|
if (it < start)
|
||||||
|
throw invalid_utf8(*it); // error - no lead byte in the sequence
|
||||||
|
octet_iterator temp = it;
|
||||||
|
return next(temp, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Deprecated in versions that include "prior"
|
||||||
|
template <typename octet_iterator>
|
||||||
|
uint32_t previous(octet_iterator& it, octet_iterator pass_start)
|
||||||
|
{
|
||||||
|
octet_iterator end = it;
|
||||||
|
while (internal::is_trail(*(--it)))
|
||||||
|
if (it == pass_start)
|
||||||
|
throw invalid_utf8(*it); // error - no lead byte in the sequence
|
||||||
|
octet_iterator temp = it;
|
||||||
|
return next(temp, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator, typename distance_type>
|
||||||
|
void advance (octet_iterator& it, distance_type n, octet_iterator end)
|
||||||
|
{
|
||||||
|
for (distance_type i = 0; i < n; ++i)
|
||||||
|
next(it, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
typename std::iterator_traits<octet_iterator>::difference_type
|
||||||
|
distance (octet_iterator first, octet_iterator last)
|
||||||
|
{
|
||||||
|
typename std::iterator_traits<octet_iterator>::difference_type dist;
|
||||||
|
for (dist = 0; first < last; ++dist)
|
||||||
|
next(first, last);
|
||||||
|
return dist;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename u16bit_iterator, typename octet_iterator>
|
||||||
|
octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result)
|
||||||
|
{
|
||||||
|
while (start != end) {
|
||||||
|
uint32_t cp = internal::mask16(*start++);
|
||||||
|
// Take care of surrogate pairs first
|
||||||
|
if (internal::is_lead_surrogate(cp)) {
|
||||||
|
if (start != end) {
|
||||||
|
uint32_t trail_surrogate = internal::mask16(*start++);
|
||||||
|
if (internal::is_trail_surrogate(trail_surrogate))
|
||||||
|
cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET;
|
||||||
|
else
|
||||||
|
throw invalid_utf16(static_cast<uint16_t>(trail_surrogate));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw invalid_utf16(static_cast<uint16_t>(cp));
|
||||||
|
|
||||||
|
}
|
||||||
|
// Lone trail surrogate
|
||||||
|
else if (internal::is_trail_surrogate(cp))
|
||||||
|
throw invalid_utf16(static_cast<uint16_t>(cp));
|
||||||
|
|
||||||
|
result = append(cp, result);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename u16bit_iterator, typename octet_iterator>
|
||||||
|
u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result)
|
||||||
|
{
|
||||||
|
while (start != end) {
|
||||||
|
uint32_t cp = next(start, end);
|
||||||
|
if (cp > 0xffff) { //make a surrogate pair
|
||||||
|
*result++ = static_cast<uint16_t>((cp >> 10) + internal::LEAD_OFFSET);
|
||||||
|
*result++ = static_cast<uint16_t>((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*result++ = static_cast<uint16_t>(cp);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator, typename u32bit_iterator>
|
||||||
|
octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result)
|
||||||
|
{
|
||||||
|
while (start != end)
|
||||||
|
result = append(*(start++), result);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator, typename u32bit_iterator>
|
||||||
|
u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result)
|
||||||
|
{
|
||||||
|
while (start != end)
|
||||||
|
(*result++) = next(start, end);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The iterator class
|
||||||
|
template <typename octet_iterator>
|
||||||
|
class iterator : public std::iterator <std::bidirectional_iterator_tag, uint32_t> {
|
||||||
|
octet_iterator it;
|
||||||
|
octet_iterator range_start;
|
||||||
|
octet_iterator range_end;
|
||||||
|
public:
|
||||||
|
iterator () {};
|
||||||
|
explicit iterator (const octet_iterator& octet_it,
|
||||||
|
const octet_iterator& range_start,
|
||||||
|
const octet_iterator& range_end) :
|
||||||
|
it(octet_it), range_start(range_start), range_end(range_end)
|
||||||
|
{
|
||||||
|
if (it < range_start || it > range_end)
|
||||||
|
throw std::out_of_range("Invalid utf-8 iterator position");
|
||||||
|
}
|
||||||
|
// the default "big three" are OK
|
||||||
|
octet_iterator base () const { return it; }
|
||||||
|
uint32_t operator * () const
|
||||||
|
{
|
||||||
|
octet_iterator temp = it;
|
||||||
|
return next(temp, range_end);
|
||||||
|
}
|
||||||
|
bool operator == (const iterator& rhs) const
|
||||||
|
{
|
||||||
|
if (range_start != rhs.range_start || range_end != rhs.range_end)
|
||||||
|
throw std::logic_error("Comparing utf-8 iterators defined with different ranges");
|
||||||
|
return (it == rhs.it);
|
||||||
|
}
|
||||||
|
bool operator != (const iterator& rhs) const
|
||||||
|
{
|
||||||
|
return !(operator == (rhs));
|
||||||
|
}
|
||||||
|
iterator& operator ++ ()
|
||||||
|
{
|
||||||
|
next(it, range_end);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
iterator operator ++ (int)
|
||||||
|
{
|
||||||
|
iterator temp = *this;
|
||||||
|
next(it, range_end);
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
iterator& operator -- ()
|
||||||
|
{
|
||||||
|
prior(it, range_start);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
iterator operator -- (int)
|
||||||
|
{
|
||||||
|
iterator temp = *this;
|
||||||
|
prior(it, range_start);
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
}; // class iterator
|
||||||
|
|
||||||
|
} // namespace utf8
|
||||||
|
|
||||||
|
#endif //header guard
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,358 @@
|
|||||||
|
// Copyright 2006 Nemanja Trifunovic
|
||||||
|
|
||||||
|
/*
|
||||||
|
Permission is hereby granted, free of charge, to any person or organization
|
||||||
|
obtaining a copy of the software and accompanying documentation covered by
|
||||||
|
this license (the "Software") to use, reproduce, display, distribute,
|
||||||
|
execute, and transmit the Software, and to prepare derivative works of the
|
||||||
|
Software, and to permit third-parties to whom the Software is furnished to
|
||||||
|
do so, all subject to the following:
|
||||||
|
|
||||||
|
The copyright notices in the Software and this entire statement, including
|
||||||
|
the above license grant, this restriction and the following disclaimer,
|
||||||
|
must be included in all copies of the Software, in whole or in part, and
|
||||||
|
all derivative works of the Software, unless such copies or derivative
|
||||||
|
works are solely in the form of machine-executable object code generated by
|
||||||
|
a source language processor.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||||
|
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||||
|
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||||
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||||
|
#define UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||||
|
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
|
namespace utf8
|
||||||
|
{
|
||||||
|
// The typedefs for 8-bit, 16-bit and 32-bit unsigned integers
|
||||||
|
// You may need to change them to match your system.
|
||||||
|
// These typedefs have the same names as ones from cstdint, or boost/cstdint
|
||||||
|
typedef unsigned char uint8_t;
|
||||||
|
typedef unsigned short uint16_t;
|
||||||
|
typedef unsigned int uint32_t;
|
||||||
|
|
||||||
|
// Helper code - not intended to be directly called by the library users. May be changed at any time
|
||||||
|
namespace internal
|
||||||
|
{
|
||||||
|
// Unicode constants
|
||||||
|
// Leading (high) surrogates: 0xd800 - 0xdbff
|
||||||
|
// Trailing (low) surrogates: 0xdc00 - 0xdfff
|
||||||
|
const uint16_t LEAD_SURROGATE_MIN = 0xd800u;
|
||||||
|
const uint16_t LEAD_SURROGATE_MAX = 0xdbffu;
|
||||||
|
const uint16_t TRAIL_SURROGATE_MIN = 0xdc00u;
|
||||||
|
const uint16_t TRAIL_SURROGATE_MAX = 0xdfffu;
|
||||||
|
const uint16_t LEAD_OFFSET = LEAD_SURROGATE_MIN - (0x10000 >> 10);
|
||||||
|
const uint32_t SURROGATE_OFFSET = 0x10000u - (LEAD_SURROGATE_MIN << 10) - TRAIL_SURROGATE_MIN;
|
||||||
|
|
||||||
|
// Maximum valid value for a Unicode code point
|
||||||
|
const uint32_t CODE_POINT_MAX = 0x0010ffffu;
|
||||||
|
|
||||||
|
template<typename octet_type>
|
||||||
|
inline uint8_t mask8(octet_type oc)
|
||||||
|
{
|
||||||
|
return static_cast<uint8_t>(0xff & oc);
|
||||||
|
}
|
||||||
|
template<typename u16_type>
|
||||||
|
inline uint16_t mask16(u16_type oc)
|
||||||
|
{
|
||||||
|
return static_cast<uint16_t>(0xffff & oc);
|
||||||
|
}
|
||||||
|
template<typename octet_type>
|
||||||
|
inline bool is_trail(octet_type oc)
|
||||||
|
{
|
||||||
|
return ((mask8(oc) >> 6) == 0x2);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename u16>
|
||||||
|
inline bool is_lead_surrogate(u16 cp)
|
||||||
|
{
|
||||||
|
return (cp >= LEAD_SURROGATE_MIN && cp <= LEAD_SURROGATE_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename u16>
|
||||||
|
inline bool is_trail_surrogate(u16 cp)
|
||||||
|
{
|
||||||
|
return (cp >= TRAIL_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename u16>
|
||||||
|
inline bool is_surrogate(u16 cp)
|
||||||
|
{
|
||||||
|
return (cp >= LEAD_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename u32>
|
||||||
|
inline bool is_code_point_valid(u32 cp)
|
||||||
|
{
|
||||||
|
return (cp <= CODE_POINT_MAX && !is_surrogate(cp) && cp != 0xfffe && cp != 0xffff);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
inline typename std::iterator_traits<octet_iterator>::difference_type
|
||||||
|
sequence_length(octet_iterator lead_it)
|
||||||
|
{
|
||||||
|
uint8_t lead = mask8(*lead_it);
|
||||||
|
if (lead < 0x80)
|
||||||
|
return 1;
|
||||||
|
else if ((lead >> 5) == 0x6)
|
||||||
|
return 2;
|
||||||
|
else if ((lead >> 4) == 0xe)
|
||||||
|
return 3;
|
||||||
|
else if ((lead >> 3) == 0x1e)
|
||||||
|
return 4;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_difference_type>
|
||||||
|
inline bool is_overlong_sequence(uint32_t cp, octet_difference_type length)
|
||||||
|
{
|
||||||
|
if (cp < 0x80) {
|
||||||
|
if (length != 1)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (cp < 0x800) {
|
||||||
|
if (length != 2)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (cp < 0x10000) {
|
||||||
|
if (length != 3)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum utf_error {UTF8_OK, NOT_ENOUGH_ROOM, INVALID_LEAD, INCOMPLETE_SEQUENCE, OVERLONG_SEQUENCE, INVALID_CODE_POINT};
|
||||||
|
|
||||||
|
/// get_sequence_x functions decode utf-8 sequences of the length x
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
utf_error get_sequence_1(octet_iterator& it, octet_iterator end, uint32_t* code_point)
|
||||||
|
{
|
||||||
|
if (it != end) {
|
||||||
|
if (code_point)
|
||||||
|
*code_point = mask8(*it);
|
||||||
|
return UTF8_OK;
|
||||||
|
}
|
||||||
|
return NOT_ENOUGH_ROOM;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
utf_error get_sequence_2(octet_iterator& it, octet_iterator end, uint32_t* code_point)
|
||||||
|
{
|
||||||
|
utf_error ret_code = NOT_ENOUGH_ROOM;
|
||||||
|
|
||||||
|
if (it != end) {
|
||||||
|
uint32_t cp = mask8(*it);
|
||||||
|
if (++it != end) {
|
||||||
|
if (is_trail(*it)) {
|
||||||
|
cp = ((cp << 6) & 0x7ff) + ((*it) & 0x3f);
|
||||||
|
|
||||||
|
if (code_point)
|
||||||
|
*code_point = cp;
|
||||||
|
ret_code = UTF8_OK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ret_code = INCOMPLETE_SEQUENCE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ret_code = NOT_ENOUGH_ROOM;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
utf_error get_sequence_3(octet_iterator& it, octet_iterator end, uint32_t* code_point)
|
||||||
|
{
|
||||||
|
utf_error ret_code = NOT_ENOUGH_ROOM;
|
||||||
|
|
||||||
|
if (it != end) {
|
||||||
|
uint32_t cp = mask8(*it);
|
||||||
|
if (++it != end) {
|
||||||
|
if (is_trail(*it)) {
|
||||||
|
cp = ((cp << 12) & 0xffff) + ((mask8(*it) << 6) & 0xfff);
|
||||||
|
if (++it != end) {
|
||||||
|
if (is_trail(*it)) {
|
||||||
|
cp += (*it) & 0x3f;
|
||||||
|
|
||||||
|
if (code_point)
|
||||||
|
*code_point = cp;
|
||||||
|
ret_code = UTF8_OK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ret_code = INCOMPLETE_SEQUENCE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ret_code = NOT_ENOUGH_ROOM;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ret_code = INCOMPLETE_SEQUENCE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ret_code = NOT_ENOUGH_ROOM;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
utf_error get_sequence_4(octet_iterator& it, octet_iterator end, uint32_t* code_point)
|
||||||
|
{
|
||||||
|
utf_error ret_code = NOT_ENOUGH_ROOM;
|
||||||
|
|
||||||
|
if (it != end) {
|
||||||
|
uint32_t cp = mask8(*it);
|
||||||
|
if (++it != end) {
|
||||||
|
if (is_trail(*it)) {
|
||||||
|
cp = ((cp << 18) & 0x1fffff) + ((mask8(*it) << 12) & 0x3ffff);
|
||||||
|
if (++it != end) {
|
||||||
|
if (is_trail(*it)) {
|
||||||
|
cp += (mask8(*it) << 6) & 0xfff;
|
||||||
|
if (++it != end) {
|
||||||
|
if (is_trail(*it)) {
|
||||||
|
cp += (*it) & 0x3f;
|
||||||
|
|
||||||
|
if (code_point)
|
||||||
|
*code_point = cp;
|
||||||
|
ret_code = UTF8_OK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ret_code = INCOMPLETE_SEQUENCE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ret_code = NOT_ENOUGH_ROOM;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ret_code = INCOMPLETE_SEQUENCE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ret_code = NOT_ENOUGH_ROOM;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ret_code = INCOMPLETE_SEQUENCE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ret_code = NOT_ENOUGH_ROOM;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
utf_error validate_next(octet_iterator& it, octet_iterator end, uint32_t* code_point)
|
||||||
|
{
|
||||||
|
// Save the original value of it so we can go back in case of failure
|
||||||
|
// Of course, it does not make much sense with i.e. stream iterators
|
||||||
|
octet_iterator original_it = it;
|
||||||
|
|
||||||
|
uint32_t cp = 0;
|
||||||
|
// Determine the sequence length based on the lead octet
|
||||||
|
typedef typename std::iterator_traits<octet_iterator>::difference_type octet_difference_type;
|
||||||
|
octet_difference_type length = sequence_length(it);
|
||||||
|
if (length == 0)
|
||||||
|
return INVALID_LEAD;
|
||||||
|
|
||||||
|
// Now that we have a valid sequence length, get trail octets and calculate the code point
|
||||||
|
utf_error err = UTF8_OK;
|
||||||
|
switch (length) {
|
||||||
|
case 1:
|
||||||
|
err = get_sequence_1(it, end, &cp);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
err = get_sequence_2(it, end, &cp);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
err = get_sequence_3(it, end, &cp);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
err = get_sequence_4(it, end, &cp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err == UTF8_OK) {
|
||||||
|
// Decoding succeeded. Now, security checks...
|
||||||
|
if (is_code_point_valid(cp)) {
|
||||||
|
if (!is_overlong_sequence(cp, length)){
|
||||||
|
// Passed! Return here.
|
||||||
|
if (code_point)
|
||||||
|
*code_point = cp;
|
||||||
|
++it;
|
||||||
|
return UTF8_OK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
err = OVERLONG_SEQUENCE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
err = INVALID_CODE_POINT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Failure branch - restore the original value of the iterator
|
||||||
|
it = original_it;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
inline utf_error validate_next(octet_iterator& it, octet_iterator end) {
|
||||||
|
return validate_next(it, end, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
/// The library API - functions intended to be called by the users
|
||||||
|
|
||||||
|
// Byte order mark
|
||||||
|
const uint8_t bom[] = {0xef, 0xbb, 0xbf};
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
octet_iterator find_invalid(octet_iterator start, octet_iterator end)
|
||||||
|
{
|
||||||
|
octet_iterator result = start;
|
||||||
|
while (result != end) {
|
||||||
|
internal::utf_error err_code = internal::validate_next(result, end);
|
||||||
|
if (err_code != internal::UTF8_OK)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
inline bool is_valid(octet_iterator start, octet_iterator end)
|
||||||
|
{
|
||||||
|
return (find_invalid(start, end) == end);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
inline bool starts_with_bom (octet_iterator it, octet_iterator end)
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
((it != end) && (internal::mask8(*it++)) == bom[0]) &&
|
||||||
|
((it != end) && (internal::mask8(*it++)) == bom[1]) &&
|
||||||
|
((it != end) && (internal::mask8(*it)) == bom[2])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Deprecated in release 2.3
|
||||||
|
template <typename octet_iterator>
|
||||||
|
inline bool is_bom (octet_iterator it)
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
(internal::mask8(*it++)) == bom[0] &&
|
||||||
|
(internal::mask8(*it++)) == bom[1] &&
|
||||||
|
(internal::mask8(*it)) == bom[2]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} // namespace utf8
|
||||||
|
|
||||||
|
#endif // header guard
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,228 @@
|
|||||||
|
// Copyright 2006 Nemanja Trifunovic
|
||||||
|
|
||||||
|
/*
|
||||||
|
Permission is hereby granted, free of charge, to any person or organization
|
||||||
|
obtaining a copy of the software and accompanying documentation covered by
|
||||||
|
this license (the "Software") to use, reproduce, display, distribute,
|
||||||
|
execute, and transmit the Software, and to prepare derivative works of the
|
||||||
|
Software, and to permit third-parties to whom the Software is furnished to
|
||||||
|
do so, all subject to the following:
|
||||||
|
|
||||||
|
The copyright notices in the Software and this entire statement, including
|
||||||
|
the above license grant, this restriction and the following disclaimer,
|
||||||
|
must be included in all copies of the Software, in whole or in part, and
|
||||||
|
all derivative works of the Software, unless such copies or derivative
|
||||||
|
works are solely in the form of machine-executable object code generated by
|
||||||
|
a source language processor.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||||
|
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||||
|
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||||
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||||
|
#define UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||||
|
|
||||||
|
#include "core.h"
|
||||||
|
|
||||||
|
namespace utf8
|
||||||
|
{
|
||||||
|
namespace unchecked
|
||||||
|
{
|
||||||
|
template <typename octet_iterator>
|
||||||
|
octet_iterator append(uint32_t cp, octet_iterator result)
|
||||||
|
{
|
||||||
|
if (cp < 0x80) // one octet
|
||||||
|
*(result++) = static_cast<uint8_t>(cp);
|
||||||
|
else if (cp < 0x800) { // two octets
|
||||||
|
*(result++) = static_cast<uint8_t>((cp >> 6) | 0xc0);
|
||||||
|
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
|
||||||
|
}
|
||||||
|
else if (cp < 0x10000) { // three octets
|
||||||
|
*(result++) = static_cast<uint8_t>((cp >> 12) | 0xe0);
|
||||||
|
*(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
|
||||||
|
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
|
||||||
|
}
|
||||||
|
else { // four octets
|
||||||
|
*(result++) = static_cast<uint8_t>((cp >> 18) | 0xf0);
|
||||||
|
*(result++) = static_cast<uint8_t>(((cp >> 12) & 0x3f)| 0x80);
|
||||||
|
*(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
|
||||||
|
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
uint32_t next(octet_iterator& it)
|
||||||
|
{
|
||||||
|
uint32_t cp = internal::mask8(*it);
|
||||||
|
typename std::iterator_traits<octet_iterator>::difference_type length = utf8::internal::sequence_length(it);
|
||||||
|
switch (length) {
|
||||||
|
case 1:
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
it++;
|
||||||
|
cp = ((cp << 6) & 0x7ff) + ((*it) & 0x3f);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
++it;
|
||||||
|
cp = ((cp << 12) & 0xffff) + ((internal::mask8(*it) << 6) & 0xfff);
|
||||||
|
++it;
|
||||||
|
cp += (*it) & 0x3f;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
++it;
|
||||||
|
cp = ((cp << 18) & 0x1fffff) + ((internal::mask8(*it) << 12) & 0x3ffff);
|
||||||
|
++it;
|
||||||
|
cp += (internal::mask8(*it) << 6) & 0xfff;
|
||||||
|
++it;
|
||||||
|
cp += (*it) & 0x3f;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++it;
|
||||||
|
return cp;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
uint32_t peek_next(octet_iterator it)
|
||||||
|
{
|
||||||
|
return next(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
uint32_t prior(octet_iterator& it)
|
||||||
|
{
|
||||||
|
while (internal::is_trail(*(--it))) ;
|
||||||
|
octet_iterator temp = it;
|
||||||
|
return next(temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated in versions that include prior, but only for the sake of consistency (see utf8::previous)
|
||||||
|
template <typename octet_iterator>
|
||||||
|
inline uint32_t previous(octet_iterator& it)
|
||||||
|
{
|
||||||
|
return prior(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator, typename distance_type>
|
||||||
|
void advance (octet_iterator& it, distance_type n)
|
||||||
|
{
|
||||||
|
for (distance_type i = 0; i < n; ++i)
|
||||||
|
next(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
typename std::iterator_traits<octet_iterator>::difference_type
|
||||||
|
distance (octet_iterator first, octet_iterator last)
|
||||||
|
{
|
||||||
|
typename std::iterator_traits<octet_iterator>::difference_type dist;
|
||||||
|
for (dist = 0; first < last; ++dist)
|
||||||
|
next(first);
|
||||||
|
return dist;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename u16bit_iterator, typename octet_iterator>
|
||||||
|
octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result)
|
||||||
|
{
|
||||||
|
while (start != end) {
|
||||||
|
uint32_t cp = internal::mask16(*start++);
|
||||||
|
// Take care of surrogate pairs first
|
||||||
|
if (internal::is_lead_surrogate(cp)) {
|
||||||
|
uint32_t trail_surrogate = internal::mask16(*start++);
|
||||||
|
cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET;
|
||||||
|
}
|
||||||
|
result = append(cp, result);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename u16bit_iterator, typename octet_iterator>
|
||||||
|
u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result)
|
||||||
|
{
|
||||||
|
while (start < end) {
|
||||||
|
uint32_t cp = next(start);
|
||||||
|
if (cp > 0xffff) { //make a surrogate pair
|
||||||
|
*result++ = static_cast<uint16_t>((cp >> 10) + internal::LEAD_OFFSET);
|
||||||
|
*result++ = static_cast<uint16_t>((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*result++ = static_cast<uint16_t>(cp);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator, typename u32bit_iterator>
|
||||||
|
octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result)
|
||||||
|
{
|
||||||
|
while (start != end)
|
||||||
|
result = append(*(start++), result);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator, typename u32bit_iterator>
|
||||||
|
u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result)
|
||||||
|
{
|
||||||
|
while (start < end)
|
||||||
|
(*result++) = next(start);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The iterator class
|
||||||
|
template <typename octet_iterator>
|
||||||
|
class iterator : public std::iterator <std::bidirectional_iterator_tag, uint32_t> {
|
||||||
|
octet_iterator it;
|
||||||
|
public:
|
||||||
|
iterator () {};
|
||||||
|
explicit iterator (const octet_iterator& octet_it): it(octet_it) {}
|
||||||
|
// the default "big three" are OK
|
||||||
|
octet_iterator base () const { return it; }
|
||||||
|
uint32_t operator * () const
|
||||||
|
{
|
||||||
|
octet_iterator temp = it;
|
||||||
|
return next(temp);
|
||||||
|
}
|
||||||
|
bool operator == (const iterator& rhs) const
|
||||||
|
{
|
||||||
|
return (it == rhs.it);
|
||||||
|
}
|
||||||
|
bool operator != (const iterator& rhs) const
|
||||||
|
{
|
||||||
|
return !(operator == (rhs));
|
||||||
|
}
|
||||||
|
iterator& operator ++ ()
|
||||||
|
{
|
||||||
|
std::advance(it, internal::sequence_length(it));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
iterator operator ++ (int)
|
||||||
|
{
|
||||||
|
iterator temp = *this;
|
||||||
|
std::advance(it, internal::sequence_length(it));
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
iterator& operator -- ()
|
||||||
|
{
|
||||||
|
prior(it);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
iterator operator -- (int)
|
||||||
|
{
|
||||||
|
iterator temp = *this;
|
||||||
|
prior(it);
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
}; // class iterator
|
||||||
|
|
||||||
|
} // namespace utf8::unchecked
|
||||||
|
} // namespace utf8
|
||||||
|
|
||||||
|
|
||||||
|
#endif // header guard
|
||||||
|
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
/*
|
||||||
|
* bfVFS : vfs/Aspects/vfs_logging.h
|
||||||
|
* - Logging interface and macros that will be used to report errors/warnings to the using program
|
||||||
|
*
|
||||||
|
* Copyright (C) 2008 - 2010 (BF) john.bf.smith@googlemail.com
|
||||||
|
*
|
||||||
|
* This file is part of the bfVFS library
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef VFS_LOGGING_H
|
||||||
|
#define VFS_LOGGING_H
|
||||||
|
|
||||||
|
#include <vfs/vfs_config.h>
|
||||||
|
|
||||||
|
namespace vfs
|
||||||
|
{
|
||||||
|
class String;
|
||||||
|
namespace Aspects
|
||||||
|
{
|
||||||
|
enum LogType { LOG_INFO, LOG_WARNING, LOG_ERROR, LOG_DEBUG };
|
||||||
|
|
||||||
|
class ILogger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void Msg(const wchar_t* msg) = 0;
|
||||||
|
virtual void Msg(const char* msg) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
VFS_API void setLogger(LogType type, ILogger* logger);
|
||||||
|
VFS_API ILogger* getLogger(LogType type);
|
||||||
|
|
||||||
|
VFS_API void setLogger( ILogger* info_logger, ILogger* warning_logger, ILogger* error_logger, ILogger* debug_logger );
|
||||||
|
|
||||||
|
void Debug(vfs::String const& msg);
|
||||||
|
void Debug(const wchar_t* msg);
|
||||||
|
void Debug(const char* msg);
|
||||||
|
|
||||||
|
void Info(vfs::String const& msg);
|
||||||
|
void Info(const wchar_t* msg);
|
||||||
|
void Info(const char* msg);
|
||||||
|
|
||||||
|
void Warning(vfs::String const& msg);
|
||||||
|
void Warning(const wchar_t* msg);
|
||||||
|
void Warning(const char* msg);
|
||||||
|
|
||||||
|
void Error(vfs::String const& msg);
|
||||||
|
void Error(const wchar_t* msg);
|
||||||
|
void Error(const char* msg);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#if !defined VFS_DISABLE_LOGGING
|
||||||
|
|
||||||
|
# if !defined VFS_LOG_DEBUG
|
||||||
|
# define VFS_LOG_DEBUG(msg) (vfs::Aspects::Debug(msg))
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# if !defined VFS_LOG_INFO
|
||||||
|
# define VFS_LOG_INFO(msg) (vfs::Aspects::Info(msg))
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# if !defined VFS_LOG_WARNING
|
||||||
|
# define VFS_LOG_WARNING(msg) (vfs::Aspects::Warning(msg))
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# if !defined VFS_LOG_ERROR
|
||||||
|
# define VFS_LOG_ERROR(msg) (vfs::Aspects::Error(msg))
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
# if !defined VFS_LOG_DEBUG
|
||||||
|
# define VFS_LOG_DEBUG(msg)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# if !defined VFS_LOG_INFO
|
||||||
|
# define VFS_LOG_INFO(msg)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# if !defined VFS_LOG_WARNING
|
||||||
|
# define VFS_LOG_WARNING(msg)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# if !defined VFS_LOG_ERROR
|
||||||
|
# define VFS_LOG_ERROR(msg)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#endif // VFS_DISABLE_LOGGING
|
||||||
|
|
||||||
|
#endif // VFS_LOGGING_H
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* bfVFS : vfs/Aspects/vfs_settings.h
|
||||||
|
* - library runtime settings,
|
||||||
|
* - e.g., to use Unicode strings or regular for file names
|
||||||
|
*
|
||||||
|
* Copyright (C) 2008 - 2010 (BF) john.bf.smith@googlemail.com
|
||||||
|
*
|
||||||
|
* This file is part of the bfVFS library
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _VFS_SETTIGNS_H_
|
||||||
|
#define _VFS_SETTIGNS_H_
|
||||||
|
|
||||||
|
#include <vfs/vfs_config.h>
|
||||||
|
|
||||||
|
namespace vfs
|
||||||
|
{
|
||||||
|
class VFS_API Settings
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static void setUseUnicode(bool useUnicode);
|
||||||
|
static bool getUseUnicode();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // _VFS_SETTIGNS_H_
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
* bfVFS : vfs/Aspects/vfs_synchronization.h
|
||||||
|
* - Interface for Mutexes and Locks, implementation can or has to be provided by the using program
|
||||||
|
*
|
||||||
|
* Copyright (C) 2008 - 2010 (BF) john.bf.smith@googlemail.com
|
||||||
|
*
|
||||||
|
* This file is part of the bfVFS library
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef VFS_SYNCHRONIZATION_H
|
||||||
|
#define VFS_SYNCHRONIZATION_H
|
||||||
|
|
||||||
|
#include <vfs/vfs_config.h>
|
||||||
|
|
||||||
|
namespace vfs
|
||||||
|
{
|
||||||
|
namespace Aspects
|
||||||
|
{
|
||||||
|
class IMutex
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void lock() {};
|
||||||
|
virtual void unlock() {};
|
||||||
|
};
|
||||||
|
|
||||||
|
class IMutexFactory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual IMutex* createMutex() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
VFS_API void setMutexFactory(IMutexFactory* mutex_factory);
|
||||||
|
VFS_API IMutexFactory* getMutexFactory();
|
||||||
|
|
||||||
|
class Mutex
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Mutex();
|
||||||
|
~Mutex();
|
||||||
|
|
||||||
|
void lock();
|
||||||
|
void unlock();
|
||||||
|
private:
|
||||||
|
int _locked;
|
||||||
|
IMutex* _mutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ScopedLock
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ScopedLock(Mutex& mutex) : _mutex(mutex) {
|
||||||
|
this->_mutex.lock();
|
||||||
|
}
|
||||||
|
~ScopedLock(){
|
||||||
|
this->_mutex.unlock();
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
Mutex& _mutex;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef VFS_SYNCHRONIZE
|
||||||
|
# if !defined VFS_LOCK
|
||||||
|
# define VFS_LOCK(mutex) vfs::Aspects::ScopedLock _scoped_lock(mutex)
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# if !defined VFS_LOCK
|
||||||
|
# define VFS_LOCK(mutex)
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // VFS_SYNCHRONIZATION_H
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* bfVFS : vfs/Core/File/vfs_buffer_file.h
|
||||||
|
* - Buffer in RAM, implements File interface to unify usage of file and memory
|
||||||
|
*
|
||||||
|
* Copyright (C) 2008 - 2010 (BF) john.bf.smith@googlemail.com
|
||||||
|
*
|
||||||
|
* This file is part of the bfVFS library
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _VFS_MEMORY_FILE_H_
|
||||||
|
#define _VFS_MEMORY_FILE_H_
|
||||||
|
|
||||||
|
#include <vfs/Core/Interface/vfs_file_interface.h>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
namespace vfs
|
||||||
|
{
|
||||||
|
class VFS_API CBufferFile : public vfs::TFileTemplate<vfs::IReadable,vfs::IWritable>
|
||||||
|
{
|
||||||
|
typedef vfs::TFileTemplate<vfs::IReadable,vfs::IWritable> tBaseClass;
|
||||||
|
public :
|
||||||
|
CBufferFile();
|
||||||
|
CBufferFile(vfs::Path const& filename);
|
||||||
|
virtual ~CBufferFile();
|
||||||
|
|
||||||
|
virtual vfs::FileAttributes getAttributes();
|
||||||
|
|
||||||
|
virtual void close();
|
||||||
|
virtual vfs::size_t getSize();
|
||||||
|
|
||||||
|
virtual bool isOpenRead();
|
||||||
|
virtual bool openRead();
|
||||||
|
virtual vfs::size_t read(vfs::Byte* data, vfs::size_t bytesToRead);
|
||||||
|
|
||||||
|
virtual vfs::size_t getReadPosition();
|
||||||
|
virtual void setReadPosition(vfs::size_t positionInBytes);
|
||||||
|
virtual void setReadPosition(vfs::offset_t offsetInBytes, vfs::IBaseFile::ESeekDir seekDir);
|
||||||
|
|
||||||
|
virtual bool isOpenWrite();
|
||||||
|
virtual bool openWrite(bool bCreateWhenNotExist = false, bool bTruncate = false);
|
||||||
|
virtual vfs::size_t write(const vfs::Byte* data, vfs::size_t bytesToWrite);
|
||||||
|
|
||||||
|
virtual vfs::size_t getWritePosition();
|
||||||
|
virtual void setWritePosition(vfs::size_t positionInBytes);
|
||||||
|
virtual void setWritePosition(vfs::offset_t offsetInBytes, vfs::IBaseFile::ESeekDir seekDir);
|
||||||
|
|
||||||
|
virtual bool deleteFile();
|
||||||
|
|
||||||
|
// convenience method
|
||||||
|
void copyToBuffer(vfs::tReadableFile& rFile);
|
||||||
|
protected:
|
||||||
|
std::stringstream m_buffer;
|
||||||
|
bool m_isOpen_read, m_isOpen_write;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace
|
||||||
|
|
||||||
|
#endif // _VFS_MEMORY_FILE_H_
|
||||||
|
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* bfVFS : vfs/Core/File/vfs_dir_file.h
|
||||||
|
* - read/read-write files for usage in vfs locations
|
||||||
|
*
|
||||||
|
* Copyright (C) 2008 - 2010 (BF) john.bf.smith@googlemail.com
|
||||||
|
*
|
||||||
|
* This file is part of the bfVFS library
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _VFS_DIR_FILE_H_
|
||||||
|
#define _VFS_DIR_FILE_H_
|
||||||
|
|
||||||
|
#include <vfs/Core/File/vfs_file.h>
|
||||||
|
|
||||||
|
#include <vfs/Core/Interface/vfs_file_interface.h>
|
||||||
|
#include <vfs/Core/Interface/vfs_location_interface.h>
|
||||||
|
#include <vfs/Core/Interface/vfs_directory_interface.h>
|
||||||
|
|
||||||
|
namespace vfs
|
||||||
|
{
|
||||||
|
class VFS_API CReadOnlyDirFile : public vfs::CReadOnlyFile
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
typedef vfs::TDirectory<vfs::CReadOnlyDirFile::write_type> tLocation;
|
||||||
|
public:
|
||||||
|
CReadOnlyDirFile(vfs::Path const& filename, tLocation *directory);
|
||||||
|
virtual ~CReadOnlyDirFile();
|
||||||
|
|
||||||
|
virtual vfs::FileAttributes getAttributes();
|
||||||
|
|
||||||
|
virtual vfs::Path getPath();
|
||||||
|
|
||||||
|
virtual bool openRead();
|
||||||
|
|
||||||
|
virtual bool _getRealPath(vfs::Path& path);
|
||||||
|
private:
|
||||||
|
tLocation* _location;
|
||||||
|
};
|
||||||
|
|
||||||
|
class VFS_API CDirFile : public vfs::CFile
|
||||||
|
{
|
||||||
|
typedef vfs::TDirectory<vfs::CFile::write_type> tLocation;
|
||||||
|
public:
|
||||||
|
CDirFile(vfs::Path const& filename, tLocation *directory);
|
||||||
|
virtual ~CDirFile();
|
||||||
|
|
||||||
|
virtual vfs::FileAttributes getAttributes();
|
||||||
|
|
||||||
|
virtual vfs::Path getPath();
|
||||||
|
virtual bool deleteFile();
|
||||||
|
|
||||||
|
virtual bool openRead();
|
||||||
|
virtual bool openWrite(bool createWhenNotExist = false, bool truncate = false);
|
||||||
|
|
||||||
|
virtual bool _getRealPath(vfs::Path& path);
|
||||||
|
private:
|
||||||
|
tLocation* _location;
|
||||||
|
};
|
||||||
|
} // end namespace
|
||||||
|
|
||||||
|
#endif // _VFS_DIR_FILE_H_
|
||||||
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user