Skip to content

Instantly share code, notes, and snippets.

@0rphon
Created August 31, 2023 23:13
Show Gist options
  • Save 0rphon/8e7ae101ab2a2d08eaab2a226aa8e90c to your computer and use it in GitHub Desktop.
Save 0rphon/8e7ae101ab2a2d08eaab2a226aa8e90c to your computer and use it in GitHub Desktop.
fix
This file has been truncated, but you can view the full file.
diff --strip-trailing-cr -NBbaur squashfs-tools/compressor.c squashfs-tools-patched/compressor.c
--- squashfs-tools/compressor.c 2016-08-25 09:06:22.983529595 -0400
+++ squashfs-tools-patched/compressor.c 2016-08-25 09:06:03.223530354 -0400
@@ -25,6 +25,9 @@
#include "compressor.h"
#include "squashfs_fs.h"
+// CJH: Added these includes
+#include "error.h"
+
#ifndef GZIP_SUPPORT
static struct compressor gzip_comp_ops = {
ZLIB_COMPRESSION, "gzip"
@@ -65,6 +68,9 @@
extern struct compressor xz_comp_ops;
#endif
+extern struct compressor lzma_alt_comp_ops;
+extern struct compressor lzma_wrt_comp_ops;
+extern struct compressor lzma_adaptive_comp_ops;
static struct compressor unknown_comp_ops = {
0, "unknown"
@@ -74,6 +80,10 @@
struct compressor *compressor[] = {
&gzip_comp_ops,
&lzma_comp_ops,
+ // CJH: Added additional LZMA decompressors. Order is intentional.
+ &lzma_adaptive_comp_ops,
+ &lzma_alt_comp_ops,
+ &lzma_wrt_comp_ops,
&lzo_comp_ops,
&lz4_comp_ops,
&xz_comp_ops,
@@ -81,6 +91,19 @@
};
+int lookup_compressor_index(char *name)
+{
+ int i;
+
+ for(i = 0; compressor[i]->id; i++)
+ {
+ if(strcmp(name, compressor[i]->name) == 0)
+ return i;
+ }
+
+ return -1;
+}
+
struct compressor *lookup_compressor(char *name)
{
int i;
@@ -135,3 +158,67 @@
compressor[i]->name, str);
}
}
+
+// CJH: calls the currently selected decompressor, unless that fails, then tries the other decompressors
+int detected_compressor_index = 0;
+int compressor_uncompress(struct compressor *comp, void *dest, void *src, int size, int block_size, int *error)
+{
+ int i = 0, retval = -1, default_compressor_id = -1;
+
+ if(detected_compressor_index)
+ {
+ retval = compressor[detected_compressor_index]->uncompress(dest, src, size, block_size, error);
+ }
+
+ if(retval < 1 && comp->uncompress)
+ {
+ if(!detected_compressor_index) ERROR("Trying to decompress using default %s decompressor...\n", comp->name);
+
+ retval = comp->uncompress(dest, src, size, block_size, error);
+
+ if(!detected_compressor_index)
+ {
+ if(retval > 0)
+ {
+ ERROR("Successfully decompressed with default %s decompressor\n", comp->name);
+ detected_compressor_index = lookup_compressor_index(comp->name);
+ }
+ else
+ {
+ TRACE("Default %s decompressor failed! [%d %d]\n", comp->name, retval, *error);
+ }
+ }
+ }
+
+ if(retval < 1)
+ {
+ default_compressor_id = comp->id;
+
+ for(i=0; compressor[i]->id; i++)
+ {
+ comp = compressor[i];
+
+ if(comp->id != default_compressor_id &&
+ comp->id != compressor[detected_compressor_index]->id &&
+ comp->uncompress)
+ {
+ ERROR("Trying to decompress with %s...\n", comp->name);
+ retval = comp->uncompress(dest, src, size, block_size, error);
+ if(retval > 0)
+ {
+ //TRACE("%s decompressor succeeded!\n", comp->name);
+ ERROR("Detected %s compression\n", comp->name);
+ detected_compressor_index = i;
+ break;
+ }
+ else
+ {
+ TRACE("%s decompressor failed! [%d %d]\n", comp->name, retval, *error);
+ }
+ }
+ }
+ }
+
+ return retval;
+}
+
diff --strip-trailing-cr -NBbaur squashfs-tools/compressor.h squashfs-tools-patched/compressor.h
--- squashfs-tools/compressor.h 2016-08-25 09:06:22.983529595 -0400
+++ squashfs-tools-patched/compressor.h 2016-08-25 09:06:03.223530354 -0400
@@ -59,11 +59,14 @@
}
+/* CJH: Needed more logic for compression auto-detection, no longer inlined
static inline int compressor_uncompress(struct compressor *comp, void *dest,
void *src, int size, int block_size, int *error)
{
return comp->uncompress(dest, src, size, block_size, error);
}
+*/
+int compressor_uncompress(struct compressor *comp, void *dest, void *src, int size, int block_size, int *error);
/*
diff --strip-trailing-cr -NBbaur squashfs-tools/error.h squashfs-tools-patched/error.h
--- squashfs-tools/error.h 2016-08-25 09:06:22.983529595 -0400
+++ squashfs-tools-patched/error.h 2016-08-25 09:06:03.223530354 -0400
@@ -30,14 +30,18 @@
extern void progressbar_error(char *fmt, ...);
extern void progressbar_info(char *fmt, ...);
-#ifdef SQUASHFS_TRACE
+// CJH: Updated so that TRACE prints if -verbose is specified on the command line
+// int verbose;
+//#ifdef SQUASHFS_TRACE
#define TRACE(s, args...) \
do { \
- progressbar_info("squashfs: "s, ## args);\
+ progressbar_info("squashfs: "s, ## args);\
} while(0)
+/*
#else
#define TRACE(s, args...)
#endif
+*/
#define INFO(s, args...) \
do {\
diff --strip-trailing-cr -NBbaur squashfs-tools/LICENSE squashfs-tools-patched/LICENSE
--- squashfs-tools/LICENSE 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LICENSE 2016-08-25 09:06:03.223530354 -0400
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 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.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, 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 or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+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 give any other recipients of the Program a copy of this License
+along with the Program.
+
+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 Program or any portion
+of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+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 Program, 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 Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) 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; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, 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 executable. However, as a
+special exception, the source code 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.
+
+If distribution of executable or 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 counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program 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.
+
+ 5. 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 Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program 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 to
+this License.
+
+ 7. 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 Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program 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 Program.
+
+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.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program 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.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the 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 Program
+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 Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, 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
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. 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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), 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 Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. 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 program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; 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.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/7zC.txt squashfs-tools-patched/LZMA/lzma465/7zC.txt
--- squashfs-tools/LZMA/lzma465/7zC.txt 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/7zC.txt 2016-08-25 09:06:03.231530353 -0400
@@ -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
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/7zFormat.txt squashfs-tools-patched/LZMA/lzma465/7zFormat.txt
--- squashfs-tools/LZMA/lzma465/7zFormat.txt 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/7zFormat.txt 2016-08-25 09:06:03.231530353 -0400
@@ -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
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/7zBuf2.c squashfs-tools-patched/LZMA/lzma465/C/7zBuf2.c
--- squashfs-tools/LZMA/lzma465/C/7zBuf2.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/7zBuf2.c 2016-08-25 09:06:03.231530353 -0400
@@ -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;
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/7zBuf.c squashfs-tools-patched/LZMA/lzma465/C/7zBuf.c
--- squashfs-tools/LZMA/lzma465/C/7zBuf.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/7zBuf.c 2016-08-25 09:06:03.231530353 -0400
@@ -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;
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/7zBuf.h squashfs-tools-patched/LZMA/lzma465/C/7zBuf.h
--- squashfs-tools/LZMA/lzma465/C/7zBuf.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/7zBuf.h 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,31 @@
+/* 7zBuf.h -- Byte Buffer
+2008-10-04 : Igor Pavlov : Public domain */
+
+#ifndef __7Z_BUF_H
+#define __7Z_BUF_H
+
+#include "Types.h"
+
+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);
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/7zCrc.c squashfs-tools-patched/LZMA/lzma465/C/7zCrc.c
--- squashfs-tools/LZMA/lzma465/C/7zCrc.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/7zCrc.c 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,35 @@
+/* 7zCrc.c -- CRC32 calculation
+2008-08-05
+Igor Pavlov
+Public domain */
+
+#include "7zCrc.h"
+
+#define kCrcPoly 0xEDB88320
+UInt32 g_CrcTable[256];
+
+void MY_FAST_CALL CrcGenerateTable(void)
+{
+ UInt32 i;
+ for (i = 0; i < 256; i++)
+ {
+ UInt32 r = i;
+ int j;
+ for (j = 0; j < 8; j++)
+ r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
+ g_CrcTable[i] = r;
+ }
+}
+
+UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size)
+{
+ const Byte *p = (const Byte *)data;
+ for (; size > 0 ; size--, p++)
+ v = CRC_UPDATE_BYTE(v, *p);
+ return v;
+}
+
+UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size)
+{
+ return CrcUpdate(CRC_INIT_VAL, data, size) ^ 0xFFFFFFFF;
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/7zCrc.h squashfs-tools-patched/LZMA/lzma465/C/7zCrc.h
--- squashfs-tools/LZMA/lzma465/C/7zCrc.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/7zCrc.h 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,24 @@
+/* 7zCrc.h -- CRC32 calculation
+2008-03-13
+Igor Pavlov
+Public domain */
+
+#ifndef __7Z_CRC_H
+#define __7Z_CRC_H
+
+#include <stddef.h>
+
+#include "Types.h"
+
+extern UInt32 g_CrcTable[];
+
+void MY_FAST_CALL CrcGenerateTable(void);
+
+#define CRC_INIT_VAL 0xFFFFFFFF
+#define CRC_GET_DIGEST(crc) ((crc) ^ 0xFFFFFFFF)
+#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);
+UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size);
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/7zFile.c squashfs-tools-patched/LZMA/lzma465/C/7zFile.c
--- squashfs-tools/LZMA/lzma465/C/7zFile.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/7zFile.c 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,263 @@
+/* 7zFile.c -- File IO
+2008-11-22 : Igor Pavlov : Public domain */
+
+#include "7zFile.h"
+
+#ifndef USE_WINDOWS_FILE
+
+#include <errno.h>
+
+#endif
+
+#ifdef USE_WINDOWS_FILE
+
+/*
+ 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
+}
+
+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 : errno;
+ #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); }
+
+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;
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/7zFile.h squashfs-tools-patched/LZMA/lzma465/C/7zFile.h
--- squashfs-tools/LZMA/lzma465/C/7zFile.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/7zFile.h 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,74 @@
+/* 7zFile.h -- File IO
+2008-11-22 : 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"
+
+
+/* ---------- File ---------- */
+
+typedef struct
+{
+ #ifdef USE_WINDOWS_FILE
+ HANDLE handle;
+ #else
+ FILE *file;
+ #endif
+} CSzFile;
+
+void File_Construct(CSzFile *p);
+WRes InFile_Open(CSzFile *p, const char *name);
+WRes OutFile_Open(CSzFile *p, const char *name);
+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);
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/7zStream.c squashfs-tools-patched/LZMA/lzma465/C/7zStream.c
--- squashfs-tools/LZMA/lzma465/C/7zStream.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/7zStream.c 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,169 @@
+/* 7zStream.c -- 7z Stream functions
+2008-11-23 : 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)
+{
+ 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, 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, 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;
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/7zVersion.h squashfs-tools-patched/LZMA/lzma465/C/7zVersion.h
--- squashfs-tools/LZMA/lzma465/C/7zVersion.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/7zVersion.h 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,7 @@
+#define MY_VER_MAJOR 4
+#define MY_VER_MINOR 65
+#define MY_VER_BUILD 0
+#define MY_VERSION "4.65"
+#define MY_DATE "2009-02-03"
+#define MY_COPYRIGHT ": Igor Pavlov : Public domain"
+#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/Alloc.c squashfs-tools-patched/LZMA/lzma465/C/Alloc.c
--- squashfs-tools/LZMA/lzma465/C/Alloc.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/Alloc.c 2016-08-25 09:06:03.231530353 -0400
@@ -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
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/Alloc.h squashfs-tools-patched/LZMA/lzma465/C/Alloc.h
--- squashfs-tools/LZMA/lzma465/C/Alloc.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/Alloc.h 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,32 @@
+/* Alloc.h -- Memory allocation functions
+2008-03-13
+Igor Pavlov
+Public domain */
+
+#ifndef __COMMON_ALLOC_H
+#define __COMMON_ALLOC_H
+
+#include <stddef.h>
+
+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
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/Archive/7z/7zAlloc.c squashfs-tools-patched/LZMA/lzma465/C/Archive/7z/7zAlloc.c
--- squashfs-tools/LZMA/lzma465/C/Archive/7z/7zAlloc.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/Archive/7z/7zAlloc.c 2016-08-25 09:06:03.231530353 -0400
@@ -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);
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/Archive/7z/7zAlloc.h squashfs-tools-patched/LZMA/lzma465/C/Archive/7z/7zAlloc.h
--- squashfs-tools/LZMA/lzma465/C/Archive/7z/7zAlloc.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/Archive/7z/7zAlloc.h 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,15 @@
+/* 7zAlloc.h -- Allocation functions
+2008-10-04 : Igor Pavlov : Public domain */
+
+#ifndef __7Z_ALLOC_H
+#define __7Z_ALLOC_H
+
+#include <stddef.h>
+
+void *SzAlloc(void *p, size_t size);
+void SzFree(void *p, void *address);
+
+void *SzAllocTemp(void *p, size_t size);
+void SzFreeTemp(void *p, void *address);
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/Archive/7z/7zDecode.c squashfs-tools-patched/LZMA/lzma465/C/Archive/7z/7zDecode.c
--- squashfs-tools/LZMA/lzma465/C/Archive/7z/7zDecode.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/Archive/7z/7zDecode.c 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,254 @@
+/* 7zDecode.c -- Decoding from 7z folder
+2008-11-23 : Igor Pavlov : Public domain */
+
+#include <string.h>
+
+#include "../../Bcj2.h"
+#include "../../Bra.h"
+#include "../../LzmaDec.h"
+#include "7zDecode.h"
+
+#define k_Copy 0
+#define k_LZMA 0x30101
+#define k_BCJ 0x03030103
+#define k_BCJ2 0x0303011B
+
+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, (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 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, (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;
+}
+
+#define IS_UNSUPPORTED_METHOD(m) ((m) != k_Copy && (m) != k_LZMA)
+#define IS_UNSUPPORTED_CODER(c) (IS_UNSUPPORTED_METHOD(c.MethodID) || c.NumInStreams != 1 || c.NumOutStreams != 1)
+#define IS_NO_BCJ(c) (c.MethodID != k_BCJ || c.NumInStreams != 1 || c.NumOutStreams != 1)
+#define IS_NO_BCJ2(c) (c.MethodID != k_BCJ2 || c.NumInStreams != 4 || c.NumOutStreams != 1)
+
+SRes CheckSupportedFolder(const CSzFolder *f)
+{
+ if (f->NumCoders < 1 || f->NumCoders > 4)
+ return SZ_ERROR_UNSUPPORTED;
+ if (IS_UNSUPPORTED_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_NO_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_UNSUPPORTED_CODER(f->Coders[1]) ||
+ IS_UNSUPPORTED_CODER(f->Coders[2]) ||
+ IS_NO_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;
+}
+
+UInt64 GetSum(const UInt64 *values, UInt32 index)
+{
+ UInt64 sum = 0;
+ UInt32 i;
+ for (i = 0; i < index; i++)
+ sum += values[i];
+ return sum;
+}
+
+SRes SzDecode2(const UInt64 *packSizes, const CSzFolder *folder,
+ 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 (coder->MethodID == k_Copy || coder->MethodID == k_LZMA)
+ {
+ 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
+ {
+ RINOK(SzDecodeLzma(coder, inSize, inStream, outBufCur, outSizeCur, allocMain));
+ }
+ }
+ 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 SzDecode(const UInt64 *packSizes, const CSzFolder *folder,
+ ILookInStream *inStream, UInt64 startPos,
+ Byte *outBuffer, size_t outSize, ISzAlloc *allocMain)
+{
+ Byte *tempBuf[3] = { 0, 0, 0};
+ int i;
+ SRes res = SzDecode2(packSizes, folder, inStream, startPos,
+ outBuffer, (SizeT)outSize, allocMain, tempBuf);
+ for (i = 0; i < 3; i++)
+ IAlloc_Free(allocMain, tempBuf[i]);
+ return res;
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/Archive/7z/7zDecode.h squashfs-tools-patched/LZMA/lzma465/C/Archive/7z/7zDecode.h
--- squashfs-tools/LZMA/lzma465/C/Archive/7z/7zDecode.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/Archive/7z/7zDecode.h 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,13 @@
+/* 7zDecode.h -- Decoding from 7z folder
+2008-11-23 : Igor Pavlov : Public domain */
+
+#ifndef __7Z_DECODE_H
+#define __7Z_DECODE_H
+
+#include "7zItem.h"
+
+SRes SzDecode(const UInt64 *packSizes, const CSzFolder *folder,
+ ILookInStream *stream, UInt64 startPos,
+ Byte *outBuffer, size_t outSize, ISzAlloc *allocMain);
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/Archive/7z/7z.dsp squashfs-tools-patched/LZMA/lzma465/C/Archive/7z/7z.dsp
--- squashfs-tools/LZMA/lzma465/C/Archive/7z/7z.dsp 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/Archive/7z/7z.dsp 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,199 @@
+# Microsoft Developer Studio Project File - Name="7z" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=7z - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "7z.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "7z.mak" CFG="7z - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "7z - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "7z - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /FAs /YX /FD /c
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"Release/7zDec.exe" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /W4 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_SZ_ALLOC_DEBUG2" /D "_SZ_NO_INT_64_A" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x419 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"Debug/7zDec.exe" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "7z - Win32 Release"
+# Name "7z - Win32 Debug"
+# Begin Group "Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\7zBuf.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\7zBuf.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\7zCrc.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\7zCrc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\7zFile.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\7zFile.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\7zStream.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Bcj2.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Bcj2.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Bra.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Bra86.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\LzmaDec.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\LzmaDec.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Types.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\7zAlloc.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zAlloc.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zDecode.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zDecode.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zExtract.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zExtract.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zHeader.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zHeader.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zIn.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zIn.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zItem.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zItem.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zMain.c
+# End Source File
+# End Target
+# End Project
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/Archive/7z/7z.dsw squashfs-tools-patched/LZMA/lzma465/C/Archive/7z/7z.dsw
--- squashfs-tools/LZMA/lzma465/C/Archive/7z/7z.dsw 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/Archive/7z/7z.dsw 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "7z"=.\7z.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/Archive/7z/7zExtract.c squashfs-tools-patched/LZMA/lzma465/C/Archive/7z/7zExtract.c
--- squashfs-tools/LZMA/lzma465/C/Archive/7z/7zExtract.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/Archive/7z/7zExtract.c 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,93 @@
+/* 7zExtract.c -- Extracting from 7z archive
+2008-11-23 : Igor Pavlov : Public domain */
+
+#include "../../7zCrc.h"
+#include "7zDecode.h"
+#include "7zExtract.h"
+
+SRes SzAr_Extract(
+ const CSzArEx *p,
+ ILookInStream *inStream,
+ UInt32 fileIndex,
+ UInt32 *blockIndex,
+ Byte **outBuffer,
+ size_t *outBufferSize,
+ size_t *offset,
+ size_t *outSizeProcessed,
+ ISzAlloc *allocMain,
+ ISzAlloc *allocTemp)
+{
+ UInt32 folderIndex = p->FileIndexToFolderIndexMap[fileIndex];
+ SRes res = SZ_OK;
+ *offset = 0;
+ *outSizeProcessed = 0;
+ if (folderIndex == (UInt32)-1)
+ {
+ IAlloc_Free(allocMain, *outBuffer);
+ *blockIndex = folderIndex;
+ *outBuffer = 0;
+ *outBufferSize = 0;
+ return SZ_OK;
+ }
+
+ if (*outBuffer == 0 || *blockIndex != folderIndex)
+ {
+ CSzFolder *folder = p->db.Folders + folderIndex;
+ UInt64 unpackSizeSpec = SzFolder_GetUnpackSize(folder);
+ size_t unpackSize = (size_t)unpackSizeSpec;
+ UInt64 startOffset = SzArEx_GetFolderStreamPos(p, folderIndex, 0);
+
+ if (unpackSize != unpackSizeSpec)
+ return SZ_ERROR_MEM;
+ *blockIndex = folderIndex;
+ IAlloc_Free(allocMain, *outBuffer);
+ *outBuffer = 0;
+
+ RINOK(LookInStream_SeekTo(inStream, startOffset));
+
+ if (res == SZ_OK)
+ {
+ *outBufferSize = unpackSize;
+ if (unpackSize != 0)
+ {
+ *outBuffer = (Byte *)IAlloc_Alloc(allocMain, unpackSize);
+ if (*outBuffer == 0)
+ res = SZ_ERROR_MEM;
+ }
+ if (res == SZ_OK)
+ {
+ res = SzDecode(p->db.PackSizes +
+ p->FolderStartPackStreamIndex[folderIndex], folder,
+ inStream, startOffset,
+ *outBuffer, unpackSize, allocTemp);
+ if (res == SZ_OK)
+ {
+ if (folder->UnpackCRCDefined)
+ {
+ if (CrcCalc(*outBuffer, unpackSize) != folder->UnpackCRC)
+ res = SZ_ERROR_CRC;
+ }
+ }
+ }
+ }
+ }
+ if (res == SZ_OK)
+ {
+ UInt32 i;
+ CSzFileItem *fileItem = p->db.Files + fileIndex;
+ *offset = 0;
+ for (i = p->FolderStartFileIndex[folderIndex]; i < fileIndex; i++)
+ *offset += (UInt32)p->db.Files[i].Size;
+ *outSizeProcessed = (size_t)fileItem->Size;
+ if (*offset + *outSizeProcessed > *outBufferSize)
+ return SZ_ERROR_FAIL;
+ {
+ if (fileItem->FileCRCDefined)
+ {
+ if (CrcCalc(*outBuffer + *offset, *outSizeProcessed) != fileItem->FileCRC)
+ res = SZ_ERROR_CRC;
+ }
+ }
+ }
+ return res;
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/Archive/7z/7zExtract.h squashfs-tools-patched/LZMA/lzma465/C/Archive/7z/7zExtract.h
--- squashfs-tools/LZMA/lzma465/C/Archive/7z/7zExtract.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/Archive/7z/7zExtract.h 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,41 @@
+/* 7zExtract.h -- Extracting from 7z archive
+2008-11-23 : Igor Pavlov : Public domain */
+
+#ifndef __7Z_EXTRACT_H
+#define __7Z_EXTRACT_H
+
+#include "7zIn.h"
+
+/*
+ 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.
+*/
+
+SRes SzAr_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);
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/Archive/7z/7zHeader.c squashfs-tools-patched/LZMA/lzma465/C/Archive/7z/7zHeader.c
--- squashfs-tools/LZMA/lzma465/C/Archive/7z/7zHeader.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/Archive/7z/7zHeader.c 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,6 @@
+/* 7zHeader.c -- 7z Headers
+2008-10-04 : Igor Pavlov : Public domain */
+
+#include "7zHeader.h"
+
+Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/Archive/7z/7zHeader.h squashfs-tools-patched/LZMA/lzma465/C/Archive/7z/7zHeader.h
--- squashfs-tools/LZMA/lzma465/C/Archive/7z/7zHeader.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/Archive/7z/7zHeader.h 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,57 @@
+/* 7zHeader.h -- 7z Headers
+2008-10-04 : Igor Pavlov : Public domain */
+
+#ifndef __7Z_HEADER_H
+#define __7Z_HEADER_H
+
+#include "../../Types.h"
+
+#define k7zSignatureSize 6
+extern Byte k7zSignature[k7zSignatureSize];
+
+#define k7zMajorVersion 0
+
+#define k7zStartHeaderSize 0x20
+
+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
+};
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/Archive/7z/7zIn.c squashfs-tools-patched/LZMA/lzma465/C/Archive/7z/7zIn.c
--- squashfs-tools/LZMA/lzma465/C/Archive/7z/7zIn.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/Archive/7z/7zIn.c 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,1204 @@
+/* 7zIn.c -- 7z Input functions
+2008-12-31 : Igor Pavlov : Public domain */
+
+#include "../../7zCrc.h"
+#include "../../CpuArch.h"
+
+#include "7zDecode.h"
+#include "7zIn.h"
+
+#define RINOM(x) { if ((x) == 0) return SZ_ERROR_MEM; }
+
+#define NUM_FOLDER_CODERS_MAX 32
+#define NUM_CODER_STREAMS_MAX 32
+
+void SzArEx_Init(CSzArEx *p)
+{
+ SzAr_Init(&p->db);
+ p->FolderStartPackStreamIndex = 0;
+ p->PackStreamStartPositions = 0;
+ p->FolderStartFileIndex = 0;
+ p->FileIndexToFolderIndexMap = 0;
+}
+
+void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc)
+{
+ IAlloc_Free(alloc, p->FolderStartPackStreamIndex);
+ IAlloc_Free(alloc, p->PackStreamStartPositions);
+ IAlloc_Free(alloc, p->FolderStartFileIndex);
+ IAlloc_Free(alloc, p->FileIndexToFolderIndexMap);
+ SzAr_Free(&p->db, alloc);
+ SzArEx_Init(p);
+}
+
+/*
+UInt64 GetFolderPackStreamSize(int folderIndex, int streamIndex) const
+{
+ return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex];
+}
+
+UInt64 GetFilePackSize(int fileIndex) const
+{
+ int folderIndex = FileIndexToFolderIndexMap[fileIndex];
+ if (folderIndex >= 0)
+ {
+ const CSzFolder &folderInfo = Folders[folderIndex];
+ if (FolderStartFileIndex[folderIndex] == fileIndex)
+ return GetFolderFullPackSize(folderIndex);
+ }
+ return 0;
+}
+*/
+
+#define MY_ALLOC(T, p, size, alloc) { if ((size) == 0) p = 0; else \
+ if ((p = (T *)IAlloc_Alloc(alloc, (size) * sizeof(T))) == 0) return SZ_ERROR_MEM; }
+
+static SRes SzArEx_Fill(CSzArEx *p, ISzAlloc *alloc)
+{
+ UInt32 startPos = 0;
+ UInt64 startPosSize = 0;
+ UInt32 i;
+ UInt32 folderIndex = 0;
+ UInt32 indexInFolder = 0;
+ MY_ALLOC(UInt32, p->FolderStartPackStreamIndex, p->db.NumFolders, alloc);
+ for (i = 0; i < p->db.NumFolders; i++)
+ {
+ p->FolderStartPackStreamIndex[i] = startPos;
+ startPos += p->db.Folders[i].NumPackStreams;
+ }
+
+ MY_ALLOC(UInt64, p->PackStreamStartPositions, p->db.NumPackStreams, alloc);
+
+ for (i = 0; i < p->db.NumPackStreams; i++)
+ {
+ p->PackStreamStartPositions[i] = startPosSize;
+ startPosSize += p->db.PackSizes[i];
+ }
+
+ MY_ALLOC(UInt32, p->FolderStartFileIndex, p->db.NumFolders, alloc);
+ MY_ALLOC(UInt32, p->FileIndexToFolderIndexMap, p->db.NumFiles, alloc);
+
+ for (i = 0; i < p->db.NumFiles; i++)
+ {
+ CSzFileItem *file = p->db.Files + i;
+ int emptyStream = !file->HasStream;
+ if (emptyStream && indexInFolder == 0)
+ {
+ p->FileIndexToFolderIndexMap[i] = (UInt32)-1;
+ continue;
+ }
+ if (indexInFolder == 0)
+ {
+ /*
+ v3.13 incorrectly worked with empty folders
+ v4.07: Loop for skipping empty folders
+ */
+ for (;;)
+ {
+ if (folderIndex >= p->db.NumFolders)
+ return SZ_ERROR_ARCHIVE;
+ p->FolderStartFileIndex[folderIndex] = i;
+ if (p->db.Folders[folderIndex].NumUnpackStreams != 0)
+ break;
+ folderIndex++;
+ }
+ }
+ p->FileIndexToFolderIndexMap[i] = folderIndex;
+ if (emptyStream)
+ continue;
+ indexInFolder++;
+ if (indexInFolder >= p->db.Folders[folderIndex].NumUnpackStreams)
+ {
+ folderIndex++;
+ indexInFolder = 0;
+ }
+ }
+ return SZ_OK;
+}
+
+
+UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder)
+{
+ return p->dataPos +
+ p->PackStreamStartPositions[p->FolderStartPackStreamIndex[folderIndex] + indexInFolder];
+}
+
+int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize)
+{
+ UInt32 packStreamIndex = p->FolderStartPackStreamIndex[folderIndex];
+ CSzFolder *folder = p->db.Folders + folderIndex;
+ UInt64 size = 0;
+ UInt32 i;
+ for (i = 0; i < folder->NumPackStreams; i++)
+ {
+ UInt64 t = size + p->db.PackSizes[packStreamIndex + i];
+ if (t < size) /* check it */
+ return SZ_ERROR_FAIL;
+ size = t;
+ }
+ *resSize = size;
+ return SZ_OK;
+}
+
+
+/*
+SRes SzReadTime(const CObjectVector<CBuf> &dataVector,
+ CObjectVector<CSzFileItem> &files, UInt64 type)
+{
+ CBoolVector boolVector;
+ RINOK(ReadBoolVector2(files.Size(), boolVector))
+
+ CStreamSwitch streamSwitch;
+ RINOK(streamSwitch.Set(this, &dataVector));
+
+ for (int i = 0; i < files.Size(); i++)
+ {
+ CSzFileItem &file = files[i];
+ CArchiveFileTime fileTime;
+ bool defined = boolVector[i];
+ if (defined)
+ {
+ UInt32 low, high;
+ RINOK(SzReadUInt32(low));
+ RINOK(SzReadUInt32(high));
+ fileTime.dwLowDateTime = low;
+ fileTime.dwHighDateTime = high;
+ }
+ switch(type)
+ {
+ case k7zIdCTime: file.IsCTimeDefined = defined; if (defined) file.CTime = fileTime; break;
+ case k7zIdATime: file.IsATimeDefined = defined; if (defined) file.ATime = fileTime; break;
+ case k7zIdMTime: file.IsMTimeDefined = defined; if (defined) file.MTime = fileTime; break;
+ }
+ }
+ return SZ_OK;
+}
+*/
+
+static int TestSignatureCandidate(Byte *testBytes)
+{
+ size_t i;
+ for (i = 0; i < k7zSignatureSize; i++)
+ if (testBytes[i] != k7zSignature[i])
+ return 0;
+ return 1;
+}
+
+typedef struct _CSzState
+{
+ Byte *Data;
+ size_t Size;
+}CSzData;
+
+static SRes SzReadByte(CSzData *sd, Byte *b)
+{
+ if (sd->Size == 0)
+ return SZ_ERROR_ARCHIVE;
+ sd->Size--;
+ *b = *sd->Data++;
+ return SZ_OK;
+}
+
+static SRes SzReadBytes(CSzData *sd, Byte *data, size_t size)
+{
+ size_t i;
+ for (i = 0; i < size; i++)
+ {
+ RINOK(SzReadByte(sd, data + i));
+ }
+ return SZ_OK;
+}
+
+static SRes SzReadUInt32(CSzData *sd, UInt32 *value)
+{
+ int i;
+ *value = 0;
+ for (i = 0; i < 4; i++)
+ {
+ Byte b;
+ RINOK(SzReadByte(sd, &b));
+ *value |= ((UInt32)(b) << (8 * i));
+ }
+ return SZ_OK;
+}
+
+static SRes SzReadNumber(CSzData *sd, UInt64 *value)
+{
+ Byte firstByte;
+ Byte mask = 0x80;
+ int i;
+ RINOK(SzReadByte(sd, &firstByte));
+ *value = 0;
+ for (i = 0; i < 8; i++)
+ {
+ Byte b;
+ if ((firstByte & mask) == 0)
+ {
+ UInt64 highPart = firstByte & (mask - 1);
+ *value += (highPart << (8 * i));
+ return SZ_OK;
+ }
+ RINOK(SzReadByte(sd, &b));
+ *value |= ((UInt64)b << (8 * i));
+ mask >>= 1;
+ }
+ return SZ_OK;
+}
+
+static SRes SzReadNumber32(CSzData *sd, UInt32 *value)
+{
+ UInt64 value64;
+ RINOK(SzReadNumber(sd, &value64));
+ if (value64 >= 0x80000000)
+ return SZ_ERROR_UNSUPPORTED;
+ if (value64 >= ((UInt64)(1) << ((sizeof(size_t) - 1) * 8 + 2)))
+ return SZ_ERROR_UNSUPPORTED;
+ *value = (UInt32)value64;
+ return SZ_OK;
+}
+
+static SRes SzReadID(CSzData *sd, UInt64 *value)
+{
+ return SzReadNumber(sd, value);
+}
+
+static SRes SzSkeepDataSize(CSzData *sd, UInt64 size)
+{
+ if (size > sd->Size)
+ return SZ_ERROR_ARCHIVE;
+ sd->Size -= (size_t)size;
+ sd->Data += (size_t)size;
+ return SZ_OK;
+}
+
+static SRes SzSkeepData(CSzData *sd)
+{
+ UInt64 size;
+ RINOK(SzReadNumber(sd, &size));
+ return SzSkeepDataSize(sd, size);
+}
+
+static SRes SzReadArchiveProperties(CSzData *sd)
+{
+ for (;;)
+ {
+ UInt64 type;
+ RINOK(SzReadID(sd, &type));
+ if (type == k7zIdEnd)
+ break;
+ SzSkeepData(sd);
+ }
+ return SZ_OK;
+}
+
+static SRes SzWaitAttribute(CSzData *sd, UInt64 attribute)
+{
+ for (;;)
+ {
+ UInt64 type;
+ RINOK(SzReadID(sd, &type));
+ if (type == attribute)
+ return SZ_OK;
+ if (type == k7zIdEnd)
+ return SZ_ERROR_ARCHIVE;
+ RINOK(SzSkeepData(sd));
+ }
+}
+
+static SRes SzReadBoolVector(CSzData *sd, size_t numItems, Byte **v, ISzAlloc *alloc)
+{
+ Byte b = 0;
+ Byte mask = 0;
+ size_t i;
+ MY_ALLOC(Byte, *v, numItems, alloc);
+ for (i = 0; i < numItems; i++)
+ {
+ if (mask == 0)
+ {
+ RINOK(SzReadByte(sd, &b));
+ mask = 0x80;
+ }
+ (*v)[i] = (Byte)(((b & mask) != 0) ? 1 : 0);
+ mask >>= 1;
+ }
+ return SZ_OK;
+}
+
+static SRes SzReadBoolVector2(CSzData *sd, size_t numItems, Byte **v, ISzAlloc *alloc)
+{
+ Byte allAreDefined;
+ size_t i;
+ RINOK(SzReadByte(sd, &allAreDefined));
+ if (allAreDefined == 0)
+ return SzReadBoolVector(sd, numItems, v, alloc);
+ MY_ALLOC(Byte, *v, numItems, alloc);
+ for (i = 0; i < numItems; i++)
+ (*v)[i] = 1;
+ return SZ_OK;
+}
+
+static SRes SzReadHashDigests(
+ CSzData *sd,
+ size_t numItems,
+ Byte **digestsDefined,
+ UInt32 **digests,
+ ISzAlloc *alloc)
+{
+ size_t i;
+ RINOK(SzReadBoolVector2(sd, numItems, digestsDefined, alloc));
+ MY_ALLOC(UInt32, *digests, numItems, alloc);
+ for (i = 0; i < numItems; i++)
+ if ((*digestsDefined)[i])
+ {
+ RINOK(SzReadUInt32(sd, (*digests) + i));
+ }
+ return SZ_OK;
+}
+
+static SRes SzReadPackInfo(
+ CSzData *sd,
+ UInt64 *dataOffset,
+ UInt32 *numPackStreams,
+ UInt64 **packSizes,
+ Byte **packCRCsDefined,
+ UInt32 **packCRCs,
+ ISzAlloc *alloc)
+{
+ UInt32 i;
+ RINOK(SzReadNumber(sd, dataOffset));
+ RINOK(SzReadNumber32(sd, numPackStreams));
+
+ RINOK(SzWaitAttribute(sd, k7zIdSize));
+
+ MY_ALLOC(UInt64, *packSizes, (size_t)*numPackStreams, alloc);
+
+ for (i = 0; i < *numPackStreams; i++)
+ {
+ RINOK(SzReadNumber(sd, (*packSizes) + i));
+ }
+
+ for (;;)
+ {
+ UInt64 type;
+ RINOK(SzReadID(sd, &type));
+ if (type == k7zIdEnd)
+ break;
+ if (type == k7zIdCRC)
+ {
+ RINOK(SzReadHashDigests(sd, (size_t)*numPackStreams, packCRCsDefined, packCRCs, alloc));
+ continue;
+ }
+ RINOK(SzSkeepData(sd));
+ }
+ if (*packCRCsDefined == 0)
+ {
+ MY_ALLOC(Byte, *packCRCsDefined, (size_t)*numPackStreams, alloc);
+ MY_ALLOC(UInt32, *packCRCs, (size_t)*numPackStreams, alloc);
+ for (i = 0; i < *numPackStreams; i++)
+ {
+ (*packCRCsDefined)[i] = 0;
+ (*packCRCs)[i] = 0;
+ }
+ }
+ return SZ_OK;
+}
+
+static SRes SzReadSwitch(CSzData *sd)
+{
+ Byte external;
+ RINOK(SzReadByte(sd, &external));
+ return (external == 0) ? SZ_OK: SZ_ERROR_UNSUPPORTED;
+}
+
+static SRes SzGetNextFolderItem(CSzData *sd, CSzFolder *folder, ISzAlloc *alloc)
+{
+ UInt32 numCoders, numBindPairs, numPackStreams, i;
+ UInt32 numInStreams = 0, numOutStreams = 0;
+
+ RINOK(SzReadNumber32(sd, &numCoders));
+ if (numCoders > NUM_FOLDER_CODERS_MAX)
+ return SZ_ERROR_UNSUPPORTED;
+ folder->NumCoders = numCoders;
+
+ MY_ALLOC(CSzCoderInfo, folder->Coders, (size_t)numCoders, alloc);
+
+ for (i = 0; i < numCoders; i++)
+ SzCoderInfo_Init(folder->Coders + i);
+
+ for (i = 0; i < numCoders; i++)
+ {
+ Byte mainByte;
+ CSzCoderInfo *coder = folder->Coders + i;
+ {
+ unsigned idSize, j;
+ Byte longID[15];
+ RINOK(SzReadByte(sd, &mainByte));
+ idSize = (unsigned)(mainByte & 0xF);
+ RINOK(SzReadBytes(sd, longID, idSize));
+ if (idSize > sizeof(coder->MethodID))
+ return SZ_ERROR_UNSUPPORTED;
+ coder->MethodID = 0;
+ for (j = 0; j < idSize; j++)
+ coder->MethodID |= (UInt64)longID[idSize - 1 - j] << (8 * j);
+
+ if ((mainByte & 0x10) != 0)
+ {
+ RINOK(SzReadNumber32(sd, &coder->NumInStreams));
+ RINOK(SzReadNumber32(sd, &coder->NumOutStreams));
+ if (coder->NumInStreams > NUM_CODER_STREAMS_MAX ||
+ coder->NumOutStreams > NUM_CODER_STREAMS_MAX)
+ return SZ_ERROR_UNSUPPORTED;
+ }
+ else
+ {
+ coder->NumInStreams = 1;
+ coder->NumOutStreams = 1;
+ }
+ if ((mainByte & 0x20) != 0)
+ {
+ UInt64 propertiesSize = 0;
+ RINOK(SzReadNumber(sd, &propertiesSize));
+ if (!Buf_Create(&coder->Props, (size_t)propertiesSize, alloc))
+ return SZ_ERROR_MEM;
+ RINOK(SzReadBytes(sd, coder->Props.data, (size_t)propertiesSize));
+ }
+ }
+ while ((mainByte & 0x80) != 0)
+ {
+ RINOK(SzReadByte(sd, &mainByte));
+ RINOK(SzSkeepDataSize(sd, (mainByte & 0xF)));
+ if ((mainByte & 0x10) != 0)
+ {
+ UInt32 n;
+ RINOK(SzReadNumber32(sd, &n));
+ RINOK(SzReadNumber32(sd, &n));
+ }
+ if ((mainByte & 0x20) != 0)
+ {
+ UInt64 propertiesSize = 0;
+ RINOK(SzReadNumber(sd, &propertiesSize));
+ RINOK(SzSkeepDataSize(sd, propertiesSize));
+ }
+ }
+ numInStreams += coder->NumInStreams;
+ numOutStreams += coder->NumOutStreams;
+ }
+
+ if (numOutStreams == 0)
+ return SZ_ERROR_UNSUPPORTED;
+
+ folder->NumBindPairs = numBindPairs = numOutStreams - 1;
+ MY_ALLOC(CBindPair, folder->BindPairs, (size_t)numBindPairs, alloc);
+
+ for (i = 0; i < numBindPairs; i++)
+ {
+ CBindPair *bp = folder->BindPairs + i;
+ RINOK(SzReadNumber32(sd, &bp->InIndex));
+ RINOK(SzReadNumber32(sd, &bp->OutIndex));
+ }
+
+ if (numInStreams < numBindPairs)
+ return SZ_ERROR_UNSUPPORTED;
+
+ folder->NumPackStreams = numPackStreams = numInStreams - numBindPairs;
+ MY_ALLOC(UInt32, folder->PackStreams, (size_t)numPackStreams, alloc);
+
+ if (numPackStreams == 1)
+ {
+ for (i = 0; i < numInStreams ; i++)
+ if (SzFolder_FindBindPairForInStream(folder, i) < 0)
+ break;
+ if (i == numInStreams)
+ return SZ_ERROR_UNSUPPORTED;
+ folder->PackStreams[0] = i;
+ }
+ else
+ for (i = 0; i < numPackStreams; i++)
+ {
+ RINOK(SzReadNumber32(sd, folder->PackStreams + i));
+ }
+ return SZ_OK;
+}
+
+static SRes SzReadUnpackInfo(
+ CSzData *sd,
+ UInt32 *numFolders,
+ CSzFolder **folders, /* for alloc */
+ ISzAlloc *alloc,
+ ISzAlloc *allocTemp)
+{
+ UInt32 i;
+ RINOK(SzWaitAttribute(sd, k7zIdFolder));
+ RINOK(SzReadNumber32(sd, numFolders));
+ {
+ RINOK(SzReadSwitch(sd));
+
+ MY_ALLOC(CSzFolder, *folders, (size_t)*numFolders, alloc);
+
+ for (i = 0; i < *numFolders; i++)
+ SzFolder_Init((*folders) + i);
+
+ for (i = 0; i < *numFolders; i++)
+ {
+ RINOK(SzGetNextFolderItem(sd, (*folders) + i, alloc));
+ }
+ }
+
+ RINOK(SzWaitAttribute(sd, k7zIdCodersUnpackSize));
+
+ for (i = 0; i < *numFolders; i++)
+ {
+ UInt32 j;
+ CSzFolder *folder = (*folders) + i;
+ UInt32 numOutStreams = SzFolder_GetNumOutStreams(folder);
+
+ MY_ALLOC(UInt64, folder->UnpackSizes, (size_t)numOutStreams, alloc);
+
+ for (j = 0; j < numOutStreams; j++)
+ {
+ RINOK(SzReadNumber(sd, folder->UnpackSizes + j));
+ }
+ }
+
+ for (;;)
+ {
+ UInt64 type;
+ RINOK(SzReadID(sd, &type));
+ if (type == k7zIdEnd)
+ return SZ_OK;
+ if (type == k7zIdCRC)
+ {
+ SRes res;
+ Byte *crcsDefined = 0;
+ UInt32 *crcs = 0;
+ res = SzReadHashDigests(sd, *numFolders, &crcsDefined, &crcs, allocTemp);
+ if (res == SZ_OK)
+ {
+ for (i = 0; i < *numFolders; i++)
+ {
+ CSzFolder *folder = (*folders) + i;
+ folder->UnpackCRCDefined = crcsDefined[i];
+ folder->UnpackCRC = crcs[i];
+ }
+ }
+ IAlloc_Free(allocTemp, crcs);
+ IAlloc_Free(allocTemp, crcsDefined);
+ RINOK(res);
+ continue;
+ }
+ RINOK(SzSkeepData(sd));
+ }
+}
+
+static SRes SzReadSubStreamsInfo(
+ CSzData *sd,
+ UInt32 numFolders,
+ CSzFolder *folders,
+ UInt32 *numUnpackStreams,
+ UInt64 **unpackSizes,
+ Byte **digestsDefined,
+ UInt32 **digests,
+ ISzAlloc *allocTemp)
+{
+ UInt64 type = 0;
+ UInt32 i;
+ UInt32 si = 0;
+ UInt32 numDigests = 0;
+
+ for (i = 0; i < numFolders; i++)
+ folders[i].NumUnpackStreams = 1;
+ *numUnpackStreams = numFolders;
+
+ for (;;)
+ {
+ RINOK(SzReadID(sd, &type));
+ if (type == k7zIdNumUnpackStream)
+ {
+ *numUnpackStreams = 0;
+ for (i = 0; i < numFolders; i++)
+ {
+ UInt32 numStreams;
+ RINOK(SzReadNumber32(sd, &numStreams));
+ folders[i].NumUnpackStreams = numStreams;
+ *numUnpackStreams += numStreams;
+ }
+ continue;
+ }
+ if (type == k7zIdCRC || type == k7zIdSize)
+ break;
+ if (type == k7zIdEnd)
+ break;
+ RINOK(SzSkeepData(sd));
+ }
+
+ if (*numUnpackStreams == 0)
+ {
+ *unpackSizes = 0;
+ *digestsDefined = 0;
+ *digests = 0;
+ }
+ else
+ {
+ *unpackSizes = (UInt64 *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(UInt64));
+ RINOM(*unpackSizes);
+ *digestsDefined = (Byte *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(Byte));
+ RINOM(*digestsDefined);
+ *digests = (UInt32 *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(UInt32));
+ RINOM(*digests);
+ }
+
+ for (i = 0; i < numFolders; i++)
+ {
+ /*
+ v3.13 incorrectly worked with empty folders
+ v4.07: we check that folder is empty
+ */
+ UInt64 sum = 0;
+ UInt32 j;
+ UInt32 numSubstreams = folders[i].NumUnpackStreams;
+ if (numSubstreams == 0)
+ continue;
+ if (type == k7zIdSize)
+ for (j = 1; j < numSubstreams; j++)
+ {
+ UInt64 size;
+ RINOK(SzReadNumber(sd, &size));
+ (*unpackSizes)[si++] = size;
+ sum += size;
+ }
+ (*unpackSizes)[si++] = SzFolder_GetUnpackSize(folders + i) - sum;
+ }
+ if (type == k7zIdSize)
+ {
+ RINOK(SzReadID(sd, &type));
+ }
+
+ for (i = 0; i < *numUnpackStreams; i++)
+ {
+ (*digestsDefined)[i] = 0;
+ (*digests)[i] = 0;
+ }
+
+
+ for (i = 0; i < numFolders; i++)
+ {
+ UInt32 numSubstreams = folders[i].NumUnpackStreams;
+ if (numSubstreams != 1 || !folders[i].UnpackCRCDefined)
+ numDigests += numSubstreams;
+ }
+
+
+ si = 0;
+ for (;;)
+ {
+ if (type == k7zIdCRC)
+ {
+ int digestIndex = 0;
+ Byte *digestsDefined2 = 0;
+ UInt32 *digests2 = 0;
+ SRes res = SzReadHashDigests(sd, numDigests, &digestsDefined2, &digests2, allocTemp);
+ if (res == SZ_OK)
+ {
+ for (i = 0; i < numFolders; i++)
+ {
+ CSzFolder *folder = folders + i;
+ UInt32 numSubstreams = folder->NumUnpackStreams;
+ if (numSubstreams == 1 && folder->UnpackCRCDefined)
+ {
+ (*digestsDefined)[si] = 1;
+ (*digests)[si] = folder->UnpackCRC;
+ si++;
+ }
+ else
+ {
+ UInt32 j;
+ for (j = 0; j < numSubstreams; j++, digestIndex++)
+ {
+ (*digestsDefined)[si] = digestsDefined2[digestIndex];
+ (*digests)[si] = digests2[digestIndex];
+ si++;
+ }
+ }
+ }
+ }
+ IAlloc_Free(allocTemp, digestsDefined2);
+ IAlloc_Free(allocTemp, digests2);
+ RINOK(res);
+ }
+ else if (type == k7zIdEnd)
+ return SZ_OK;
+ else
+ {
+ RINOK(SzSkeepData(sd));
+ }
+ RINOK(SzReadID(sd, &type));
+ }
+}
+
+
+static SRes SzReadStreamsInfo(
+ CSzData *sd,
+ UInt64 *dataOffset,
+ CSzAr *p,
+ UInt32 *numUnpackStreams,
+ UInt64 **unpackSizes, /* allocTemp */
+ Byte **digestsDefined, /* allocTemp */
+ UInt32 **digests, /* allocTemp */
+ ISzAlloc *alloc,
+ ISzAlloc *allocTemp)
+{
+ for (;;)
+ {
+ UInt64 type;
+ RINOK(SzReadID(sd, &type));
+ if ((UInt64)(int)type != type)
+ return SZ_ERROR_UNSUPPORTED;
+ switch((int)type)
+ {
+ case k7zIdEnd:
+ return SZ_OK;
+ case k7zIdPackInfo:
+ {
+ RINOK(SzReadPackInfo(sd, dataOffset, &p->NumPackStreams,
+ &p->PackSizes, &p->PackCRCsDefined, &p->PackCRCs, alloc));
+ break;
+ }
+ case k7zIdUnpackInfo:
+ {
+ RINOK(SzReadUnpackInfo(sd, &p->NumFolders, &p->Folders, alloc, allocTemp));
+ break;
+ }
+ case k7zIdSubStreamsInfo:
+ {
+ RINOK(SzReadSubStreamsInfo(sd, p->NumFolders, p->Folders,
+ numUnpackStreams, unpackSizes, digestsDefined, digests, allocTemp));
+ break;
+ }
+ default:
+ return SZ_ERROR_UNSUPPORTED;
+ }
+ }
+}
+
+Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
+
+static SRes SzReadFileNames(CSzData *sd, UInt32 numFiles, CSzFileItem *files, ISzAlloc *alloc)
+{
+ UInt32 i;
+ for (i = 0; i < numFiles; i++)
+ {
+ UInt32 len = 0;
+ UInt32 pos = 0;
+ CSzFileItem *file = files + i;
+ while (pos + 2 <= sd->Size)
+ {
+ int numAdds;
+ UInt32 value = (UInt32)(sd->Data[pos] | (((UInt32)sd->Data[pos + 1]) << 8));
+ pos += 2;
+ len++;
+ if (value == 0)
+ break;
+ if (value < 0x80)
+ continue;
+ if (value >= 0xD800 && value < 0xE000)
+ {
+ UInt32 c2;
+ if (value >= 0xDC00)
+ return SZ_ERROR_ARCHIVE;
+ if (pos + 2 > sd->Size)
+ return SZ_ERROR_ARCHIVE;
+ c2 = (UInt32)(sd->Data[pos] | (((UInt32)sd->Data[pos + 1]) << 8));
+ pos += 2;
+ if (c2 < 0xDC00 || c2 >= 0xE000)
+ return SZ_ERROR_ARCHIVE;
+ value = ((value - 0xD800) << 10) | (c2 - 0xDC00);
+ }
+ for (numAdds = 1; numAdds < 5; numAdds++)
+ if (value < (((UInt32)1) << (numAdds * 5 + 6)))
+ break;
+ len += numAdds;
+ }
+
+ MY_ALLOC(char, file->Name, (size_t)len, alloc);
+
+ len = 0;
+ while (2 <= sd->Size)
+ {
+ int numAdds;
+ UInt32 value = (UInt32)(sd->Data[0] | (((UInt32)sd->Data[1]) << 8));
+ SzSkeepDataSize(sd, 2);
+ if (value < 0x80)
+ {
+ file->Name[len++] = (char)value;
+ if (value == 0)
+ break;
+ continue;
+ }
+ if (value >= 0xD800 && value < 0xE000)
+ {
+ UInt32 c2 = (UInt32)(sd->Data[0] | (((UInt32)sd->Data[1]) << 8));
+ SzSkeepDataSize(sd, 2);
+ value = ((value - 0xD800) << 10) | (c2 - 0xDC00);
+ }
+ for (numAdds = 1; numAdds < 5; numAdds++)
+ if (value < (((UInt32)1) << (numAdds * 5 + 6)))
+ break;
+ file->Name[len++] = (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds)));
+ do
+ {
+ numAdds--;
+ file->Name[len++] = (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F));
+ }
+ while (numAdds > 0);
+
+ len += numAdds;
+ }
+ }
+ return SZ_OK;
+}
+
+static SRes SzReadHeader2(
+ CSzArEx *p, /* allocMain */
+ CSzData *sd,
+ UInt64 **unpackSizes, /* allocTemp */
+ Byte **digestsDefined, /* allocTemp */
+ UInt32 **digests, /* allocTemp */
+ Byte **emptyStreamVector, /* allocTemp */
+ Byte **emptyFileVector, /* allocTemp */
+ Byte **lwtVector, /* allocTemp */
+ ISzAlloc *allocMain,
+ ISzAlloc *allocTemp)
+{
+ UInt64 type;
+ UInt32 numUnpackStreams = 0;
+ UInt32 numFiles = 0;
+ CSzFileItem *files = 0;
+ UInt32 numEmptyStreams = 0;
+ UInt32 i;
+
+ RINOK(SzReadID(sd, &type));
+
+ if (type == k7zIdArchiveProperties)
+ {
+ RINOK(SzReadArchiveProperties(sd));
+ RINOK(SzReadID(sd, &type));
+ }
+
+
+ if (type == k7zIdMainStreamsInfo)
+ {
+ RINOK(SzReadStreamsInfo(sd,
+ &p->dataPos,
+ &p->db,
+ &numUnpackStreams,
+ unpackSizes,
+ digestsDefined,
+ digests, allocMain, allocTemp));
+ p->dataPos += p->startPosAfterHeader;
+ RINOK(SzReadID(sd, &type));
+ }
+
+ if (type == k7zIdEnd)
+ return SZ_OK;
+ if (type != k7zIdFilesInfo)
+ return SZ_ERROR_ARCHIVE;
+
+ RINOK(SzReadNumber32(sd, &numFiles));
+ p->db.NumFiles = numFiles;
+
+ MY_ALLOC(CSzFileItem, files, (size_t)numFiles, allocMain);
+
+ p->db.Files = files;
+ for (i = 0; i < numFiles; i++)
+ SzFile_Init(files + i);
+
+ for (;;)
+ {
+ UInt64 type;
+ UInt64 size;
+ RINOK(SzReadID(sd, &type));
+ if (type == k7zIdEnd)
+ break;
+ RINOK(SzReadNumber(sd, &size));
+
+ if ((UInt64)(int)type != type)
+ {
+ RINOK(SzSkeepDataSize(sd, size));
+ }
+ else
+ switch((int)type)
+ {
+ case k7zIdName:
+ {
+ RINOK(SzReadSwitch(sd));
+ RINOK(SzReadFileNames(sd, numFiles, files, allocMain))
+ break;
+ }
+ case k7zIdEmptyStream:
+ {
+ RINOK(SzReadBoolVector(sd, numFiles, emptyStreamVector, allocTemp));
+ numEmptyStreams = 0;
+ for (i = 0; i < numFiles; i++)
+ if ((*emptyStreamVector)[i])
+ numEmptyStreams++;
+ break;
+ }
+ case k7zIdEmptyFile:
+ {
+ RINOK(SzReadBoolVector(sd, numEmptyStreams, emptyFileVector, allocTemp));
+ break;
+ }
+ case k7zIdMTime:
+ {
+ RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp));
+ RINOK(SzReadSwitch(sd));
+ for (i = 0; i < numFiles; i++)
+ {
+ CSzFileItem *f = &files[i];
+ Byte defined = (*lwtVector)[i];
+ f->MTimeDefined = defined;
+ f->MTime.Low = f->MTime.High = 0;
+ if (defined)
+ {
+ RINOK(SzReadUInt32(sd, &f->MTime.Low));
+ RINOK(SzReadUInt32(sd, &f->MTime.High));
+ }
+ }
+ break;
+ }
+ default:
+ {
+ RINOK(SzSkeepDataSize(sd, size));
+ }
+ }
+ }
+
+ {
+ UInt32 emptyFileIndex = 0;
+ UInt32 sizeIndex = 0;
+ for (i = 0; i < numFiles; i++)
+ {
+ CSzFileItem *file = files + i;
+ file->IsAnti = 0;
+ if (*emptyStreamVector == 0)
+ file->HasStream = 1;
+ else
+ file->HasStream = (Byte)((*emptyStreamVector)[i] ? 0 : 1);
+ if (file->HasStream)
+ {
+ file->IsDir = 0;
+ file->Size = (*unpackSizes)[sizeIndex];
+ file->FileCRC = (*digests)[sizeIndex];
+ file->FileCRCDefined = (Byte)(*digestsDefined)[sizeIndex];
+ sizeIndex++;
+ }
+ else
+ {
+ if (*emptyFileVector == 0)
+ file->IsDir = 1;
+ else
+ file->IsDir = (Byte)((*emptyFileVector)[emptyFileIndex] ? 0 : 1);
+ emptyFileIndex++;
+ file->Size = 0;
+ file->FileCRCDefined = 0;
+ }
+ }
+ }
+ return SzArEx_Fill(p, allocMain);
+}
+
+static SRes SzReadHeader(
+ CSzArEx *p,
+ CSzData *sd,
+ ISzAlloc *allocMain,
+ ISzAlloc *allocTemp)
+{
+ UInt64 *unpackSizes = 0;
+ Byte *digestsDefined = 0;
+ UInt32 *digests = 0;
+ Byte *emptyStreamVector = 0;
+ Byte *emptyFileVector = 0;
+ Byte *lwtVector = 0;
+ SRes res = SzReadHeader2(p, sd,
+ &unpackSizes, &digestsDefined, &digests,
+ &emptyStreamVector, &emptyFileVector, &lwtVector,
+ allocMain, allocTemp);
+ IAlloc_Free(allocTemp, unpackSizes);
+ IAlloc_Free(allocTemp, digestsDefined);
+ IAlloc_Free(allocTemp, digests);
+ IAlloc_Free(allocTemp, emptyStreamVector);
+ IAlloc_Free(allocTemp, emptyFileVector);
+ IAlloc_Free(allocTemp, lwtVector);
+ return res;
+}
+
+static SRes SzReadAndDecodePackedStreams2(
+ ILookInStream *inStream,
+ CSzData *sd,
+ CBuf *outBuffer,
+ UInt64 baseOffset,
+ CSzAr *p,
+ UInt64 **unpackSizes,
+ Byte **digestsDefined,
+ UInt32 **digests,
+ ISzAlloc *allocTemp)
+{
+
+ UInt32 numUnpackStreams = 0;
+ UInt64 dataStartPos;
+ CSzFolder *folder;
+ UInt64 unpackSize;
+ SRes res;
+
+ RINOK(SzReadStreamsInfo(sd, &dataStartPos, p,
+ &numUnpackStreams, unpackSizes, digestsDefined, digests,
+ allocTemp, allocTemp));
+
+ dataStartPos += baseOffset;
+ if (p->NumFolders != 1)
+ return SZ_ERROR_ARCHIVE;
+
+ folder = p->Folders;
+ unpackSize = SzFolder_GetUnpackSize(folder);
+
+ RINOK(LookInStream_SeekTo(inStream, dataStartPos));
+
+ if (!Buf_Create(outBuffer, (size_t)unpackSize, allocTemp))
+ return SZ_ERROR_MEM;
+
+ res = SzDecode(p->PackSizes, folder,
+ inStream, dataStartPos,
+ outBuffer->data, (size_t)unpackSize, allocTemp);
+ RINOK(res);
+ if (folder->UnpackCRCDefined)
+ if (CrcCalc(outBuffer->data, (size_t)unpackSize) != folder->UnpackCRC)
+ return SZ_ERROR_CRC;
+ return SZ_OK;
+}
+
+static SRes SzReadAndDecodePackedStreams(
+ ILookInStream *inStream,
+ CSzData *sd,
+ CBuf *outBuffer,
+ UInt64 baseOffset,
+ ISzAlloc *allocTemp)
+{
+ CSzAr p;
+ UInt64 *unpackSizes = 0;
+ Byte *digestsDefined = 0;
+ UInt32 *digests = 0;
+ SRes res;
+ SzAr_Init(&p);
+ res = SzReadAndDecodePackedStreams2(inStream, sd, outBuffer, baseOffset,
+ &p, &unpackSizes, &digestsDefined, &digests,
+ allocTemp);
+ SzAr_Free(&p, allocTemp);
+ IAlloc_Free(allocTemp, unpackSizes);
+ IAlloc_Free(allocTemp, digestsDefined);
+ IAlloc_Free(allocTemp, digests);
+ return res;
+}
+
+static SRes SzArEx_Open2(
+ CSzArEx *p,
+ ILookInStream *inStream,
+ ISzAlloc *allocMain,
+ ISzAlloc *allocTemp)
+{
+ Byte header[k7zStartHeaderSize];
+ UInt64 nextHeaderOffset, nextHeaderSize;
+ size_t nextHeaderSizeT;
+ UInt32 nextHeaderCRC;
+ CBuf buffer;
+ SRes res;
+
+ RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE));
+
+ if (!TestSignatureCandidate(header))
+ return SZ_ERROR_NO_ARCHIVE;
+ if (header[6] != k7zMajorVersion)
+ return SZ_ERROR_UNSUPPORTED;
+
+ nextHeaderOffset = GetUi64(header + 12);
+ nextHeaderSize = GetUi64(header + 20);
+ nextHeaderCRC = GetUi32(header + 28);
+
+ p->startPosAfterHeader = k7zStartHeaderSize;
+
+ if (CrcCalc(header + 12, 20) != GetUi32(header + 8))
+ return SZ_ERROR_CRC;
+
+ nextHeaderSizeT = (size_t)nextHeaderSize;
+ if (nextHeaderSizeT != nextHeaderSize)
+ return SZ_ERROR_MEM;
+ if (nextHeaderSizeT == 0)
+ return SZ_OK;
+ if (nextHeaderOffset > nextHeaderOffset + nextHeaderSize ||
+ nextHeaderOffset > nextHeaderOffset + nextHeaderSize + k7zStartHeaderSize)
+ return SZ_ERROR_NO_ARCHIVE;
+
+ {
+ Int64 pos = 0;
+ RINOK(inStream->Seek(inStream, &pos, SZ_SEEK_END));
+ if ((UInt64)pos < nextHeaderOffset ||
+ (UInt64)pos < k7zStartHeaderSize + nextHeaderOffset ||
+ (UInt64)pos < k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize)
+ return SZ_ERROR_INPUT_EOF;
+ }
+
+ RINOK(LookInStream_SeekTo(inStream, k7zStartHeaderSize + nextHeaderOffset));
+
+ if (!Buf_Create(&buffer, nextHeaderSizeT, allocTemp))
+ return SZ_ERROR_MEM;
+
+ res = LookInStream_Read(inStream, buffer.data, nextHeaderSizeT);
+ if (res == SZ_OK)
+ {
+ res = SZ_ERROR_ARCHIVE;
+ if (CrcCalc(buffer.data, nextHeaderSizeT) == nextHeaderCRC)
+ {
+ CSzData sd;
+ UInt64 type;
+ sd.Data = buffer.data;
+ sd.Size = buffer.size;
+ res = SzReadID(&sd, &type);
+ if (res == SZ_OK)
+ {
+ if (type == k7zIdEncodedHeader)
+ {
+ CBuf outBuffer;
+ Buf_Init(&outBuffer);
+ res = SzReadAndDecodePackedStreams(inStream, &sd, &outBuffer, p->startPosAfterHeader, allocTemp);
+ if (res != SZ_OK)
+ Buf_Free(&outBuffer, allocTemp);
+ else
+ {
+ Buf_Free(&buffer, allocTemp);
+ buffer.data = outBuffer.data;
+ buffer.size = outBuffer.size;
+ sd.Data = buffer.data;
+ sd.Size = buffer.size;
+ res = SzReadID(&sd, &type);
+ }
+ }
+ }
+ if (res == SZ_OK)
+ {
+ if (type == k7zIdHeader)
+ res = SzReadHeader(p, &sd, allocMain, allocTemp);
+ else
+ res = SZ_ERROR_UNSUPPORTED;
+ }
+ }
+ }
+ Buf_Free(&buffer, allocTemp);
+ return res;
+}
+
+SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp)
+{
+ SRes res = SzArEx_Open2(p, inStream, allocMain, allocTemp);
+ if (res != SZ_OK)
+ SzArEx_Free(p, allocMain);
+ return res;
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/Archive/7z/7zIn.h squashfs-tools-patched/LZMA/lzma465/C/Archive/7z/7zIn.h
--- squashfs-tools/LZMA/lzma465/C/Archive/7z/7zIn.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/Archive/7z/7zIn.h 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,41 @@
+/* 7zIn.h -- 7z Input functions
+2008-11-23 : Igor Pavlov : Public domain */
+
+#ifndef __7Z_IN_H
+#define __7Z_IN_H
+
+#include "7zHeader.h"
+#include "7zItem.h"
+
+typedef struct
+{
+ CSzAr db;
+
+ UInt64 startPosAfterHeader;
+ UInt64 dataPos;
+
+ UInt32 *FolderStartPackStreamIndex;
+ UInt64 *PackStreamStartPositions;
+ UInt32 *FolderStartFileIndex;
+ UInt32 *FileIndexToFolderIndexMap;
+} CSzArEx;
+
+void SzArEx_Init(CSzArEx *p);
+void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc);
+UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder);
+int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize);
+
+/*
+Errors:
+SZ_ERROR_NO_ARCHIVE
+SZ_ERROR_ARCHIVE
+SZ_ERROR_UNSUPPORTED
+SZ_ERROR_MEM
+SZ_ERROR_CRC
+SZ_ERROR_INPUT_EOF
+SZ_ERROR_FAIL
+*/
+
+SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp);
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/Archive/7z/7zItem.c squashfs-tools-patched/LZMA/lzma465/C/Archive/7z/7zItem.c
--- squashfs-tools/LZMA/lzma465/C/Archive/7z/7zItem.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/Archive/7z/7zItem.c 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,127 @@
+/* 7zItem.c -- 7z Items
+2008-10-04 : Igor Pavlov : Public domain */
+
+#include "7zItem.h"
+
+void SzCoderInfo_Init(CSzCoderInfo *p)
+{
+ Buf_Init(&p->Props);
+}
+
+void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc)
+{
+ Buf_Free(&p->Props, alloc);
+ SzCoderInfo_Init(p);
+}
+
+void SzFolder_Init(CSzFolder *p)
+{
+ p->Coders = 0;
+ p->BindPairs = 0;
+ p->PackStreams = 0;
+ p->UnpackSizes = 0;
+ p->NumCoders = 0;
+ p->NumBindPairs = 0;
+ p->NumPackStreams = 0;
+ p->UnpackCRCDefined = 0;
+ p->UnpackCRC = 0;
+ p->NumUnpackStreams = 0;
+}
+
+void SzFolder_Free(CSzFolder *p, ISzAlloc *alloc)
+{
+ UInt32 i;
+ if (p->Coders)
+ for (i = 0; i < p->NumCoders; i++)
+ SzCoderInfo_Free(&p->Coders[i], alloc);
+ IAlloc_Free(alloc, p->Coders);
+ IAlloc_Free(alloc, p->BindPairs);
+ IAlloc_Free(alloc, p->PackStreams);
+ IAlloc_Free(alloc, p->UnpackSizes);
+ SzFolder_Init(p);
+}
+
+UInt32 SzFolder_GetNumOutStreams(CSzFolder *p)
+{
+ UInt32 result = 0;
+ UInt32 i;
+ for (i = 0; i < p->NumCoders; i++)
+ result += p->Coders[i].NumOutStreams;
+ return result;
+}
+
+int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex)
+{
+ UInt32 i;
+ for (i = 0; i < p->NumBindPairs; i++)
+ if (p->BindPairs[i].InIndex == inStreamIndex)
+ return i;
+ return -1;
+}
+
+
+int SzFolder_FindBindPairForOutStream(CSzFolder *p, UInt32 outStreamIndex)
+{
+ UInt32 i;
+ for (i = 0; i < p->NumBindPairs; i++)
+ if (p->BindPairs[i].OutIndex == outStreamIndex)
+ return i;
+ return -1;
+}
+
+UInt64 SzFolder_GetUnpackSize(CSzFolder *p)
+{
+ int i = (int)SzFolder_GetNumOutStreams(p);
+ if (i == 0)
+ return 0;
+ for (i--; i >= 0; i--)
+ if (SzFolder_FindBindPairForOutStream(p, i) < 0)
+ return p->UnpackSizes[i];
+ /* throw 1; */
+ return 0;
+}
+
+void SzFile_Init(CSzFileItem *p)
+{
+ p->HasStream = 1;
+ p->IsDir = 0;
+ p->IsAnti = 0;
+ p->FileCRCDefined = 0;
+ p->MTimeDefined = 0;
+ p->Name = 0;
+}
+
+static void SzFile_Free(CSzFileItem *p, ISzAlloc *alloc)
+{
+ IAlloc_Free(alloc, p->Name);
+ SzFile_Init(p);
+}
+
+void SzAr_Init(CSzAr *p)
+{
+ p->PackSizes = 0;
+ p->PackCRCsDefined = 0;
+ p->PackCRCs = 0;
+ p->Folders = 0;
+ p->Files = 0;
+ p->NumPackStreams = 0;
+ p->NumFolders = 0;
+ p->NumFiles = 0;
+}
+
+void SzAr_Free(CSzAr *p, ISzAlloc *alloc)
+{
+ UInt32 i;
+ if (p->Folders)
+ for (i = 0; i < p->NumFolders; i++)
+ SzFolder_Free(&p->Folders[i], alloc);
+ if (p->Files)
+ for (i = 0; i < p->NumFiles; i++)
+ SzFile_Free(&p->Files[i], alloc);
+ IAlloc_Free(alloc, p->PackSizes);
+ IAlloc_Free(alloc, p->PackCRCsDefined);
+ IAlloc_Free(alloc, p->PackCRCs);
+ IAlloc_Free(alloc, p->Folders);
+ IAlloc_Free(alloc, p->Files);
+ SzAr_Init(p);
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/Archive/7z/7zItem.h squashfs-tools-patched/LZMA/lzma465/C/Archive/7z/7zItem.h
--- squashfs-tools/LZMA/lzma465/C/Archive/7z/7zItem.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/Archive/7z/7zItem.h 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,84 @@
+/* 7zItem.h -- 7z Items
+2008-10-04 : Igor Pavlov : Public domain */
+
+#ifndef __7Z_ITEM_H
+#define __7Z_ITEM_H
+
+#include "../../7zBuf.h"
+
+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;
+} CBindPair;
+
+typedef struct
+{
+ CSzCoderInfo *Coders;
+ CBindPair *BindPairs;
+ UInt32 *PackStreams;
+ UInt64 *UnpackSizes;
+ UInt32 NumCoders;
+ UInt32 NumBindPairs;
+ UInt32 NumPackStreams;
+ int UnpackCRCDefined;
+ UInt32 UnpackCRC;
+
+ UInt32 NumUnpackStreams;
+} CSzFolder;
+
+void SzFolder_Init(CSzFolder *p);
+UInt64 SzFolder_GetUnpackSize(CSzFolder *p);
+int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex);
+UInt32 SzFolder_GetNumOutStreams(CSzFolder *p);
+UInt64 SzFolder_GetUnpackSize(CSzFolder *p);
+
+typedef struct
+{
+ UInt32 Low;
+ UInt32 High;
+} CNtfsFileTime;
+
+typedef struct
+{
+ CNtfsFileTime MTime;
+ UInt64 Size;
+ char *Name;
+ UInt32 FileCRC;
+
+ Byte HasStream;
+ Byte IsDir;
+ Byte IsAnti;
+ Byte FileCRCDefined;
+ Byte MTimeDefined;
+} 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);
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/Archive/7z/7zMain.c squashfs-tools-patched/LZMA/lzma465/C/Archive/7z/7zMain.c
--- squashfs-tools/LZMA/lzma465/C/Archive/7z/7zMain.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/Archive/7z/7zMain.c 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,262 @@
+/* 7zMain.c - Test application for 7z Decoder
+2008-11-23 : Igor Pavlov : Public domain */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "../../7zCrc.h"
+#include "../../7zFile.h"
+#include "../../7zVersion.h"
+
+#include "7zAlloc.h"
+#include "7zExtract.h"
+#include "7zIn.h"
+
+static void ConvertNumberToString(UInt64 value, char *s)
+{
+ char temp[32];
+ int pos = 0;
+ do
+ {
+ temp[pos++] = (char)('0' + (int)(value % 10));
+ value /= 10;
+ }
+ while (value != 0);
+ do
+ *s++ = temp[--pos];
+ while (pos > 0);
+ *s = '\0';
+}
+
+#define PERIOD_4 (4 * 365 + 1)
+#define PERIOD_100 (PERIOD_4 * 25 - 1)
+#define PERIOD_400 (PERIOD_100 * 4 + 1)
+
+static void ConvertFileTimeToString(CNtfsFileTime *ft, char *s)
+{
+ unsigned year, mon, day, hour, min, sec;
+ UInt64 v64 = ft->Low | ((UInt64)ft->High << 32);
+ Byte ms[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+ unsigned temp;
+ UInt32 v;
+ v64 /= 10000000;
+ sec = (unsigned)(v64 % 60);
+ v64 /= 60;
+ min = (unsigned)(v64 % 60);
+ v64 /= 60;
+ hour = (unsigned)(v64 % 24);
+ v64 /= 24;
+
+ v = (UInt32)v64;
+
+ year = (unsigned)(1601 + v / PERIOD_400 * 400);
+ v %= PERIOD_400;
+
+ temp = (unsigned)(v / PERIOD_100);
+ if (temp == 4)
+ temp = 3;
+ year += temp * 100;
+ v -= temp * PERIOD_100;
+
+ temp = v / PERIOD_4;
+ if (temp == 25)
+ temp = 24;
+ year += temp * 4;
+ v -= temp * PERIOD_4;
+
+ temp = v / 365;
+ if (temp == 4)
+ temp = 3;
+ year += temp;
+ v -= temp * 365;
+
+ if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))
+ ms[1] = 29;
+ for (mon = 1; mon <= 12; mon++)
+ {
+ unsigned s = ms[mon - 1];
+ if (v < s)
+ break;
+ v -= s;
+ }
+ day = (unsigned)v + 1;
+ sprintf(s, "%04d-%02d-%02d %02d:%02d:%02d", year, mon, day, hour, min, sec);
+}
+
+void PrintError(char *sz)
+{
+ printf("\nERROR: %s\n", sz);
+}
+
+int MY_CDECL main(int numargs, char *args[])
+{
+ CFileInStream archiveStream;
+ CLookToRead lookStream;
+ CSzArEx db;
+ SRes res;
+ ISzAlloc allocImp;
+ ISzAlloc allocTempImp;
+
+ printf("\n7z ANSI-C Decoder " MY_VERSION_COPYRIGHT_DATE "\n");
+ if (numargs == 1)
+ {
+ printf(
+ "\nUsage: 7zDec <command> <archive_name>\n\n"
+ "<Commands>\n"
+ " e: Extract files from archive\n"
+ " l: List contents of archive\n"
+ " t: Test integrity of archive\n");
+ return 0;
+ }
+ if (numargs < 3)
+ {
+ PrintError("incorrect command");
+ return 1;
+ }
+
+ if (InFile_Open(&archiveStream.file, args[2]))
+ {
+ PrintError("can not open input file");
+ return 1;
+ }
+
+
+ FileInStream_CreateVTable(&archiveStream);
+ LookToRead_CreateVTable(&lookStream, False);
+
+ lookStream.realStream = &archiveStream.s;
+ LookToRead_Init(&lookStream);
+
+ allocImp.Alloc = SzAlloc;
+ allocImp.Free = SzFree;
+
+ allocTempImp.Alloc = SzAllocTemp;
+ allocTempImp.Free = SzFreeTemp;
+
+ CrcGenerateTable();
+
+ SzArEx_Init(&db);
+ res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp);
+ if (res == SZ_OK)
+ {
+ char *command = args[1];
+ int listCommand = 0, testCommand = 0, extractCommand = 0;
+ if (strcmp(command, "l") == 0) listCommand = 1;
+ else if (strcmp(command, "t") == 0) testCommand = 1;
+ else if (strcmp(command, "e") == 0) extractCommand = 1;
+
+ if (listCommand)
+ {
+ UInt32 i;
+ for (i = 0; i < db.db.NumFiles; i++)
+ {
+ CSzFileItem *f = db.db.Files + i;
+ char s[32], t[32];
+ ConvertNumberToString(f->Size, s);
+ if (f->MTimeDefined)
+ ConvertFileTimeToString(&f->MTime, t);
+ else
+ strcpy(t, " ");
+
+ printf("%s %10s %s\n", t, s, f->Name);
+ }
+ }
+ else if (testCommand || extractCommand)
+ {
+ UInt32 i;
+
+ /*
+ if you need cache, use these 3 variables.
+ if you use external function, you can make these variable as static.
+ */
+ UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */
+ Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */
+ size_t outBufferSize = 0; /* it can have any value before first call (if outBuffer = 0) */
+
+ printf("\n");
+ for (i = 0; i < db.db.NumFiles; i++)
+ {
+ size_t offset;
+ size_t outSizeProcessed;
+ CSzFileItem *f = db.db.Files + i;
+ if (f->IsDir)
+ printf("Directory ");
+ else
+ printf(testCommand ?
+ "Testing ":
+ "Extracting");
+ printf(" %s", f->Name);
+ if (f->IsDir)
+ {
+ printf("\n");
+ continue;
+ }
+ res = SzAr_Extract(&db, &lookStream.s, i,
+ &blockIndex, &outBuffer, &outBufferSize,
+ &offset, &outSizeProcessed,
+ &allocImp, &allocTempImp);
+ if (res != SZ_OK)
+ break;
+ if (!testCommand)
+ {
+ CSzFile outFile;
+ size_t processedSize;
+ char *fileName = f->Name;
+ size_t nameLen = strlen(f->Name);
+ for (; nameLen > 0; nameLen--)
+ if (f->Name[nameLen - 1] == '/')
+ {
+ fileName = f->Name + nameLen;
+ break;
+ }
+
+ if (OutFile_Open(&outFile, fileName))
+ {
+ PrintError("can not open output file");
+ res = SZ_ERROR_FAIL;
+ break;
+ }
+ processedSize = outSizeProcessed;
+ if (File_Write(&outFile, outBuffer + offset, &processedSize) != 0 ||
+ processedSize != outSizeProcessed)
+ {
+ PrintError("can not write output file");
+ res = SZ_ERROR_FAIL;
+ break;
+ }
+ if (File_Close(&outFile))
+ {
+ PrintError("can not close output file");
+ res = SZ_ERROR_FAIL;
+ break;
+ }
+ }
+ printf("\n");
+ }
+ IAlloc_Free(&allocImp, outBuffer);
+ }
+ else
+ {
+ PrintError("incorrect command");
+ res = SZ_ERROR_FAIL;
+ }
+ }
+ SzArEx_Free(&db, &allocImp);
+
+ File_Close(&archiveStream.file);
+ if (res == SZ_OK)
+ {
+ printf("\nEverything is Ok\n");
+ return 0;
+ }
+ if (res == SZ_ERROR_UNSUPPORTED)
+ PrintError("decoder doesn't support this archive");
+ else if (res == SZ_ERROR_MEM)
+ PrintError("can not allocate memory");
+ else if (res == SZ_ERROR_CRC)
+ PrintError("CRC error");
+ else
+ printf("\nERROR #%d\n", res);
+ return 1;
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/Archive/7z/makefile squashfs-tools-patched/LZMA/lzma465/C/Archive/7z/makefile
--- squashfs-tools/LZMA/lzma465/C/Archive/7z/makefile 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/Archive/7z/makefile 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,33 @@
+MY_STATIC_LINK=1
+
+PROG = 7zDec.exe
+
+C_OBJS = \
+ $O\7zBuf.obj \
+ $O\7zBuf2.obj \
+ $O\7zCrc.obj \
+ $O\LzmaDec.obj \
+ $O\Bra86.obj \
+ $O\Bcj2.obj \
+ $O\7zFile.obj \
+ $O\7zStream.obj \
+
+7Z_OBJS = \
+ $O\7zAlloc.obj \
+ $O\7zDecode.obj \
+ $O\7zExtract.obj \
+ $O\7zHeader.obj \
+ $O\7zIn.obj \
+ $O\7zItem.obj \
+ $O\7zMain.obj \
+
+OBJS = \
+ $(7Z_OBJS) \
+ $(C_OBJS) \
+
+!include "../../../CPP/Build.mak"
+
+$(7Z_OBJS): $(*B).c
+ $(COMPL_O1)
+$(C_OBJS): ../../$(*B).c
+ $(COMPL_O2)
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/Archive/7z/makefile.gcc squashfs-tools-patched/LZMA/lzma465/C/Archive/7z/makefile.gcc
--- squashfs-tools/LZMA/lzma465/C/Archive/7z/makefile.gcc 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/Archive/7z/makefile.gcc 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,61 @@
+PROG = 7zDec
+CXX = g++
+LIB =
+RM = rm -f
+CFLAGS = -c -O2 -Wall
+
+OBJS = 7zAlloc.o 7zBuf.o 7zBuf2.o 7zCrc.o 7zDecode.o 7zExtract.o 7zHeader.o 7zIn.o 7zItem.o 7zMain.o LzmaDec.o Bra86.o Bcj2.o 7zFile.o 7zStream.o
+
+all: $(PROG)
+
+$(PROG): $(OBJS)
+ $(CXX) -o $(PROG) $(LDFLAGS) $(OBJS) $(LIB)
+
+7zAlloc.o: 7zAlloc.c
+ $(CXX) $(CFLAGS) 7zAlloc.c
+
+7zBuf.o: ../../7zBuf.c
+ $(CXX) $(CFLAGS) ../../7zBuf.c
+
+7zBuf2.o: ../../7zBuf2.c
+ $(CXX) $(CFLAGS) ../../7zBuf2.c
+
+7zCrc.o: ../../7zCrc.c
+ $(CXX) $(CFLAGS) ../../7zCrc.c
+
+7zDecode.o: 7zDecode.c
+ $(CXX) $(CFLAGS) 7zDecode.c
+
+7zExtract.o: 7zExtract.c
+ $(CXX) $(CFLAGS) 7zExtract.c
+
+7zHeader.o: 7zHeader.c
+ $(CXX) $(CFLAGS) 7zHeader.c
+
+7zIn.o: 7zIn.c
+ $(CXX) $(CFLAGS) 7zIn.c
+
+7zItem.o: 7zItem.c
+ $(CXX) $(CFLAGS) 7zItem.c
+
+7zMain.o: 7zMain.c
+ $(CXX) $(CFLAGS) 7zMain.c
+
+LzmaDec.o: ../../LzmaDec.c
+ $(CXX) $(CFLAGS) ../../LzmaDec.c
+
+Bra86.o: ../../Bra86.c
+ $(CXX) $(CFLAGS) ../../Bra86.c
+
+Bcj2.o: ../../Bcj2.c
+ $(CXX) $(CFLAGS) ../../Bcj2.c
+
+7zFile.o: ../../7zFile.c
+ $(CXX) $(CFLAGS) ../../7zFile.c
+
+7zStream.o: ../../7zStream.c
+ $(CXX) $(CFLAGS) ../../7zStream.c
+
+clean:
+ -$(RM) $(PROG) $(OBJS)
+
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/Bcj2.c squashfs-tools-patched/LZMA/lzma465/C/Bcj2.c
--- squashfs-tools/LZMA/lzma465/C/Bcj2.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/Bcj2.c 2016-08-25 09:06:03.231530353 -0400
@@ -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;
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/Bcj2.h squashfs-tools-patched/LZMA/lzma465/C/Bcj2.h
--- squashfs-tools/LZMA/lzma465/C/Bcj2.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/Bcj2.h 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,30 @@
+/* Bcj2.h -- Converter for x86 code (BCJ2)
+2008-10-04 : Igor Pavlov : Public domain */
+
+#ifndef __BCJ2_H
+#define __BCJ2_H
+
+#include "Types.h"
+
+/*
+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);
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/Bra86.c squashfs-tools-patched/LZMA/lzma465/C/Bra86.c
--- squashfs-tools/LZMA/lzma465/C/Bra86.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/Bra86.c 2016-08-25 09:06:03.231530353 -0400
@@ -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;
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/Bra.c squashfs-tools-patched/LZMA/lzma465/C/Bra.c
--- squashfs-tools/LZMA/lzma465/C/Bra.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/Bra.c 2016-08-25 09:06:03.231530353 -0400
@@ -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;
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/Bra.h squashfs-tools-patched/LZMA/lzma465/C/Bra.h
--- squashfs-tools/LZMA/lzma465/C/Bra.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/Bra.h 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,60 @@
+/* Bra.h -- Branch converters for executables
+2008-10-04 : Igor Pavlov : Public domain */
+
+#ifndef __BRA_H
+#define __BRA_H
+
+#include "Types.h"
+
+/*
+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);
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/BraIA64.c squashfs-tools-patched/LZMA/lzma465/C/BraIA64.c
--- squashfs-tools/LZMA/lzma465/C/BraIA64.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/BraIA64.c 2016-08-25 09:06:03.231530353 -0400
@@ -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;
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/CpuArch.h squashfs-tools-patched/LZMA/lzma465/C/CpuArch.h
--- squashfs-tools/LZMA/lzma465/C/CpuArch.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/CpuArch.h 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,69 @@
+/* CpuArch.h
+2008-08-05
+Igor Pavlov
+Public domain */
+
+#ifndef __CPUARCH_H
+#define __CPUARCH_H
+
+/*
+LITTLE_ENDIAN_UNALIGN means:
+ 1) CPU is LITTLE_ENDIAN
+ 2) it's allowed to make unaligned memory accesses
+if LITTLE_ENDIAN_UNALIGN is not defined, it means that we don't know
+about these properties of platform.
+*/
+
+#if defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64) || defined(__i386__) || defined(__x86_64__)
+#define LITTLE_ENDIAN_UNALIGN
+#endif
+
+#ifdef LITTLE_ENDIAN_UNALIGN
+
+#define GetUi16(p) (*(const UInt16 *)(p))
+#define GetUi32(p) (*(const UInt32 *)(p))
+#define GetUi64(p) (*(const UInt64 *)(p))
+#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 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(LITTLE_ENDIAN_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])
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/LzFind.c squashfs-tools-patched/LZMA/lzma465/C/LzFind.c
--- squashfs-tools/LZMA/lzma465/C/LzFind.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/LzFind.c 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,751 @@
+/* LzFind.c -- Match finder for LZ algorithms
+2008-10-04 : 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;
+ 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->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->skipModeBits = 0; */
+ p->directInput = 0;
+ 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 /* >> p->skipModeBits */) + 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 >>= p->skipModeBits; */
+ 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;
+ }
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/LzFind.h squashfs-tools-patched/LZMA/lzma465/C/LzFind.h
--- squashfs-tools/LZMA/lzma465/C/LzFind.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/LzFind.h 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,107 @@
+/* LzFind.h -- Match finder for LZ algorithms
+2008-10-04 : Igor Pavlov : Public domain */
+
+#ifndef __LZFIND_H
+#define __LZFIND_H
+
+#include "Types.h"
+
+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;
+ int btMode;
+ /* int skipModeBits; */
+ 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);
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/LzFindMt.c squashfs-tools-patched/LZMA/lzma465/C/LzFindMt.c
--- squashfs-tools/LZMA/lzma465/C/LzFindMt.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/LzFindMt.c 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,793 @@
+/* LzFindMt.c -- multithreaded Match finder for LZ algorithms
+2008-10-04 : 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 do { GET_NEXT_BLOCK_IF_REQUIRED
+#define SKIP_HEADER(n) SKIP_HEADER2 if (p->btNumAvailBytes-- >= (n)) { const Byte *cur = p->pointerToCurPos; UInt32 *hash = p->hash;
+#define SKIP_FOOTER } INCREASE_LZ_POS p->btBufPos += p->btBuf[p->btBufPos] + 1; } while (--num != 0);
+
+void MatchFinderMt0_Skip(CMatchFinderMt *p, UInt32 num)
+{
+ SKIP_HEADER2 { p->btNumAvailBytes--;
+ SKIP_FOOTER
+}
+
+void MatchFinderMt2_Skip(CMatchFinderMt *p, UInt32 num)
+{
+ SKIP_HEADER(2)
+ UInt32 hash2Value;
+ MT_HASH2_CALC
+ hash[hash2Value] = p->lzPos;
+ SKIP_FOOTER
+}
+
+void MatchFinderMt3_Skip(CMatchFinderMt *p, UInt32 num)
+{
+ SKIP_HEADER(3)
+ UInt32 hash2Value, hash3Value;
+ MT_HASH3_CALC
+ hash[kFix3HashSize + hash3Value] =
+ hash[ hash2Value] =
+ p->lzPos;
+ SKIP_FOOTER
+}
+
+/*
+void MatchFinderMt4_Skip(CMatchFinderMt *p, UInt32 num)
+{
+ SKIP_HEADER(4)
+ UInt32 hash2Value, hash3Value, hash4Value;
+ MT_HASH4_CALC
+ hash[kFix4HashSize + hash4Value] =
+ hash[kFix3HashSize + hash3Value] =
+ hash[ hash2Value] =
+ p->lzPos;
+ SKIP_FOOTER
+}
+*/
+
+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;
+ */
+ }
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/LzFindMt.h squashfs-tools-patched/LZMA/lzma465/C/LzFindMt.h
--- squashfs-tools/LZMA/lzma465/C/LzFindMt.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/LzFindMt.h 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,97 @@
+/* LzFindMt.h -- multithreaded Match finder for LZ algorithms
+2008-10-04 : Igor Pavlov : Public domain */
+
+#ifndef __LZFINDMT_H
+#define __LZFINDMT_H
+
+#include "Threads.h"
+#include "LzFind.h"
+
+#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);
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/LzHash.h squashfs-tools-patched/LZMA/lzma465/C/LzHash.h
--- squashfs-tools/LZMA/lzma465/C/LzHash.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/LzHash.h 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,54 @@
+/* LzHash.h -- HASH functions for LZ algorithms
+2008-10-04 : Igor Pavlov : Public domain */
+
+#ifndef __LZHASH_H
+#define __LZHASH_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
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/LzmaDec.c squashfs-tools-patched/LZMA/lzma465/C/LzmaDec.c
--- squashfs-tools/LZMA/lzma465/C/LzmaDec.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/LzmaDec.c 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,1007 @@
+/* LzmaDec.c -- LZMA Decoder
+2008-11-06 : 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
+
+static const Byte kLiteralNextStates[kNumStates * 2] =
+{
+ 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5,
+ 7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10
+};
+
+#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)
+ {
+ 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;
+ 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++;
+
+ state = kLiteralNextStates[state];
+ /* if (state < 4) state = 0; else if (state < 10) state -= 3; else state -= 6; */
+ 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;
+ /* state = kLiteralNextStates[state]; */
+ }
+
+ 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;
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/LzmaDec.h squashfs-tools-patched/LZMA/lzma465/C/LzmaDec.h
--- squashfs-tools/LZMA/lzma465/C/LzmaDec.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/LzmaDec.h 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,223 @@
+/* LzmaDec.h -- LZMA Decoder
+2008-10-04 : Igor Pavlov : Public domain */
+
+#ifndef __LZMADEC_H
+#define __LZMADEC_H
+
+#include "Types.h"
+
+/* #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);
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/LzmaEnc.c squashfs-tools-patched/LZMA/lzma465/C/LzmaEnc.c
--- squashfs-tools/LZMA/lzma465/C/LzmaEnc.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/LzmaEnc.c 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,2281 @@
+/* LzmaEnc.c -- LZMA Encoder
+2009-02-02 : Igor Pavlov : Public domain */
+
+#include <string.h>
+
+/* #define SHOW_STAT */
+/* #define SHOW_STAT2 */
+
+#if defined(SHOW_STAT) || defined(SHOW_STAT2)
+#include <stdio.h>
+#endif
+
+#include "LzmaEnc.h"
+
+#include "LzFind.h"
+#ifdef COMPRESS_MF_MT
+#include "LzFindMt.h"
+#endif
+
+#ifdef SHOW_STAT
+static int ttt = 0;
+#endif
+
+#define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1)
+
+#define kBlockSize (9 << 10)
+#define kUnpackBlockSize (1 << 18)
+#define kMatchArraySize (1 << 21)
+#define kMatchRecordMaxSize ((LZMA_MATCH_LEN_MAX * 2 + 3) * LZMA_MATCH_LEN_MAX)
+
+#define kNumMaxDirectBits (31)
+
+#define kNumTopBits 24
+#define kTopValue ((UInt32)1 << kNumTopBits)
+
+#define kNumBitModelTotalBits 11
+#define kBitModelTotal (1 << kNumBitModelTotalBits)
+#define kNumMoveBits 5
+#define kProbInitValue (kBitModelTotal >> 1)
+
+#define kNumMoveReducingBits 4
+#define kNumBitPriceShiftBits 4
+#define kBitPrice (1 << kNumBitPriceShiftBits)
+
+void LzmaEncProps_Init(CLzmaEncProps *p)
+{
+ p->level = 5;
+ p->dictSize = p->mc = 0;
+ p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1;
+ p->writeEndMark = 0;
+}
+
+void LzmaEncProps_Normalize(CLzmaEncProps *p)
+{
+ int level = p->level;
+ if (level < 0) level = 5;
+ p->level = level;
+ if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26)));
+ if (p->lc < 0) p->lc = 3;
+ if (p->lp < 0) p->lp = 0;
+ if (p->pb < 0) p->pb = 2;
+ if (p->algo < 0) p->algo = (level < 5 ? 0 : 1);
+ if (p->fb < 0) p->fb = (level < 7 ? 32 : 64);
+ if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1);
+ if (p->numHashBytes < 0) p->numHashBytes = 4;
+ if (p->mc == 0) p->mc = (16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1);
+ if (p->numThreads < 0)
+ p->numThreads =
+ #ifdef COMPRESS_MF_MT
+ ((p->btMode && p->algo) ? 2 : 1);
+ #else
+ 1;
+ #endif
+}
+
+UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2)
+{
+ CLzmaEncProps props = *props2;
+ LzmaEncProps_Normalize(&props);
+ return props.dictSize;
+}
+
+/* #define LZMA_LOG_BSR */
+/* Define it for Intel's CPU */
+
+
+#ifdef LZMA_LOG_BSR
+
+#define kDicLogSizeMaxCompress 30
+
+#define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); }
+
+UInt32 GetPosSlot1(UInt32 pos)
+{
+ UInt32 res;
+ BSR2_RET(pos, res);
+ return res;
+}
+#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); }
+#define GetPosSlot(pos, res) { if (pos < 2) res = pos; else BSR2_RET(pos, res); }
+
+#else
+
+#define kNumLogBits (9 + (int)sizeof(size_t) / 2)
+#define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7)
+
+void LzmaEnc_FastPosInit(Byte *g_FastPos)
+{
+ int c = 2, slotFast;
+ g_FastPos[0] = 0;
+ g_FastPos[1] = 1;
+
+ for (slotFast = 2; slotFast < kNumLogBits * 2; slotFast++)
+ {
+ UInt32 k = (1 << ((slotFast >> 1) - 1));
+ UInt32 j;
+ for (j = 0; j < k; j++, c++)
+ g_FastPos[c] = (Byte)slotFast;
+ }
+}
+
+#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \
+ (0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \
+ res = p->g_FastPos[pos >> i] + (i * 2); }
+/*
+#define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \
+ p->g_FastPos[pos >> 6] + 12 : \
+ p->g_FastPos[pos >> (6 + kNumLogBits - 1)] + (6 + (kNumLogBits - 1)) * 2; }
+*/
+
+#define GetPosSlot1(pos) p->g_FastPos[pos]
+#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); }
+#define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[pos]; else BSR2_RET(pos, res); }
+
+#endif
+
+
+#define LZMA_NUM_REPS 4
+
+typedef unsigned CState;
+
+typedef struct _COptimal
+{
+ UInt32 price;
+
+ CState state;
+ int prev1IsChar;
+ int prev2;
+
+ UInt32 posPrev2;
+ UInt32 backPrev2;
+
+ UInt32 posPrev;
+ UInt32 backPrev;
+ UInt32 backs[LZMA_NUM_REPS];
+} COptimal;
+
+#define kNumOpts (1 << 12)
+
+#define kNumLenToPosStates 4
+#define kNumPosSlotBits 6
+#define kDicLogSizeMin 0
+#define kDicLogSizeMax 32
+#define kDistTableSizeMax (kDicLogSizeMax * 2)
+
+
+#define kNumAlignBits 4
+#define kAlignTableSize (1 << kNumAlignBits)
+#define kAlignMask (kAlignTableSize - 1)
+
+#define kStartPosModelIndex 4
+#define kEndPosModelIndex 14
+#define kNumPosModels (kEndPosModelIndex - kStartPosModelIndex)
+
+#define kNumFullDistances (1 << (kEndPosModelIndex / 2))
+
+#ifdef _LZMA_PROB32
+#define CLzmaProb UInt32
+#else
+#define CLzmaProb UInt16
+#endif
+
+#define LZMA_PB_MAX 4
+#define LZMA_LC_MAX 8
+#define LZMA_LP_MAX 4
+
+#define LZMA_NUM_PB_STATES_MAX (1 << LZMA_PB_MAX)
+
+
+#define kLenNumLowBits 3
+#define kLenNumLowSymbols (1 << kLenNumLowBits)
+#define kLenNumMidBits 3
+#define kLenNumMidSymbols (1 << kLenNumMidBits)
+#define kLenNumHighBits 8
+#define kLenNumHighSymbols (1 << kLenNumHighBits)
+
+#define kLenNumSymbolsTotal (kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
+
+#define LZMA_MATCH_LEN_MIN 2
+#define LZMA_MATCH_LEN_MAX (LZMA_MATCH_LEN_MIN + kLenNumSymbolsTotal - 1)
+
+#define kNumStates 12
+
+typedef struct
+{
+ CLzmaProb choice;
+ CLzmaProb choice2;
+ CLzmaProb low[LZMA_NUM_PB_STATES_MAX << kLenNumLowBits];
+ CLzmaProb mid[LZMA_NUM_PB_STATES_MAX << kLenNumMidBits];
+ CLzmaProb high[kLenNumHighSymbols];
+} CLenEnc;
+
+typedef struct
+{
+ CLenEnc p;
+ UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal];
+ UInt32 tableSize;
+ UInt32 counters[LZMA_NUM_PB_STATES_MAX];
+} CLenPriceEnc;
+
+typedef struct _CRangeEnc
+{
+ UInt32 range;
+ Byte cache;
+ UInt64 low;
+ UInt64 cacheSize;
+ Byte *buf;
+ Byte *bufLim;
+ Byte *bufBase;
+ ISeqOutStream *outStream;
+ UInt64 processed;
+ SRes res;
+} CRangeEnc;
+
+typedef struct _CSeqInStreamBuf
+{
+ ISeqInStream funcTable;
+ const Byte *data;
+ SizeT rem;
+} CSeqInStreamBuf;
+
+static SRes MyRead(void *pp, void *data, size_t *size)
+{
+ size_t curSize = *size;
+ CSeqInStreamBuf *p = (CSeqInStreamBuf *)pp;
+ if (p->rem < curSize)
+ curSize = p->rem;
+ memcpy(data, p->data, curSize);
+ p->rem -= curSize;
+ p->data += curSize;
+ *size = curSize;
+ return SZ_OK;
+}
+
+typedef struct
+{
+ CLzmaProb *litProbs;
+
+ CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
+ CLzmaProb isRep[kNumStates];
+ CLzmaProb isRepG0[kNumStates];
+ CLzmaProb isRepG1[kNumStates];
+ CLzmaProb isRepG2[kNumStates];
+ CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX];
+
+ CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits];
+ CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex];
+ CLzmaProb posAlignEncoder[1 << kNumAlignBits];
+
+ CLenPriceEnc lenEnc;
+ CLenPriceEnc repLenEnc;
+
+ UInt32 reps[LZMA_NUM_REPS];
+ UInt32 state;
+} CSaveState;
+
+typedef struct _CLzmaEnc
+{
+ IMatchFinder matchFinder;
+ void *matchFinderObj;
+
+ #ifdef COMPRESS_MF_MT
+ Bool mtMode;
+ CMatchFinderMt matchFinderMt;
+ #endif
+
+ CMatchFinder matchFinderBase;
+
+ #ifdef COMPRESS_MF_MT
+ Byte pad[128];
+ #endif
+
+ UInt32 optimumEndIndex;
+ UInt32 optimumCurrentIndex;
+
+ UInt32 longestMatchLength;
+ UInt32 numPairs;
+ UInt32 numAvail;
+ COptimal opt[kNumOpts];
+
+ #ifndef LZMA_LOG_BSR
+ Byte g_FastPos[1 << kNumLogBits];
+ #endif
+
+ UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
+ UInt32 matches[LZMA_MATCH_LEN_MAX * 2 + 2 + 1];
+ UInt32 numFastBytes;
+ UInt32 additionalOffset;
+ UInt32 reps[LZMA_NUM_REPS];
+ UInt32 state;
+
+ UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax];
+ UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances];
+ UInt32 alignPrices[kAlignTableSize];
+ UInt32 alignPriceCount;
+
+ UInt32 distTableSize;
+
+ unsigned lc, lp, pb;
+ unsigned lpMask, pbMask;
+
+ CLzmaProb *litProbs;
+
+ CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
+ CLzmaProb isRep[kNumStates];
+ CLzmaProb isRepG0[kNumStates];
+ CLzmaProb isRepG1[kNumStates];
+ CLzmaProb isRepG2[kNumStates];
+ CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX];
+
+ CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits];
+ CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex];
+ CLzmaProb posAlignEncoder[1 << kNumAlignBits];
+
+ CLenPriceEnc lenEnc;
+ CLenPriceEnc repLenEnc;
+
+ unsigned lclp;
+
+ Bool fastMode;
+
+ CRangeEnc rc;
+
+ Bool writeEndMark;
+ UInt64 nowPos64;
+ UInt32 matchPriceCount;
+ Bool finished;
+ Bool multiThread;
+
+ SRes result;
+ UInt32 dictSize;
+ UInt32 matchFinderCycles;
+
+ ISeqInStream *inStream;
+ CSeqInStreamBuf seqBufInStream;
+
+ CSaveState saveState;
+} CLzmaEnc;
+
+void LzmaEnc_SaveState(CLzmaEncHandle pp)
+{
+ CLzmaEnc *p = (CLzmaEnc *)pp;
+ CSaveState *dest = &p->saveState;
+ int i;
+ dest->lenEnc = p->lenEnc;
+ dest->repLenEnc = p->repLenEnc;
+ dest->state = p->state;
+
+ for (i = 0; i < kNumStates; i++)
+ {
+ memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i]));
+ memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i]));
+ }
+ for (i = 0; i < kNumLenToPosStates; i++)
+ memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i]));
+ memcpy(dest->isRep, p->isRep, sizeof(p->isRep));
+ memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0));
+ memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1));
+ memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2));
+ memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));
+ memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));
+ memcpy(dest->reps, p->reps, sizeof(p->reps));
+ memcpy(dest->litProbs, p->litProbs, (0x300 << p->lclp) * sizeof(CLzmaProb));
+}
+
+void LzmaEnc_RestoreState(CLzmaEncHandle pp)
+{
+ CLzmaEnc *dest = (CLzmaEnc *)pp;
+ const CSaveState *p = &dest->saveState;
+ int i;
+ dest->lenEnc = p->lenEnc;
+ dest->repLenEnc = p->repLenEnc;
+ dest->state = p->state;
+
+ for (i = 0; i < kNumStates; i++)
+ {
+ memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i]));
+ memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i]));
+ }
+ for (i = 0; i < kNumLenToPosStates; i++)
+ memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i]));
+ memcpy(dest->isRep, p->isRep, sizeof(p->isRep));
+ memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0));
+ memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1));
+ memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2));
+ memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));
+ memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));
+ memcpy(dest->reps, p->reps, sizeof(p->reps));
+ memcpy(dest->litProbs, p->litProbs, (0x300 << dest->lclp) * sizeof(CLzmaProb));
+}
+
+SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
+{
+ CLzmaEnc *p = (CLzmaEnc *)pp;
+ CLzmaEncProps props = *props2;
+ LzmaEncProps_Normalize(&props);
+
+ if (props.lc > LZMA_LC_MAX || props.lp > LZMA_LP_MAX || props.pb > LZMA_PB_MAX ||
+ props.dictSize > (1 << kDicLogSizeMaxCompress) || props.dictSize > (1 << 30))
+ return SZ_ERROR_PARAM;
+ p->dictSize = props.dictSize;
+ p->matchFinderCycles = props.mc;
+ {
+ unsigned fb = props.fb;
+ if (fb < 5)
+ fb = 5;
+ if (fb > LZMA_MATCH_LEN_MAX)
+ fb = LZMA_MATCH_LEN_MAX;
+ p->numFastBytes = fb;
+ }
+ p->lc = props.lc;
+ p->lp = props.lp;
+ p->pb = props.pb;
+ p->fastMode = (props.algo == 0);
+ p->matchFinderBase.btMode = props.btMode;
+ {
+ UInt32 numHashBytes = 4;
+ if (props.btMode)
+ {
+ if (props.numHashBytes < 2)
+ numHashBytes = 2;
+ else if (props.numHashBytes < 4)
+ numHashBytes = props.numHashBytes;
+ }
+ p->matchFinderBase.numHashBytes = numHashBytes;
+ }
+
+ p->matchFinderBase.cutValue = props.mc;
+
+ p->writeEndMark = props.writeEndMark;
+
+ #ifdef COMPRESS_MF_MT
+ /*
+ if (newMultiThread != _multiThread)
+ {
+ ReleaseMatchFinder();
+ _multiThread = newMultiThread;
+ }
+ */
+ p->multiThread = (props.numThreads > 1);
+ #endif
+
+ return SZ_OK;
+}
+
+static const int kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5};
+static const int kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10};
+static const int kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};
+static const int kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11};
+
+#define IsCharState(s) ((s) < 7)
+
+#define GetLenToPosState(len) (((len) < kNumLenToPosStates + 1) ? (len) - 2 : kNumLenToPosStates - 1)
+
+#define kInfinityPrice (1 << 30)
+
+static void RangeEnc_Construct(CRangeEnc *p)
+{
+ p->outStream = 0;
+ p->bufBase = 0;
+}
+
+#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize)
+
+#define RC_BUF_SIZE (1 << 16)
+static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc)
+{
+ if (p->bufBase == 0)
+ {
+ p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE);
+ if (p->bufBase == 0)
+ return 0;
+ p->bufLim = p->bufBase + RC_BUF_SIZE;
+ }
+ return 1;
+}
+
+static void RangeEnc_Free(CRangeEnc *p, ISzAlloc *alloc)
+{
+ alloc->Free(alloc, p->bufBase);
+ p->bufBase = 0;
+}
+
+static void RangeEnc_Init(CRangeEnc *p)
+{
+ /* Stream.Init(); */
+ p->low = 0;
+ p->range = 0xFFFFFFFF;
+ p->cacheSize = 1;
+ p->cache = 0;
+
+ p->buf = p->bufBase;
+
+ p->processed = 0;
+ p->res = SZ_OK;
+}
+
+static void RangeEnc_FlushStream(CRangeEnc *p)
+{
+ size_t num;
+ if (p->res != SZ_OK)
+ return;
+ num = p->buf - p->bufBase;
+ if (num != p->outStream->Write(p->outStream, p->bufBase, num))
+ p->res = SZ_ERROR_WRITE;
+ p->processed += num;
+ p->buf = p->bufBase;
+}
+
+static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p)
+{
+ if ((UInt32)p->low < (UInt32)0xFF000000 || (int)(p->low >> 32) != 0)
+ {
+ Byte temp = p->cache;
+ do
+ {
+ Byte *buf = p->buf;
+ *buf++ = (Byte)(temp + (Byte)(p->low >> 32));
+ p->buf = buf;
+ if (buf == p->bufLim)
+ RangeEnc_FlushStream(p);
+ temp = 0xFF;
+ }
+ while (--p->cacheSize != 0);
+ p->cache = (Byte)((UInt32)p->low >> 24);
+ }
+ p->cacheSize++;
+ p->low = (UInt32)p->low << 8;
+}
+
+static void RangeEnc_FlushData(CRangeEnc *p)
+{
+ int i;
+ for (i = 0; i < 5; i++)
+ RangeEnc_ShiftLow(p);
+}
+
+static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, int numBits)
+{
+ do
+ {
+ p->range >>= 1;
+ p->low += p->range & (0 - ((value >> --numBits) & 1));
+ if (p->range < kTopValue)
+ {
+ p->range <<= 8;
+ RangeEnc_ShiftLow(p);
+ }
+ }
+ while (numBits != 0);
+}
+
+static void RangeEnc_EncodeBit(CRangeEnc *p, CLzmaProb *prob, UInt32 symbol)
+{
+ UInt32 ttt = *prob;
+ UInt32 newBound = (p->range >> kNumBitModelTotalBits) * ttt;
+ if (symbol == 0)
+ {
+ p->range = newBound;
+ ttt += (kBitModelTotal - ttt) >> kNumMoveBits;
+ }
+ else
+ {
+ p->low += newBound;
+ p->range -= newBound;
+ ttt -= ttt >> kNumMoveBits;
+ }
+ *prob = (CLzmaProb)ttt;
+ if (p->range < kTopValue)
+ {
+ p->range <<= 8;
+ RangeEnc_ShiftLow(p);
+ }
+}
+
+static void LitEnc_Encode(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol)
+{
+ symbol |= 0x100;
+ do
+ {
+ RangeEnc_EncodeBit(p, probs + (symbol >> 8), (symbol >> 7) & 1);
+ symbol <<= 1;
+ }
+ while (symbol < 0x10000);
+}
+
+static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol, UInt32 matchByte)
+{
+ UInt32 offs = 0x100;
+ symbol |= 0x100;
+ do
+ {
+ matchByte <<= 1;
+ RangeEnc_EncodeBit(p, probs + (offs + (matchByte & offs) + (symbol >> 8)), (symbol >> 7) & 1);
+ symbol <<= 1;
+ offs &= ~(matchByte ^ symbol);
+ }
+ while (symbol < 0x10000);
+}
+
+void LzmaEnc_InitPriceTables(UInt32 *ProbPrices)
+{
+ UInt32 i;
+ for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits))
+ {
+ const int kCyclesBits = kNumBitPriceShiftBits;
+ UInt32 w = i;
+ UInt32 bitCount = 0;
+ int j;
+ for (j = 0; j < kCyclesBits; j++)
+ {
+ w = w * w;
+ bitCount <<= 1;
+ while (w >= ((UInt32)1 << 16))
+ {
+ w >>= 1;
+ bitCount++;
+ }
+ }
+ ProbPrices[i >> kNumMoveReducingBits] = ((kNumBitModelTotalBits << kCyclesBits) - 15 - bitCount);
+ }
+}
+
+
+#define GET_PRICE(prob, symbol) \
+ p->ProbPrices[((prob) ^ (((-(int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits];
+
+#define GET_PRICEa(prob, symbol) \
+ ProbPrices[((prob) ^ ((-((int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits];
+
+#define GET_PRICE_0(prob) p->ProbPrices[(prob) >> kNumMoveReducingBits]
+#define GET_PRICE_1(prob) p->ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]
+
+#define GET_PRICE_0a(prob) ProbPrices[(prob) >> kNumMoveReducingBits]
+#define GET_PRICE_1a(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]
+
+static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, UInt32 *ProbPrices)
+{
+ UInt32 price = 0;
+ symbol |= 0x100;
+ do
+ {
+ price += GET_PRICEa(probs[symbol >> 8], (symbol >> 7) & 1);
+ symbol <<= 1;
+ }
+ while (symbol < 0x10000);
+ return price;
+}
+
+static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, UInt32 *ProbPrices)
+{
+ UInt32 price = 0;
+ UInt32 offs = 0x100;
+ symbol |= 0x100;
+ do
+ {
+ matchByte <<= 1;
+ price += GET_PRICEa(probs[offs + (matchByte & offs) + (symbol >> 8)], (symbol >> 7) & 1);
+ symbol <<= 1;
+ offs &= ~(matchByte ^ symbol);
+ }
+ while (symbol < 0x10000);
+ return price;
+}
+
+
+static void RcTree_Encode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol)
+{
+ UInt32 m = 1;
+ int i;
+ for (i = numBitLevels; i != 0;)
+ {
+ UInt32 bit;
+ i--;
+ bit = (symbol >> i) & 1;
+ RangeEnc_EncodeBit(rc, probs + m, bit);
+ m = (m << 1) | bit;
+ }
+}
+
+static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol)
+{
+ UInt32 m = 1;
+ int i;
+ for (i = 0; i < numBitLevels; i++)
+ {
+ UInt32 bit = symbol & 1;
+ RangeEnc_EncodeBit(rc, probs + m, bit);
+ m = (m << 1) | bit;
+ symbol >>= 1;
+ }
+}
+
+static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices)
+{
+ UInt32 price = 0;
+ symbol |= (1 << numBitLevels);
+ while (symbol != 1)
+ {
+ price += GET_PRICEa(probs[symbol >> 1], symbol & 1);
+ symbol >>= 1;
+ }
+ return price;
+}
+
+static UInt32 RcTree_ReverseGetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices)
+{
+ UInt32 price = 0;
+ UInt32 m = 1;
+ int i;
+ for (i = numBitLevels; i != 0; i--)
+ {
+ UInt32 bit = symbol & 1;
+ symbol >>= 1;
+ price += GET_PRICEa(probs[m], bit);
+ m = (m << 1) | bit;
+ }
+ return price;
+}
+
+
+static void LenEnc_Init(CLenEnc *p)
+{
+ unsigned i;
+ p->choice = p->choice2 = kProbInitValue;
+ for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumLowBits); i++)
+ p->low[i] = kProbInitValue;
+ for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumMidBits); i++)
+ p->mid[i] = kProbInitValue;
+ for (i = 0; i < kLenNumHighSymbols; i++)
+ p->high[i] = kProbInitValue;
+}
+
+static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState)
+{
+ if (symbol < kLenNumLowSymbols)
+ {
+ RangeEnc_EncodeBit(rc, &p->choice, 0);
+ RcTree_Encode(rc, p->low + (posState << kLenNumLowBits), kLenNumLowBits, symbol);
+ }
+ else
+ {
+ RangeEnc_EncodeBit(rc, &p->choice, 1);
+ if (symbol < kLenNumLowSymbols + kLenNumMidSymbols)
+ {
+ RangeEnc_EncodeBit(rc, &p->choice2, 0);
+ RcTree_Encode(rc, p->mid + (posState << kLenNumMidBits), kLenNumMidBits, symbol - kLenNumLowSymbols);
+ }
+ else
+ {
+ RangeEnc_EncodeBit(rc, &p->choice2, 1);
+ RcTree_Encode(rc, p->high, kLenNumHighBits, symbol - kLenNumLowSymbols - kLenNumMidSymbols);
+ }
+ }
+}
+
+static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UInt32 *prices, UInt32 *ProbPrices)
+{
+ UInt32 a0 = GET_PRICE_0a(p->choice);
+ UInt32 a1 = GET_PRICE_1a(p->choice);
+ UInt32 b0 = a1 + GET_PRICE_0a(p->choice2);
+ UInt32 b1 = a1 + GET_PRICE_1a(p->choice2);
+ UInt32 i = 0;
+ for (i = 0; i < kLenNumLowSymbols; i++)
+ {
+ if (i >= numSymbols)
+ return;
+ prices[i] = a0 + RcTree_GetPrice(p->low + (posState << kLenNumLowBits), kLenNumLowBits, i, ProbPrices);
+ }
+ for (; i < kLenNumLowSymbols + kLenNumMidSymbols; i++)
+ {
+ if (i >= numSymbols)
+ return;
+ prices[i] = b0 + RcTree_GetPrice(p->mid + (posState << kLenNumMidBits), kLenNumMidBits, i - kLenNumLowSymbols, ProbPrices);
+ }
+ for (; i < numSymbols; i++)
+ prices[i] = b1 + RcTree_GetPrice(p->high, kLenNumHighBits, i - kLenNumLowSymbols - kLenNumMidSymbols, ProbPrices);
+}
+
+static void MY_FAST_CALL LenPriceEnc_UpdateTable(CLenPriceEnc *p, UInt32 posState, UInt32 *ProbPrices)
+{
+ LenEnc_SetPrices(&p->p, posState, p->tableSize, p->prices[posState], ProbPrices);
+ p->counters[posState] = p->tableSize;
+}
+
+static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, UInt32 numPosStates, UInt32 *ProbPrices)
+{
+ UInt32 posState;
+ for (posState = 0; posState < numPosStates; posState++)
+ LenPriceEnc_UpdateTable(p, posState, ProbPrices);
+}
+
+static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState, Bool updatePrice, UInt32 *ProbPrices)
+{
+ LenEnc_Encode(&p->p, rc, symbol, posState);
+ if (updatePrice)
+ if (--p->counters[posState] == 0)
+ LenPriceEnc_UpdateTable(p, posState, ProbPrices);
+}
+
+
+
+
+static void MovePos(CLzmaEnc *p, UInt32 num)
+{
+ #ifdef SHOW_STAT
+ ttt += num;
+ printf("\n MovePos %d", num);
+ #endif
+ if (num != 0)
+ {
+ p->additionalOffset += num;
+ p->matchFinder.Skip(p->matchFinderObj, num);
+ }
+}
+
+static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes)
+{
+ UInt32 lenRes = 0, numPairs;
+ p->numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
+ numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches);
+ #ifdef SHOW_STAT
+ printf("\n i = %d numPairs = %d ", ttt, numPairs / 2);
+ ttt++;
+ {
+ UInt32 i;
+ for (i = 0; i < numPairs; i += 2)
+ printf("%2d %6d | ", p->matches[i], p->matches[i + 1]);
+ }
+ #endif
+ if (numPairs > 0)
+ {
+ lenRes = p->matches[numPairs - 2];
+ if (lenRes == p->numFastBytes)
+ {
+ const Byte *pby = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
+ UInt32 distance = p->matches[numPairs - 1] + 1;
+ UInt32 numAvail = p->numAvail;
+ if (numAvail > LZMA_MATCH_LEN_MAX)
+ numAvail = LZMA_MATCH_LEN_MAX;
+ {
+ const Byte *pby2 = pby - distance;
+ for (; lenRes < numAvail && pby[lenRes] == pby2[lenRes]; lenRes++);
+ }
+ }
+ }
+ p->additionalOffset++;
+ *numDistancePairsRes = numPairs;
+ return lenRes;
+}
+
+
+#define MakeAsChar(p) (p)->backPrev = (UInt32)(-1); (p)->prev1IsChar = False;
+#define MakeAsShortRep(p) (p)->backPrev = 0; (p)->prev1IsChar = False;
+#define IsShortRep(p) ((p)->backPrev == 0)
+
+static UInt32 GetRepLen1Price(CLzmaEnc *p, UInt32 state, UInt32 posState)
+{
+ return
+ GET_PRICE_0(p->isRepG0[state]) +
+ GET_PRICE_0(p->isRep0Long[state][posState]);
+}
+
+static UInt32 GetPureRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 state, UInt32 posState)
+{
+ UInt32 price;
+ if (repIndex == 0)
+ {
+ price = GET_PRICE_0(p->isRepG0[state]);
+ price += GET_PRICE_1(p->isRep0Long[state][posState]);
+ }
+ else
+ {
+ price = GET_PRICE_1(p->isRepG0[state]);
+ if (repIndex == 1)
+ price += GET_PRICE_0(p->isRepG1[state]);
+ else
+ {
+ price += GET_PRICE_1(p->isRepG1[state]);
+ price += GET_PRICE(p->isRepG2[state], repIndex - 2);
+ }
+ }
+ return price;
+}
+
+static UInt32 GetRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 len, UInt32 state, UInt32 posState)
+{
+ return p->repLenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN] +
+ GetPureRepPrice(p, repIndex, state, posState);
+}
+
+static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur)
+{
+ UInt32 posMem = p->opt[cur].posPrev;
+ UInt32 backMem = p->opt[cur].backPrev;
+ p->optimumEndIndex = cur;
+ do
+ {
+ if (p->opt[cur].prev1IsChar)
+ {
+ MakeAsChar(&p->opt[posMem])
+ p->opt[posMem].posPrev = posMem - 1;
+ if (p->opt[cur].prev2)
+ {
+ p->opt[posMem - 1].prev1IsChar = False;
+ p->opt[posMem - 1].posPrev = p->opt[cur].posPrev2;
+ p->opt[posMem - 1].backPrev = p->opt[cur].backPrev2;
+ }
+ }
+ {
+ UInt32 posPrev = posMem;
+ UInt32 backCur = backMem;
+
+ backMem = p->opt[posPrev].backPrev;
+ posMem = p->opt[posPrev].posPrev;
+
+ p->opt[posPrev].backPrev = backCur;
+ p->opt[posPrev].posPrev = cur;
+ cur = posPrev;
+ }
+ }
+ while (cur != 0);
+ *backRes = p->opt[0].backPrev;
+ p->optimumCurrentIndex = p->opt[0].posPrev;
+ return p->optimumCurrentIndex;
+}
+
+#define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + ((prevByte) >> (8 - p->lc))) * 0x300)
+
+static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
+{
+ UInt32 numAvail, mainLen, numPairs, repMaxIndex, i, posState, lenEnd, len, cur;
+ UInt32 matchPrice, repMatchPrice, normalMatchPrice;
+ UInt32 reps[LZMA_NUM_REPS], repLens[LZMA_NUM_REPS];
+ UInt32 *matches;
+ const Byte *data;
+ Byte curByte, matchByte;
+ if (p->optimumEndIndex != p->optimumCurrentIndex)
+ {
+ const COptimal *opt = &p->opt[p->optimumCurrentIndex];
+ UInt32 lenRes = opt->posPrev - p->optimumCurrentIndex;
+ *backRes = opt->backPrev;
+ p->optimumCurrentIndex = opt->posPrev;
+ return lenRes;
+ }
+ p->optimumCurrentIndex = p->optimumEndIndex = 0;
+
+ if (p->additionalOffset == 0)
+ mainLen = ReadMatchDistances(p, &numPairs);
+ else
+ {
+ mainLen = p->longestMatchLength;
+ numPairs = p->numPairs;
+ }
+
+ numAvail = p->numAvail;
+ if (numAvail < 2)
+ {
+ *backRes = (UInt32)(-1);
+ return 1;
+ }
+ if (numAvail > LZMA_MATCH_LEN_MAX)
+ numAvail = LZMA_MATCH_LEN_MAX;
+
+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
+ repMaxIndex = 0;
+ for (i = 0; i < LZMA_NUM_REPS; i++)
+ {
+ UInt32 lenTest;
+ const Byte *data2;
+ reps[i] = p->reps[i];
+ data2 = data - (reps[i] + 1);
+ if (data[0] != data2[0] || data[1] != data2[1])
+ {
+ repLens[i] = 0;
+ continue;
+ }
+ for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++);
+ repLens[i] = lenTest;
+ if (lenTest > repLens[repMaxIndex])
+ repMaxIndex = i;
+ }
+ if (repLens[repMaxIndex] >= p->numFastBytes)
+ {
+ UInt32 lenRes;
+ *backRes = repMaxIndex;
+ lenRes = repLens[repMaxIndex];
+ MovePos(p, lenRes - 1);
+ return lenRes;
+ }
+
+ matches = p->matches;
+ if (mainLen >= p->numFastBytes)
+ {
+ *backRes = matches[numPairs - 1] + LZMA_NUM_REPS;
+ MovePos(p, mainLen - 1);
+ return mainLen;
+ }
+ curByte = *data;
+ matchByte = *(data - (reps[0] + 1));
+
+ if (mainLen < 2 && curByte != matchByte && repLens[repMaxIndex] < 2)
+ {
+ *backRes = (UInt32)-1;
+ return 1;
+ }
+
+ p->opt[0].state = (CState)p->state;
+
+ posState = (position & p->pbMask);
+
+ {
+ const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));
+ p->opt[1].price = GET_PRICE_0(p->isMatch[p->state][posState]) +
+ (!IsCharState(p->state) ?
+ LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) :
+ LitEnc_GetPrice(probs, curByte, p->ProbPrices));
+ }
+
+ MakeAsChar(&p->opt[1]);
+
+ matchPrice = GET_PRICE_1(p->isMatch[p->state][posState]);
+ repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[p->state]);
+
+ if (matchByte == curByte)
+ {
+ UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, p->state, posState);
+ if (shortRepPrice < p->opt[1].price)
+ {
+ p->opt[1].price = shortRepPrice;
+ MakeAsShortRep(&p->opt[1]);
+ }
+ }
+ lenEnd = ((mainLen >= repLens[repMaxIndex]) ? mainLen : repLens[repMaxIndex]);
+
+ if (lenEnd < 2)
+ {
+ *backRes = p->opt[1].backPrev;
+ return 1;
+ }
+
+ p->opt[1].posPrev = 0;
+ for (i = 0; i < LZMA_NUM_REPS; i++)
+ p->opt[0].backs[i] = reps[i];
+
+ len = lenEnd;
+ do
+ p->opt[len--].price = kInfinityPrice;
+ while (len >= 2);
+
+ for (i = 0; i < LZMA_NUM_REPS; i++)
+ {
+ UInt32 repLen = repLens[i];
+ UInt32 price;
+ if (repLen < 2)
+ continue;
+ price = repMatchPrice + GetPureRepPrice(p, i, p->state, posState);
+ do
+ {
+ UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][repLen - 2];
+ COptimal *opt = &p->opt[repLen];
+ if (curAndLenPrice < opt->price)
+ {
+ opt->price = curAndLenPrice;
+ opt->posPrev = 0;
+ opt->backPrev = i;
+ opt->prev1IsChar = False;
+ }
+ }
+ while (--repLen >= 2);
+ }
+
+ normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[p->state]);
+
+ len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2);
+ if (len <= mainLen)
+ {
+ UInt32 offs = 0;
+ while (len > matches[offs])
+ offs += 2;
+ for (; ; len++)
+ {
+ COptimal *opt;
+ UInt32 distance = matches[offs + 1];
+
+ UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN];
+ UInt32 lenToPosState = GetLenToPosState(len);
+ if (distance < kNumFullDistances)
+ curAndLenPrice += p->distancesPrices[lenToPosState][distance];
+ else
+ {
+ UInt32 slot;
+ GetPosSlot2(distance, slot);
+ curAndLenPrice += p->alignPrices[distance & kAlignMask] + p->posSlotPrices[lenToPosState][slot];
+ }
+ opt = &p->opt[len];
+ if (curAndLenPrice < opt->price)
+ {
+ opt->price = curAndLenPrice;
+ opt->posPrev = 0;
+ opt->backPrev = distance + LZMA_NUM_REPS;
+ opt->prev1IsChar = False;
+ }
+ if (len == matches[offs])
+ {
+ offs += 2;
+ if (offs == numPairs)
+ break;
+ }
+ }
+ }
+
+ cur = 0;
+
+ #ifdef SHOW_STAT2
+ if (position >= 0)
+ {
+ unsigned i;
+ printf("\n pos = %4X", position);
+ for (i = cur; i <= lenEnd; i++)
+ printf("\nprice[%4X] = %d", position - cur + i, p->opt[i].price);
+ }
+ #endif
+
+ for (;;)
+ {
+ UInt32 numAvailFull, newLen, numPairs, posPrev, state, posState, startLen;
+ UInt32 curPrice, curAnd1Price, matchPrice, repMatchPrice;
+ Bool nextIsChar;
+ Byte curByte, matchByte;
+ const Byte *data;
+ COptimal *curOpt;
+ COptimal *nextOpt;
+
+ cur++;
+ if (cur == lenEnd)
+ return Backward(p, backRes, cur);
+
+ newLen = ReadMatchDistances(p, &numPairs);
+ if (newLen >= p->numFastBytes)
+ {
+ p->numPairs = numPairs;
+ p->longestMatchLength = newLen;
+ return Backward(p, backRes, cur);
+ }
+ position++;
+ curOpt = &p->opt[cur];
+ posPrev = curOpt->posPrev;
+ if (curOpt->prev1IsChar)
+ {
+ posPrev--;
+ if (curOpt->prev2)
+ {
+ state = p->opt[curOpt->posPrev2].state;
+ if (curOpt->backPrev2 < LZMA_NUM_REPS)
+ state = kRepNextStates[state];
+ else
+ state = kMatchNextStates[state];
+ }
+ else
+ state = p->opt[posPrev].state;
+ state = kLiteralNextStates[state];
+ }
+ else
+ state = p->opt[posPrev].state;
+ if (posPrev == cur - 1)
+ {
+ if (IsShortRep(curOpt))
+ state = kShortRepNextStates[state];
+ else
+ state = kLiteralNextStates[state];
+ }
+ else
+ {
+ UInt32 pos;
+ const COptimal *prevOpt;
+ if (curOpt->prev1IsChar && curOpt->prev2)
+ {
+ posPrev = curOpt->posPrev2;
+ pos = curOpt->backPrev2;
+ state = kRepNextStates[state];
+ }
+ else
+ {
+ pos = curOpt->backPrev;
+ if (pos < LZMA_NUM_REPS)
+ state = kRepNextStates[state];
+ else
+ state = kMatchNextStates[state];
+ }
+ prevOpt = &p->opt[posPrev];
+ if (pos < LZMA_NUM_REPS)
+ {
+ UInt32 i;
+ reps[0] = prevOpt->backs[pos];
+ for (i = 1; i <= pos; i++)
+ reps[i] = prevOpt->backs[i - 1];
+ for (; i < LZMA_NUM_REPS; i++)
+ reps[i] = prevOpt->backs[i];
+ }
+ else
+ {
+ UInt32 i;
+ reps[0] = (pos - LZMA_NUM_REPS);
+ for (i = 1; i < LZMA_NUM_REPS; i++)
+ reps[i] = prevOpt->backs[i - 1];
+ }
+ }
+ curOpt->state = (CState)state;
+
+ curOpt->backs[0] = reps[0];
+ curOpt->backs[1] = reps[1];
+ curOpt->backs[2] = reps[2];
+ curOpt->backs[3] = reps[3];
+
+ curPrice = curOpt->price;
+ nextIsChar = False;
+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
+ curByte = *data;
+ matchByte = *(data - (reps[0] + 1));
+
+ posState = (position & p->pbMask);
+
+ curAnd1Price = curPrice + GET_PRICE_0(p->isMatch[state][posState]);
+ {
+ const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));
+ curAnd1Price +=
+ (!IsCharState(state) ?
+ LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) :
+ LitEnc_GetPrice(probs, curByte, p->ProbPrices));
+ }
+
+ nextOpt = &p->opt[cur + 1];
+
+ if (curAnd1Price < nextOpt->price)
+ {
+ nextOpt->price = curAnd1Price;
+ nextOpt->posPrev = cur;
+ MakeAsChar(nextOpt);
+ nextIsChar = True;
+ }
+
+ matchPrice = curPrice + GET_PRICE_1(p->isMatch[state][posState]);
+ repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]);
+
+ if (matchByte == curByte && !(nextOpt->posPrev < cur && nextOpt->backPrev == 0))
+ {
+ UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, state, posState);
+ if (shortRepPrice <= nextOpt->price)
+ {
+ nextOpt->price = shortRepPrice;
+ nextOpt->posPrev = cur;
+ MakeAsShortRep(nextOpt);
+ nextIsChar = True;
+ }
+ }
+ numAvailFull = p->numAvail;
+ {
+ UInt32 temp = kNumOpts - 1 - cur;
+ if (temp < numAvailFull)
+ numAvailFull = temp;
+ }
+
+ if (numAvailFull < 2)
+ continue;
+ numAvail = (numAvailFull <= p->numFastBytes ? numAvailFull : p->numFastBytes);
+
+ if (!nextIsChar && matchByte != curByte) /* speed optimization */
+ {
+ /* try Literal + rep0 */
+ UInt32 temp;
+ UInt32 lenTest2;
+ const Byte *data2 = data - (reps[0] + 1);
+ UInt32 limit = p->numFastBytes + 1;
+ if (limit > numAvailFull)
+ limit = numAvailFull;
+
+ for (temp = 1; temp < limit && data[temp] == data2[temp]; temp++);
+ lenTest2 = temp - 1;
+ if (lenTest2 >= 2)
+ {
+ UInt32 state2 = kLiteralNextStates[state];
+ UInt32 posStateNext = (position + 1) & p->pbMask;
+ UInt32 nextRepMatchPrice = curAnd1Price +
+ GET_PRICE_1(p->isMatch[state2][posStateNext]) +
+ GET_PRICE_1(p->isRep[state2]);
+ /* for (; lenTest2 >= 2; lenTest2--) */
+ {
+ UInt32 curAndLenPrice;
+ COptimal *opt;
+ UInt32 offset = cur + 1 + lenTest2;
+ while (lenEnd < offset)
+ p->opt[++lenEnd].price = kInfinityPrice;
+ curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
+ opt = &p->opt[offset];
+ if (curAndLenPrice < opt->price)
+ {
+ opt->price = curAndLenPrice;
+ opt->posPrev = cur + 1;
+ opt->backPrev = 0;
+ opt->prev1IsChar = True;
+ opt->prev2 = False;
+ }
+ }
+ }
+ }
+
+ startLen = 2; /* speed optimization */
+ {
+ UInt32 repIndex;
+ for (repIndex = 0; repIndex < LZMA_NUM_REPS; repIndex++)
+ {
+ UInt32 lenTest;
+ UInt32 lenTestTemp;
+ UInt32 price;
+ const Byte *data2 = data - (reps[repIndex] + 1);
+ if (data[0] != data2[0] || data[1] != data2[1])
+ continue;
+ for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++);
+ while (lenEnd < cur + lenTest)
+ p->opt[++lenEnd].price = kInfinityPrice;
+ lenTestTemp = lenTest;
+ price = repMatchPrice + GetPureRepPrice(p, repIndex, state, posState);
+ do
+ {
+ UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][lenTest - 2];
+ COptimal *opt = &p->opt[cur + lenTest];
+ if (curAndLenPrice < opt->price)
+ {
+ opt->price = curAndLenPrice;
+ opt->posPrev = cur;
+ opt->backPrev = repIndex;
+ opt->prev1IsChar = False;
+ }
+ }
+ while (--lenTest >= 2);
+ lenTest = lenTestTemp;
+
+ if (repIndex == 0)
+ startLen = lenTest + 1;
+
+ /* if (_maxMode) */
+ {
+ UInt32 lenTest2 = lenTest + 1;
+ UInt32 limit = lenTest2 + p->numFastBytes;
+ UInt32 nextRepMatchPrice;
+ if (limit > numAvailFull)
+ limit = numAvailFull;
+ for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
+ lenTest2 -= lenTest + 1;
+ if (lenTest2 >= 2)
+ {
+ UInt32 state2 = kRepNextStates[state];
+ UInt32 posStateNext = (position + lenTest) & p->pbMask;
+ UInt32 curAndLenCharPrice =
+ price + p->repLenEnc.prices[posState][lenTest - 2] +
+ GET_PRICE_0(p->isMatch[state2][posStateNext]) +
+ LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]),
+ data[lenTest], data2[lenTest], p->ProbPrices);
+ state2 = kLiteralNextStates[state2];
+ posStateNext = (position + lenTest + 1) & p->pbMask;
+ nextRepMatchPrice = curAndLenCharPrice +
+ GET_PRICE_1(p->isMatch[state2][posStateNext]) +
+ GET_PRICE_1(p->isRep[state2]);
+
+ /* for (; lenTest2 >= 2; lenTest2--) */
+ {
+ UInt32 curAndLenPrice;
+ COptimal *opt;
+ UInt32 offset = cur + lenTest + 1 + lenTest2;
+ while (lenEnd < offset)
+ p->opt[++lenEnd].price = kInfinityPrice;
+ curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
+ opt = &p->opt[offset];
+ if (curAndLenPrice < opt->price)
+ {
+ opt->price = curAndLenPrice;
+ opt->posPrev = cur + lenTest + 1;
+ opt->backPrev = 0;
+ opt->prev1IsChar = True;
+ opt->prev2 = True;
+ opt->posPrev2 = cur;
+ opt->backPrev2 = repIndex;
+ }
+ }
+ }
+ }
+ }
+ }
+ /* for (UInt32 lenTest = 2; lenTest <= newLen; lenTest++) */
+ if (newLen > numAvail)
+ {
+ newLen = numAvail;
+ for (numPairs = 0; newLen > matches[numPairs]; numPairs += 2);
+ matches[numPairs] = newLen;
+ numPairs += 2;
+ }
+ if (newLen >= startLen)
+ {
+ UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[state]);
+ UInt32 offs, curBack, posSlot;
+ UInt32 lenTest;
+ while (lenEnd < cur + newLen)
+ p->opt[++lenEnd].price = kInfinityPrice;
+
+ offs = 0;
+ while (startLen > matches[offs])
+ offs += 2;
+ curBack = matches[offs + 1];
+ GetPosSlot2(curBack, posSlot);
+ for (lenTest = /*2*/ startLen; ; lenTest++)
+ {
+ UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][lenTest - LZMA_MATCH_LEN_MIN];
+ UInt32 lenToPosState = GetLenToPosState(lenTest);
+ COptimal *opt;
+ if (curBack < kNumFullDistances)
+ curAndLenPrice += p->distancesPrices[lenToPosState][curBack];
+ else
+ curAndLenPrice += p->posSlotPrices[lenToPosState][posSlot] + p->alignPrices[curBack & kAlignMask];
+
+ opt = &p->opt[cur + lenTest];
+ if (curAndLenPrice < opt->price)
+ {
+ opt->price = curAndLenPrice;
+ opt->posPrev = cur;
+ opt->backPrev = curBack + LZMA_NUM_REPS;
+ opt->prev1IsChar = False;
+ }
+
+ if (/*_maxMode && */lenTest == matches[offs])
+ {
+ /* Try Match + Literal + Rep0 */
+ const Byte *data2 = data - (curBack + 1);
+ UInt32 lenTest2 = lenTest + 1;
+ UInt32 limit = lenTest2 + p->numFastBytes;
+ UInt32 nextRepMatchPrice;
+ if (limit > numAvailFull)
+ limit = numAvailFull;
+ for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
+ lenTest2 -= lenTest + 1;
+ if (lenTest2 >= 2)
+ {
+ UInt32 state2 = kMatchNextStates[state];
+ UInt32 posStateNext = (position + lenTest) & p->pbMask;
+ UInt32 curAndLenCharPrice = curAndLenPrice +
+ GET_PRICE_0(p->isMatch[state2][posStateNext]) +
+ LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]),
+ data[lenTest], data2[lenTest], p->ProbPrices);
+ state2 = kLiteralNextStates[state2];
+ posStateNext = (posStateNext + 1) & p->pbMask;
+ nextRepMatchPrice = curAndLenCharPrice +
+ GET_PRICE_1(p->isMatch[state2][posStateNext]) +
+ GET_PRICE_1(p->isRep[state2]);
+
+ /* for (; lenTest2 >= 2; lenTest2--) */
+ {
+ UInt32 offset = cur + lenTest + 1 + lenTest2;
+ UInt32 curAndLenPrice;
+ COptimal *opt;
+ while (lenEnd < offset)
+ p->opt[++lenEnd].price = kInfinityPrice;
+ curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
+ opt = &p->opt[offset];
+ if (curAndLenPrice < opt->price)
+ {
+ opt->price = curAndLenPrice;
+ opt->posPrev = cur + lenTest + 1;
+ opt->backPrev = 0;
+ opt->prev1IsChar = True;
+ opt->prev2 = True;
+ opt->posPrev2 = cur;
+ opt->backPrev2 = curBack + LZMA_NUM_REPS;
+ }
+ }
+ }
+ offs += 2;
+ if (offs == numPairs)
+ break;
+ curBack = matches[offs + 1];
+ if (curBack >= kNumFullDistances)
+ GetPosSlot2(curBack, posSlot);
+ }
+ }
+ }
+ }
+}
+
+#define ChangePair(smallDist, bigDist) (((bigDist) >> 7) > (smallDist))
+
+static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes)
+{
+ UInt32 numAvail, mainLen, mainDist, numPairs, repIndex, repLen, i;
+ const Byte *data;
+ const UInt32 *matches;
+
+ if (p->additionalOffset == 0)
+ mainLen = ReadMatchDistances(p, &numPairs);
+ else
+ {
+ mainLen = p->longestMatchLength;
+ numPairs = p->numPairs;
+ }
+
+ numAvail = p->numAvail;
+ *backRes = (UInt32)-1;
+ if (numAvail < 2)
+ return 1;
+ if (numAvail > LZMA_MATCH_LEN_MAX)
+ numAvail = LZMA_MATCH_LEN_MAX;
+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
+
+ repLen = repIndex = 0;
+ for (i = 0; i < LZMA_NUM_REPS; i++)
+ {
+ UInt32 len;
+ const Byte *data2 = data - (p->reps[i] + 1);
+ if (data[0] != data2[0] || data[1] != data2[1])
+ continue;
+ for (len = 2; len < numAvail && data[len] == data2[len]; len++);
+ if (len >= p->numFastBytes)
+ {
+ *backRes = i;
+ MovePos(p, len - 1);
+ return len;
+ }
+ if (len > repLen)
+ {
+ repIndex = i;
+ repLen = len;
+ }
+ }
+
+ matches = p->matches;
+ if (mainLen >= p->numFastBytes)
+ {
+ *backRes = matches[numPairs - 1] + LZMA_NUM_REPS;
+ MovePos(p, mainLen - 1);
+ return mainLen;
+ }
+
+ mainDist = 0; /* for GCC */
+ if (mainLen >= 2)
+ {
+ mainDist = matches[numPairs - 1];
+ while (numPairs > 2 && mainLen == matches[numPairs - 4] + 1)
+ {
+ if (!ChangePair(matches[numPairs - 3], mainDist))
+ break;
+ numPairs -= 2;
+ mainLen = matches[numPairs - 2];
+ mainDist = matches[numPairs - 1];
+ }
+ if (mainLen == 2 && mainDist >= 0x80)
+ mainLen = 1;
+ }
+
+ if (repLen >= 2 && (
+ (repLen + 1 >= mainLen) ||
+ (repLen + 2 >= mainLen && mainDist >= (1 << 9)) ||
+ (repLen + 3 >= mainLen && mainDist >= (1 << 15))))
+ {
+ *backRes = repIndex;
+ MovePos(p, repLen - 1);
+ return repLen;
+ }
+
+ if (mainLen < 2 || numAvail <= 2)
+ return 1;
+
+ p->longestMatchLength = ReadMatchDistances(p, &p->numPairs);
+ if (p->longestMatchLength >= 2)
+ {
+ UInt32 newDistance = matches[p->numPairs - 1];
+ if ((p->longestMatchLength >= mainLen && newDistance < mainDist) ||
+ (p->longestMatchLength == mainLen + 1 && !ChangePair(mainDist, newDistance)) ||
+ (p->longestMatchLength > mainLen + 1) ||
+ (p->longestMatchLength + 1 >= mainLen && mainLen >= 3 && ChangePair(newDistance, mainDist)))
+ return 1;
+ }
+
+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
+ for (i = 0; i < LZMA_NUM_REPS; i++)
+ {
+ UInt32 len, limit;
+ const Byte *data2 = data - (p->reps[i] + 1);
+ if (data[0] != data2[0] || data[1] != data2[1])
+ continue;
+ limit = mainLen - 1;
+ for (len = 2; len < limit && data[len] == data2[len]; len++);
+ if (len >= limit)
+ return 1;
+ }
+ *backRes = mainDist + LZMA_NUM_REPS;
+ MovePos(p, mainLen - 2);
+ return mainLen;
+}
+
+static void WriteEndMarker(CLzmaEnc *p, UInt32 posState)
+{
+ UInt32 len;
+ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1);
+ RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0);
+ p->state = kMatchNextStates[p->state];
+ len = LZMA_MATCH_LEN_MIN;
+ LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
+ RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, (1 << kNumPosSlotBits) - 1);
+ RangeEnc_EncodeDirectBits(&p->rc, (((UInt32)1 << 30) - 1) >> kNumAlignBits, 30 - kNumAlignBits);
+ RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, kAlignMask);
+}
+
+static SRes CheckErrors(CLzmaEnc *p)
+{
+ if (p->result != SZ_OK)
+ return p->result;
+ if (p->rc.res != SZ_OK)
+ p->result = SZ_ERROR_WRITE;
+ if (p->matchFinderBase.result != SZ_OK)
+ p->result = SZ_ERROR_READ;
+ if (p->result != SZ_OK)
+ p->finished = True;
+ return p->result;
+}
+
+static SRes Flush(CLzmaEnc *p, UInt32 nowPos)
+{
+ /* ReleaseMFStream(); */
+ p->finished = True;
+ if (p->writeEndMark)
+ WriteEndMarker(p, nowPos & p->pbMask);
+ RangeEnc_FlushData(&p->rc);
+ RangeEnc_FlushStream(&p->rc);
+ return CheckErrors(p);
+}
+
+static void FillAlignPrices(CLzmaEnc *p)
+{
+ UInt32 i;
+ for (i = 0; i < kAlignTableSize; i++)
+ p->alignPrices[i] = RcTree_ReverseGetPrice(p->posAlignEncoder, kNumAlignBits, i, p->ProbPrices);
+ p->alignPriceCount = 0;
+}
+
+static void FillDistancesPrices(CLzmaEnc *p)
+{
+ UInt32 tempPrices[kNumFullDistances];
+ UInt32 i, lenToPosState;
+ for (i = kStartPosModelIndex; i < kNumFullDistances; i++)
+ {
+ UInt32 posSlot = GetPosSlot1(i);
+ UInt32 footerBits = ((posSlot >> 1) - 1);
+ UInt32 base = ((2 | (posSlot & 1)) << footerBits);
+ tempPrices[i] = RcTree_ReverseGetPrice(p->posEncoders + base - posSlot - 1, footerBits, i - base, p->ProbPrices);
+ }
+
+ for (lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++)
+ {
+ UInt32 posSlot;
+ const CLzmaProb *encoder = p->posSlotEncoder[lenToPosState];
+ UInt32 *posSlotPrices = p->posSlotPrices[lenToPosState];
+ for (posSlot = 0; posSlot < p->distTableSize; posSlot++)
+ posSlotPrices[posSlot] = RcTree_GetPrice(encoder, kNumPosSlotBits, posSlot, p->ProbPrices);
+ for (posSlot = kEndPosModelIndex; posSlot < p->distTableSize; posSlot++)
+ posSlotPrices[posSlot] += ((((posSlot >> 1) - 1) - kNumAlignBits) << kNumBitPriceShiftBits);
+
+ {
+ UInt32 *distancesPrices = p->distancesPrices[lenToPosState];
+ UInt32 i;
+ for (i = 0; i < kStartPosModelIndex; i++)
+ distancesPrices[i] = posSlotPrices[i];
+ for (; i < kNumFullDistances; i++)
+ distancesPrices[i] = posSlotPrices[GetPosSlot1(i)] + tempPrices[i];
+ }
+ }
+ p->matchPriceCount = 0;
+}
+
+void LzmaEnc_Construct(CLzmaEnc *p)
+{
+ RangeEnc_Construct(&p->rc);
+ MatchFinder_Construct(&p->matchFinderBase);
+ #ifdef COMPRESS_MF_MT
+ MatchFinderMt_Construct(&p->matchFinderMt);
+ p->matchFinderMt.MatchFinder = &p->matchFinderBase;
+ #endif
+
+ {
+ CLzmaEncProps props;
+ LzmaEncProps_Init(&props);
+ LzmaEnc_SetProps(p, &props);
+ }
+
+ #ifndef LZMA_LOG_BSR
+ LzmaEnc_FastPosInit(p->g_FastPos);
+ #endif
+
+ LzmaEnc_InitPriceTables(p->ProbPrices);
+ p->litProbs = 0;
+ p->saveState.litProbs = 0;
+}
+
+CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc)
+{
+ void *p;
+ p = alloc->Alloc(alloc, sizeof(CLzmaEnc));
+ if (p != 0)
+ LzmaEnc_Construct((CLzmaEnc *)p);
+ return p;
+}
+
+void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc)
+{
+ alloc->Free(alloc, p->litProbs);
+ alloc->Free(alloc, p->saveState.litProbs);
+ p->litProbs = 0;
+ p->saveState.litProbs = 0;
+}
+
+void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+ #ifdef COMPRESS_MF_MT
+ MatchFinderMt_Destruct(&p->matchFinderMt, allocBig);
+ #endif
+ MatchFinder_Free(&p->matchFinderBase, allocBig);
+ LzmaEnc_FreeLits(p, alloc);
+ RangeEnc_Free(&p->rc, alloc);
+}
+
+void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+ LzmaEnc_Destruct((CLzmaEnc *)p, alloc, allocBig);
+ alloc->Free(alloc, p);
+}
+
+static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize, UInt32 maxUnpackSize)
+{
+ UInt32 nowPos32, startPos32;
+ if (p->inStream != 0)
+ {
+ p->matchFinderBase.stream = p->inStream;
+ p->matchFinder.Init(p->matchFinderObj);
+ p->inStream = 0;
+ }
+
+ if (p->finished)
+ return p->result;
+ RINOK(CheckErrors(p));
+
+ nowPos32 = (UInt32)p->nowPos64;
+ startPos32 = nowPos32;
+
+ if (p->nowPos64 == 0)
+ {
+ UInt32 numPairs;
+ Byte curByte;
+ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0)
+ return Flush(p, nowPos32);
+ ReadMatchDistances(p, &numPairs);
+ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][0], 0);
+ p->state = kLiteralNextStates[p->state];
+ curByte = p->matchFinder.GetIndexByte(p->matchFinderObj, 0 - p->additionalOffset);
+ LitEnc_Encode(&p->rc, p->litProbs, curByte);
+ p->additionalOffset--;
+ nowPos32++;
+ }
+
+ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) != 0)
+ for (;;)
+ {
+ UInt32 pos, len, posState;
+
+ if (p->fastMode)
+ len = GetOptimumFast(p, &pos);
+ else
+ len = GetOptimum(p, nowPos32, &pos);
+
+ #ifdef SHOW_STAT2
+ printf("\n pos = %4X, len = %d pos = %d", nowPos32, len, pos);
+ #endif
+
+ posState = nowPos32 & p->pbMask;
+ if (len == 1 && pos == (UInt32)-1)
+ {
+ Byte curByte;
+ CLzmaProb *probs;
+ const Byte *data;
+
+ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 0);
+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
+ curByte = *data;
+ probs = LIT_PROBS(nowPos32, *(data - 1));
+ if (IsCharState(p->state))
+ LitEnc_Encode(&p->rc, probs, curByte);
+ else
+ LitEnc_EncodeMatched(&p->rc, probs, curByte, *(data - p->reps[0] - 1));
+ p->state = kLiteralNextStates[p->state];
+ }
+ else
+ {
+ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1);
+ if (pos < LZMA_NUM_REPS)
+ {
+ RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 1);
+ if (pos == 0)
+ {
+ RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 0);
+ RangeEnc_EncodeBit(&p->rc, &p->isRep0Long[p->state][posState], ((len == 1) ? 0 : 1));
+ }
+ else
+ {
+ UInt32 distance = p->reps[pos];
+ RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 1);
+ if (pos == 1)
+ RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 0);
+ else
+ {
+ RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 1);
+ RangeEnc_EncodeBit(&p->rc, &p->isRepG2[p->state], pos - 2);
+ if (pos == 3)
+ p->reps[3] = p->reps[2];
+ p->reps[2] = p->reps[1];
+ }
+ p->reps[1] = p->reps[0];
+ p->reps[0] = distance;
+ }
+ if (len == 1)
+ p->state = kShortRepNextStates[p->state];
+ else
+ {
+ LenEnc_Encode2(&p->repLenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
+ p->state = kRepNextStates[p->state];
+ }
+ }
+ else
+ {
+ UInt32 posSlot;
+ RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0);
+ p->state = kMatchNextStates[p->state];
+ LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
+ pos -= LZMA_NUM_REPS;
+ GetPosSlot(pos, posSlot);
+ RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot);
+
+ if (posSlot >= kStartPosModelIndex)
+ {
+ UInt32 footerBits = ((posSlot >> 1) - 1);
+ UInt32 base = ((2 | (posSlot & 1)) << footerBits);
+ UInt32 posReduced = pos - base;
+
+ if (posSlot < kEndPosModelIndex)
+ RcTree_ReverseEncode(&p->rc, p->posEncoders + base - posSlot - 1, footerBits, posReduced);
+ else
+ {
+ RangeEnc_EncodeDirectBits(&p->rc, posReduced >> kNumAlignBits, footerBits - kNumAlignBits);
+ RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, posReduced & kAlignMask);
+ p->alignPriceCount++;
+ }
+ }
+ p->reps[3] = p->reps[2];
+ p->reps[2] = p->reps[1];
+ p->reps[1] = p->reps[0];
+ p->reps[0] = pos;
+ p->matchPriceCount++;
+ }
+ }
+ p->additionalOffset -= len;
+ nowPos32 += len;
+ if (p->additionalOffset == 0)
+ {
+ UInt32 processed;
+ if (!p->fastMode)
+ {
+ if (p->matchPriceCount >= (1 << 7))
+ FillDistancesPrices(p);
+ if (p->alignPriceCount >= kAlignTableSize)
+ FillAlignPrices(p);
+ }
+ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0)
+ break;
+ processed = nowPos32 - startPos32;
+ if (useLimits)
+ {
+ if (processed + kNumOpts + 300 >= maxUnpackSize ||
+ RangeEnc_GetProcessed(&p->rc) + kNumOpts * 2 >= maxPackSize)
+ break;
+ }
+ else if (processed >= (1 << 15))
+ {
+ p->nowPos64 += nowPos32 - startPos32;
+ return CheckErrors(p);
+ }
+ }
+ }
+ p->nowPos64 += nowPos32 - startPos32;
+ return Flush(p, nowPos32);
+}
+
+#define kBigHashDicLimit ((UInt32)1 << 24)
+
+static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+ UInt32 beforeSize = kNumOpts;
+ if (!RangeEnc_Alloc(&p->rc, alloc))
+ return SZ_ERROR_MEM;
+ #ifdef COMPRESS_MF_MT
+ Bool btMode;
+ btMode = (p->matchFinderBase.btMode != 0);
+ p->mtMode = (p->multiThread && !p->fastMode && btMode);
+ #endif
+
+ {
+ unsigned lclp = p->lc + p->lp;
+ if (p->litProbs == 0 || p->saveState.litProbs == 0 || p->lclp != lclp)
+ {
+ LzmaEnc_FreeLits(p, alloc);
+ p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb));
+ p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb));
+ if (p->litProbs == 0 || p->saveState.litProbs == 0)
+ {
+ LzmaEnc_FreeLits(p, alloc);
+ return SZ_ERROR_MEM;
+ }
+ p->lclp = lclp;
+ }
+ }
+
+ p->matchFinderBase.bigHash = (p->dictSize > kBigHashDicLimit);
+
+ if (beforeSize + p->dictSize < keepWindowSize)
+ beforeSize = keepWindowSize - p->dictSize;
+
+ #ifdef COMPRESS_MF_MT
+ if (p->mtMode)
+ {
+ RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig));
+ p->matchFinderObj = &p->matchFinderMt;
+ MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder);
+ }
+ else
+ #endif
+ {
+ if (!MatchFinder_Create(&p->matchFinderBase, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig))
+ return SZ_ERROR_MEM;
+ p->matchFinderObj = &p->matchFinderBase;
+ MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder);
+ }
+ return SZ_OK;
+}
+
+void LzmaEnc_Init(CLzmaEnc *p)
+{
+ UInt32 i;
+ p->state = 0;
+ for (i = 0 ; i < LZMA_NUM_REPS; i++)
+ p->reps[i] = 0;
+
+ RangeEnc_Init(&p->rc);
+
+
+ for (i = 0; i < kNumStates; i++)
+ {
+ UInt32 j;
+ for (j = 0; j < LZMA_NUM_PB_STATES_MAX; j++)
+ {
+ p->isMatch[i][j] = kProbInitValue;
+ p->isRep0Long[i][j] = kProbInitValue;
+ }
+ p->isRep[i] = kProbInitValue;
+ p->isRepG0[i] = kProbInitValue;
+ p->isRepG1[i] = kProbInitValue;
+ p->isRepG2[i] = kProbInitValue;
+ }
+
+ {
+ UInt32 num = 0x300 << (p->lp + p->lc);
+ for (i = 0; i < num; i++)
+ p->litProbs[i] = kProbInitValue;
+ }
+
+ {
+ for (i = 0; i < kNumLenToPosStates; i++)
+ {
+ CLzmaProb *probs = p->posSlotEncoder[i];
+ UInt32 j;
+ for (j = 0; j < (1 << kNumPosSlotBits); j++)
+ probs[j] = kProbInitValue;
+ }
+ }
+ {
+ for (i = 0; i < kNumFullDistances - kEndPosModelIndex; i++)
+ p->posEncoders[i] = kProbInitValue;
+ }
+
+ LenEnc_Init(&p->lenEnc.p);
+ LenEnc_Init(&p->repLenEnc.p);
+
+ for (i = 0; i < (1 << kNumAlignBits); i++)
+ p->posAlignEncoder[i] = kProbInitValue;
+
+ p->optimumEndIndex = 0;
+ p->optimumCurrentIndex = 0;
+ p->additionalOffset = 0;
+
+ p->pbMask = (1 << p->pb) - 1;
+ p->lpMask = (1 << p->lp) - 1;
+}
+
+void LzmaEnc_InitPrices(CLzmaEnc *p)
+{
+ if (!p->fastMode)
+ {
+ FillDistancesPrices(p);
+ FillAlignPrices(p);
+ }
+
+ p->lenEnc.tableSize =
+ p->repLenEnc.tableSize =
+ p->numFastBytes + 1 - LZMA_MATCH_LEN_MIN;
+ LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, p->ProbPrices);
+ LenPriceEnc_UpdateTables(&p->repLenEnc, 1 << p->pb, p->ProbPrices);
+}
+
+static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+ UInt32 i;
+ for (i = 0; i < (UInt32)kDicLogSizeMaxCompress; i++)
+ if (p->dictSize <= ((UInt32)1 << i))
+ break;
+ p->distTableSize = i * 2;
+
+ p->finished = False;
+ p->result = SZ_OK;
+ RINOK(LzmaEnc_Alloc(p, keepWindowSize, alloc, allocBig));
+ LzmaEnc_Init(p);
+ LzmaEnc_InitPrices(p);
+ p->nowPos64 = 0;
+ return SZ_OK;
+}
+
+static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqInStream *inStream, ISeqOutStream *outStream,
+ ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+ CLzmaEnc *p = (CLzmaEnc *)pp;
+ p->inStream = inStream;
+ p->rc.outStream = outStream;
+ return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig);
+}
+
+SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp,
+ ISeqInStream *inStream, UInt32 keepWindowSize,
+ ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+ CLzmaEnc *p = (CLzmaEnc *)pp;
+ p->inStream = inStream;
+ return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
+}
+
+static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen)
+{
+ p->seqBufInStream.funcTable.Read = MyRead;
+ p->seqBufInStream.data = src;
+ p->seqBufInStream.rem = srcLen;
+}
+
+SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen,
+ UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+ CLzmaEnc *p = (CLzmaEnc *)pp;
+ LzmaEnc_SetInputBuf(p, src, srcLen);
+ p->inStream = &p->seqBufInStream.funcTable;
+ return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
+}
+
+void LzmaEnc_Finish(CLzmaEncHandle pp)
+{
+ #ifdef COMPRESS_MF_MT
+ CLzmaEnc *p = (CLzmaEnc *)pp;
+ if (p->mtMode)
+ MatchFinderMt_ReleaseStream(&p->matchFinderMt);
+ #else
+ pp = pp;
+ #endif
+}
+
+typedef struct _CSeqOutStreamBuf
+{
+ ISeqOutStream funcTable;
+ Byte *data;
+ SizeT rem;
+ Bool overflow;
+} CSeqOutStreamBuf;
+
+static size_t MyWrite(void *pp, const void *data, size_t size)
+{
+ CSeqOutStreamBuf *p = (CSeqOutStreamBuf *)pp;
+ if (p->rem < size)
+ {
+ size = p->rem;
+ p->overflow = True;
+ }
+ memcpy(p->data, data, size);
+ p->rem -= size;
+ p->data += size;
+ return size;
+}
+
+
+UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp)
+{
+ const CLzmaEnc *p = (CLzmaEnc *)pp;
+ return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
+}
+
+const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp)
+{
+ const CLzmaEnc *p = (CLzmaEnc *)pp;
+ return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
+}
+
+SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
+ Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize)
+{
+ CLzmaEnc *p = (CLzmaEnc *)pp;
+ UInt64 nowPos64;
+ SRes res;
+ CSeqOutStreamBuf outStream;
+
+ outStream.funcTable.Write = MyWrite;
+ outStream.data = dest;
+ outStream.rem = *destLen;
+ outStream.overflow = False;
+
+ p->writeEndMark = False;
+ p->finished = False;
+ p->result = SZ_OK;
+
+ if (reInit)
+ LzmaEnc_Init(p);
+ LzmaEnc_InitPrices(p);
+ nowPos64 = p->nowPos64;
+ RangeEnc_Init(&p->rc);
+ p->rc.outStream = &outStream.funcTable;
+
+ res = LzmaEnc_CodeOneBlock(p, True, desiredPackSize, *unpackSize);
+
+ *unpackSize = (UInt32)(p->nowPos64 - nowPos64);
+ *destLen -= outStream.rem;
+ if (outStream.overflow)
+ return SZ_ERROR_OUTPUT_EOF;
+
+ return res;
+}
+
+SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress,
+ ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+ CLzmaEnc *p = (CLzmaEnc *)pp;
+ SRes res = SZ_OK;
+
+ #ifdef COMPRESS_MF_MT
+ Byte allocaDummy[0x300];
+ int i = 0;
+ for (i = 0; i < 16; i++)
+ allocaDummy[i] = (Byte)i;
+ #endif
+
+ RINOK(LzmaEnc_Prepare(pp, inStream, outStream, alloc, allocBig));
+
+ for (;;)
+ {
+ res = LzmaEnc_CodeOneBlock(p, False, 0, 0);
+ if (res != SZ_OK || p->finished != 0)
+ break;
+ if (progress != 0)
+ {
+ res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc));
+ if (res != SZ_OK)
+ {
+ res = SZ_ERROR_PROGRESS;
+ break;
+ }
+ }
+ }
+ LzmaEnc_Finish(pp);
+ return res;
+}
+
+SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size)
+{
+ CLzmaEnc *p = (CLzmaEnc *)pp;
+ int i;
+ UInt32 dictSize = p->dictSize;
+ if (*size < LZMA_PROPS_SIZE)
+ return SZ_ERROR_PARAM;
+ *size = LZMA_PROPS_SIZE;
+ props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc);
+
+ for (i = 11; i <= 30; i++)
+ {
+ if (dictSize <= ((UInt32)2 << i))
+ {
+ dictSize = (2 << i);
+ break;
+ }
+ if (dictSize <= ((UInt32)3 << i))
+ {
+ dictSize = (3 << i);
+ break;
+ }
+ }
+
+ for (i = 0; i < 4; i++)
+ props[1 + i] = (Byte)(dictSize >> (8 * i));
+ return SZ_OK;
+}
+
+SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
+ int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+ SRes res;
+ CLzmaEnc *p = (CLzmaEnc *)pp;
+
+ CSeqOutStreamBuf outStream;
+
+ LzmaEnc_SetInputBuf(p, src, srcLen);
+
+ outStream.funcTable.Write = MyWrite;
+ outStream.data = dest;
+ outStream.rem = *destLen;
+ outStream.overflow = False;
+
+ p->writeEndMark = writeEndMark;
+ res = LzmaEnc_Encode(pp, &outStream.funcTable, &p->seqBufInStream.funcTable,
+ progress, alloc, allocBig);
+
+ *destLen -= outStream.rem;
+ if (outStream.overflow)
+ return SZ_ERROR_OUTPUT_EOF;
+ return res;
+}
+
+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)
+{
+ CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc);
+ SRes res;
+ if (p == 0)
+ return SZ_ERROR_MEM;
+
+ res = LzmaEnc_SetProps(p, props);
+ if (res == SZ_OK)
+ {
+ res = LzmaEnc_WriteProperties(p, propsEncoded, propsSize);
+ if (res == SZ_OK)
+ res = LzmaEnc_MemEncode(p, dest, destLen, src, srcLen,
+ writeEndMark, progress, alloc, allocBig);
+ }
+
+ LzmaEnc_Destroy(p, alloc, allocBig);
+ return res;
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/LzmaEnc.h squashfs-tools-patched/LZMA/lzma465/C/LzmaEnc.h
--- squashfs-tools/LZMA/lzma465/C/LzmaEnc.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/LzmaEnc.h 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,72 @@
+/* LzmaEnc.h -- LZMA Encoder
+2008-10-04 : Igor Pavlov : Public domain */
+
+#ifndef __LZMAENC_H
+#define __LZMAENC_H
+
+#include "Types.h"
+
+#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);
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/LzmaLib/LzmaLib.def squashfs-tools-patched/LZMA/lzma465/C/LzmaLib/LzmaLib.def
--- squashfs-tools/LZMA/lzma465/C/LzmaLib/LzmaLib.def 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/LzmaLib/LzmaLib.def 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,4 @@
+EXPORTS
+ LzmaCompress
+ LzmaUncompress
+
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/LzmaLib/LzmaLib.dsp squashfs-tools-patched/LZMA/lzma465/C/LzmaLib/LzmaLib.dsp
--- squashfs-tools/LZMA/lzma465/C/LzmaLib/LzmaLib.dsp 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/LzmaLib/LzmaLib.dsp 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,178 @@
+# Microsoft Developer Studio Project File - Name="LzmaLib" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=LzmaLib - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "LzmaLib.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "LzmaLib.mak" CFG="LzmaLib - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "LzmaLib - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "LzmaLib - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "LzmaLib - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LZMALIB_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /Gr /MT /W3 /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LZMALIB_EXPORTS" /D "COMPRESS_MF_MT" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Util\LZMA.dll" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "LzmaLib - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LZMALIB_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LZMALIB_EXPORTS" /D "COMPRESS_MF_MT" /FD /GZ /c
+# SUBTRACT CPP /YX
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x419 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Util\LZMA.dll" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "LzmaLib - Win32 Release"
+# Name "LzmaLib - Win32 Debug"
+# Begin Group "Spec"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\LzmaLib.def
+# End Source File
+# Begin Source File
+
+SOURCE=.\LzmaLibExports.c
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\Alloc.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\Alloc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\IStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LzFind.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\LzFind.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LzFindMt.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\LzFindMt.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LzHash.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LzmaDec.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\LzmaDec.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LzmaEnc.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\LzmaEnc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LzmaLib.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\LzmaLib.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource.rc
+# End Source File
+# Begin Source File
+
+SOURCE=..\Threads.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\Threads.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Types.h
+# End Source File
+# End Target
+# End Project
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/LzmaLib/LzmaLib.dsw squashfs-tools-patched/LZMA/lzma465/C/LzmaLib/LzmaLib.dsw
--- squashfs-tools/LZMA/lzma465/C/LzmaLib/LzmaLib.dsw 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/LzmaLib/LzmaLib.dsw 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "LzmaLib"=.\LzmaLib.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/LzmaLib/LzmaLibExports.c squashfs-tools-patched/LZMA/lzma465/C/LzmaLib/LzmaLibExports.c
--- squashfs-tools/LZMA/lzma465/C/LzmaLib/LzmaLibExports.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/LzmaLib/LzmaLibExports.c 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,12 @@
+/* LzmaLibExports.c -- LZMA library DLL Entry point
+2008-10-04 : Igor Pavlov : Public domain */
+
+#include <windows.h>
+
+BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
+{
+ hInstance = hInstance;
+ dwReason = dwReason;
+ lpReserved = lpReserved;
+ return TRUE;
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/LzmaLib/makefile squashfs-tools-patched/LZMA/lzma465/C/LzmaLib/makefile
--- squashfs-tools/LZMA/lzma465/C/LzmaLib/makefile 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/LzmaLib/makefile 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,37 @@
+MY_STATIC_LINK=1
+SLIB = sLZMA.lib
+PROG = LZMA.dll
+SLIBPATH = $O\$(SLIB)
+
+DEF_FILE = LzmaLib.def
+CFLAGS = $(CFLAGS) \
+ -DCOMPRESS_MF_MT \
+
+LIBS = $(LIBS) oleaut32.lib
+
+LIB_OBJS = \
+ $O\LzmaLibExports.obj \
+
+C_OBJS = \
+ $O\Alloc.obj \
+ $O\LzFind.obj \
+ $O\LzFindMt.obj \
+ $O\LzmaDec.obj \
+ $O\LzmaEnc.obj \
+ $O\LzmaLib.obj \
+ $O\Threads.obj \
+
+OBJS = \
+ $(LIB_OBJS) \
+ $(C_OBJS) \
+ $O\resource.res
+
+!include "../../CPP/Build.mak"
+
+$(SLIBPATH): $O $(OBJS)
+ lib -out:$(SLIBPATH) $(OBJS) $(LIBS)
+
+$(LIB_OBJS): $(*B).c
+ $(COMPL_O2)
+$(C_OBJS): ../$(*B).c
+ $(COMPL_O2)
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/LzmaLib/resource.rc squashfs-tools-patched/LZMA/lzma465/C/LzmaLib/resource.rc
--- squashfs-tools/LZMA/lzma465/C/LzmaLib/resource.rc 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/LzmaLib/resource.rc 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,4 @@
+#include "../../CPP/7zip/MyVersionInfo.rc"
+
+MY_VERSION_INFO_DLL("LZMA library", "LZMA")
+
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/LzmaLib.c squashfs-tools-patched/LZMA/lzma465/C/LzmaLib.c
--- squashfs-tools/LZMA/lzma465/C/LzmaLib.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/LzmaLib.c 2016-08-25 09:06:03.231530353 -0400
@@ -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);
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/LzmaLib.h squashfs-tools-patched/LZMA/lzma465/C/LzmaLib.h
--- squashfs-tools/LZMA/lzma465/C/LzmaLib.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/LzmaLib.h 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,135 @@
+/* LzmaLib.h -- LZMA library interface
+2008-08-05
+Igor Pavlov
+Public domain */
+
+#ifndef __LZMALIB_H
+#define __LZMALIB_H
+
+#include "Types.h"
+
+#ifdef __cplusplus
+ #define MY_EXTERN_C extern "C"
+#else
+ #define MY_EXTERN_C extern
+#endif
+
+#define MY_STDAPI MY_EXTERN_C 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);
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/LzmaUtil/Lzma86Dec.c squashfs-tools-patched/LZMA/lzma465/C/LzmaUtil/Lzma86Dec.c
--- squashfs-tools/LZMA/lzma465/C/LzmaUtil/Lzma86Dec.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/LzmaUtil/Lzma86Dec.c 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,61 @@
+/* Lzma86Dec.c -- LZMA + x86 (BCJ) Filter Decoder
+2008-04-07
+Igor Pavlov
+Public domain */
+
+#include "Lzma86Dec.h"
+
+#include "../Alloc.h"
+#include "../Bra.h"
+#include "../LzmaDec.h"
+
+#define LZMA86_SIZE_OFFSET (1 + LZMA_PROPS_SIZE)
+#define LZMA86_HEADER_SIZE (LZMA86_SIZE_OFFSET + 8)
+
+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 };
+
+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)
+{
+ 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;
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/LzmaUtil/Lzma86Dec.h squashfs-tools-patched/LZMA/lzma465/C/LzmaUtil/Lzma86Dec.h
--- squashfs-tools/LZMA/lzma465/C/LzmaUtil/Lzma86Dec.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/LzmaUtil/Lzma86Dec.h 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,45 @@
+/* Lzma86Dec.h -- LZMA + x86 (BCJ) Filter Decoder
+2008-08-05
+Igor Pavlov
+Public domain */
+
+#ifndef __LZMA86DEC_H
+#define __LZMA86DEC_H
+
+#include "../Types.h"
+
+/*
+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);
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/LzmaUtil/Lzma86Enc.c squashfs-tools-patched/LZMA/lzma465/C/LzmaUtil/Lzma86Enc.c
--- squashfs-tools/LZMA/lzma465/C/LzmaUtil/Lzma86Enc.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/LzmaUtil/Lzma86Enc.c 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,113 @@
+/* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder
+2008-08-05
+Igor Pavlov
+Public domain */
+
+#include <string.h>
+
+#include "Lzma86Enc.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); }
+static ISzAlloc g_Alloc = { SzAlloc, SzFree };
+
+#define LZMA86_SIZE_OFFSET (1 + LZMA_PROPS_SIZE)
+#define LZMA86_HEADER_SIZE (LZMA86_SIZE_OFFSET + 8)
+
+int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen,
+ int level, UInt32 dictSize, int filterMode)
+{
+ 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;
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/LzmaUtil/Lzma86Enc.h squashfs-tools-patched/LZMA/lzma465/C/LzmaUtil/Lzma86Enc.h
--- squashfs-tools/LZMA/lzma465/C/LzmaUtil/Lzma86Enc.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/LzmaUtil/Lzma86Enc.h 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,72 @@
+/* Lzma86Enc.h -- LZMA + x86 (BCJ) Filter Encoder
+2008-08-05
+Igor Pavlov
+Public domain */
+
+#ifndef __LZMA86ENC_H
+#define __LZMA86ENC_H
+
+#include "../Types.h"
+
+/*
+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,
+ = 1 - x86 filter
+ 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);
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/LzmaUtil/LzmaUtil.c squashfs-tools-patched/LZMA/lzma465/C/LzmaUtil/LzmaUtil.c
--- squashfs-tools/LZMA/lzma465/C/LzmaUtil/LzmaUtil.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/LzmaUtil/LzmaUtil.c 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,254 @@
+/* LzmaUtil.c -- Test application for LZMA compression
+2008-11-23 : Igor Pavlov : Public domain */
+
+#define _CRT_SECURE_NO_WARNINGS
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../Alloc.h"
+#include "../7zFile.h"
+#include "../7zVersion.h"
+#include "../LzmaDec.h"
+#include "../LzmaEnc.h"
+
+const char *kCantReadMessage = "Can not read input file";
+const char *kCantWriteMessage = "Can not write output file";
+const char *kCantAllocateMessage = "Can not allocate memory";
+const char *kDataErrorMessage = "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); }
+static ISzAlloc g_Alloc = { SzAlloc, SzFree };
+
+void PrintHelp(char *buffer)
+{
+ strcat(buffer, "\nLZMA Utility " MY_VERSION_COPYRIGHT_DATE "\n"
+ "\nUsage: lzma <e|d> inputFile outputFile\n"
+ " e: encode file\n"
+ " d: decode file\n");
+}
+
+int PrintError(char *buffer, const char *message)
+{
+ strcat(buffer, "\nError: ");
+ strcat(buffer, message);
+ strcat(buffer, "\n");
+ return 1;
+}
+
+int PrintErrorNumber(char *buffer, SRes val)
+{
+ sprintf(buffer + strlen(buffer), "\nError code: %x\n", (unsigned)val);
+ return 1;
+}
+
+int PrintUserError(char *buffer)
+{
+ return PrintError(buffer, "Incorrect command");
+}
+
+#define IN_BUF_SIZE (1 << 16)
+#define OUT_BUF_SIZE (1 << 16)
+
+static SRes Decode2(CLzmaDec *state, ISeqOutStream *outStream, ISeqInStream *inStream,
+ UInt64 unpackSize)
+{
+ int thereIsSize = (unpackSize != (UInt64)(Int64)-1);
+ Byte inBuf[IN_BUF_SIZE];
+ Byte outBuf[OUT_BUF_SIZE];
+ size_t inPos = 0, inSize = 0, outPos = 0;
+ LzmaDec_Init(state);
+ for (;;)
+ {
+ if (inPos == inSize)
+ {
+ inSize = IN_BUF_SIZE;
+ RINOK(inStream->Read(inStream, inBuf, &inSize));
+ inPos = 0;
+ }
+ {
+ SRes res;
+ SizeT inProcessed = inSize - inPos;
+ SizeT outProcessed = OUT_BUF_SIZE - outPos;
+ ELzmaFinishMode finishMode = LZMA_FINISH_ANY;
+ ELzmaStatus status;
+ if (thereIsSize && outProcessed > unpackSize)
+ {
+ outProcessed = (SizeT)unpackSize;
+ finishMode = LZMA_FINISH_END;
+ }
+
+ res = LzmaDec_DecodeToBuf(state, outBuf + outPos, &outProcessed,
+ inBuf + inPos, &inProcessed, finishMode, &status);
+ inPos += inProcessed;
+ outPos += outProcessed;
+ unpackSize -= outProcessed;
+
+ if (outStream)
+ if (outStream->Write(outStream, outBuf, outPos) != outPos)
+ return SZ_ERROR_WRITE;
+
+ outPos = 0;
+
+ if (res != SZ_OK || thereIsSize && unpackSize == 0)
+ return res;
+
+ if (inProcessed == 0 && outProcessed == 0)
+ {
+ if (thereIsSize || status != LZMA_STATUS_FINISHED_WITH_MARK)
+ return SZ_ERROR_DATA;
+ return res;
+ }
+ }
+ }
+}
+
+static SRes Decode(ISeqOutStream *outStream, ISeqInStream *inStream)
+{
+ UInt64 unpackSize;
+ int i;
+ SRes res = 0;
+
+ CLzmaDec state;
+
+ /* header: 5 bytes of LZMA properties and 8 bytes of uncompressed size */
+ unsigned char header[LZMA_PROPS_SIZE + 8];
+
+ /* Read and parse header */
+
+ RINOK(SeqInStream_Read(inStream, header, sizeof(header)));
+
+ unpackSize = 0;
+ for (i = 0; i < 8; i++)
+ unpackSize += (UInt64)header[LZMA_PROPS_SIZE + i] << (i * 8);
+
+ LzmaDec_Construct(&state);
+ RINOK(LzmaDec_Allocate(&state, header, LZMA_PROPS_SIZE, &g_Alloc));
+ res = Decode2(&state, outStream, inStream, unpackSize);
+ LzmaDec_Free(&state, &g_Alloc);
+ return res;
+}
+
+static SRes Encode(ISeqOutStream *outStream, ISeqInStream *inStream, UInt64 fileSize, char *rs)
+{
+ CLzmaEncHandle enc;
+ SRes res;
+ CLzmaEncProps props;
+
+ rs = rs;
+
+ enc = LzmaEnc_Create(&g_Alloc);
+ if (enc == 0)
+ return SZ_ERROR_MEM;
+
+ LzmaEncProps_Init(&props);
+ res = LzmaEnc_SetProps(enc, &props);
+
+ if (res == SZ_OK)
+ {
+ Byte header[LZMA_PROPS_SIZE + 8];
+ size_t headerSize = LZMA_PROPS_SIZE;
+ int i;
+
+ res = LzmaEnc_WriteProperties(enc, header, &headerSize);
+ for (i = 0; i < 8; i++)
+ header[headerSize++] = (Byte)(fileSize >> (8 * i));
+ if (outStream->Write(outStream, header, headerSize) != headerSize)
+ res = SZ_ERROR_WRITE;
+ else
+ {
+ if (res == SZ_OK)
+ res = LzmaEnc_Encode(enc, outStream, inStream, NULL, &g_Alloc, &g_Alloc);
+ }
+ }
+ LzmaEnc_Destroy(enc, &g_Alloc, &g_Alloc);
+ return res;
+}
+
+int main2(int numArgs, const char *args[], char *rs)
+{
+ CFileSeqInStream inStream;
+ CFileOutStream outStream;
+ char c;
+ int res;
+ int encodeMode;
+ Bool useOutFile = False;
+
+ FileSeqInStream_CreateVTable(&inStream);
+ File_Construct(&inStream.file);
+
+ FileOutStream_CreateVTable(&outStream);
+ File_Construct(&outStream.file);
+
+ if (numArgs == 1)
+ {
+ PrintHelp(rs);
+ return 0;
+ }
+
+ if (numArgs < 3 || numArgs > 4 || strlen(args[1]) != 1)
+ return PrintUserError(rs);
+
+ c = args[1][0];
+ encodeMode = (c == 'e' || c == 'E');
+ if (!encodeMode && c != 'd' && c != 'D')
+ return PrintUserError(rs);
+
+ {
+ size_t t4 = sizeof(UInt32);
+ size_t t8 = sizeof(UInt64);
+ if (t4 != 4 || t8 != 8)
+ return PrintError(rs, "Incorrect UInt32 or UInt64");
+ }
+
+ if (InFile_Open(&inStream.file, args[2]) != 0)
+ return PrintError(rs, "Can not open input file");
+
+ if (numArgs > 3)
+ {
+ useOutFile = True;
+ if (OutFile_Open(&outStream.file, args[3]) != 0)
+ return PrintError(rs, "Can not open output file");
+ }
+ else if (encodeMode)
+ PrintUserError(rs);
+
+ if (encodeMode)
+ {
+ UInt64 fileSize;
+ File_GetLength(&inStream.file, &fileSize);
+ res = Encode(&outStream.s, &inStream.s, fileSize, rs);
+ }
+ else
+ {
+ res = Decode(&outStream.s, useOutFile ? &inStream.s : NULL);
+ }
+
+ if (useOutFile)
+ File_Close(&outStream.file);
+ File_Close(&inStream.file);
+
+ if (res != SZ_OK)
+ {
+ if (res == SZ_ERROR_MEM)
+ return PrintError(rs, kCantAllocateMessage);
+ else if (res == SZ_ERROR_DATA)
+ return PrintError(rs, kDataErrorMessage);
+ else if (res == SZ_ERROR_WRITE)
+ return PrintError(rs, kCantWriteMessage);
+ else if (res == SZ_ERROR_READ)
+ return PrintError(rs, kCantReadMessage);
+ return PrintErrorNumber(rs, res);
+ }
+ return 0;
+}
+
+int MY_CDECL main(int numArgs, const char *args[])
+{
+ char rs[800] = { 0 };
+ int res = main2(numArgs, args, rs);
+ printf(rs);
+ return res;
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/LzmaUtil/LzmaUtil.dsp squashfs-tools-patched/LZMA/lzma465/C/LzmaUtil/LzmaUtil.dsp
--- squashfs-tools/LZMA/lzma465/C/LzmaUtil/LzmaUtil.dsp 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/LzmaUtil/LzmaUtil.dsp 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,168 @@
+# Microsoft Developer Studio Project File - Name="LzmaUtil" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=LzmaUtil - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "LzmaUtil.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "LzmaUtil.mak" CFG="LzmaUtil - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "LzmaUtil - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "LzmaUtil - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "LzmaUtil - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\util\lzmac.exe"
+
+!ELSEIF "$(CFG)" == "LzmaUtil - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /GZ /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x419 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\util\lzmac.exe" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "LzmaUtil - Win32 Release"
+# Name "LzmaUtil - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\7zFile.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\7zFile.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\7zStream.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\7zVersion.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Alloc.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\Alloc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\CpuArch.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LzFind.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\LzFind.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LzFindMt.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\LzFindMt.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LzHash.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LzmaDec.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\LzmaDec.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LzmaEnc.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\LzmaEnc.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\LzmaUtil.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\Threads.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\Threads.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Types.h
+# End Source File
+# End Target
+# End Project
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/LzmaUtil/LzmaUtil.dsw squashfs-tools-patched/LZMA/lzma465/C/LzmaUtil/LzmaUtil.dsw
--- squashfs-tools/LZMA/lzma465/C/LzmaUtil/LzmaUtil.dsw 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/LzmaUtil/LzmaUtil.dsw 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "LzmaUtil"=.\LzmaUtil.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/LzmaUtil/makefile squashfs-tools-patched/LZMA/lzma465/C/LzmaUtil/makefile
--- squashfs-tools/LZMA/lzma465/C/LzmaUtil/makefile 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/LzmaUtil/makefile 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,29 @@
+MY_STATIC_LINK=1
+PROG = LZMAc.exe
+
+CFLAGS = $(CFLAGS) \
+ -DCOMPRESS_MF_MT \
+
+LIB_OBJS = \
+ $O\LzmaUtil.obj \
+
+C_OBJS = \
+ $O\Alloc.obj \
+ $O\LzFind.obj \
+ $O\LzFindMt.obj \
+ $O\LzmaDec.obj \
+ $O\LzmaEnc.obj \
+ $O\7zFile.obj \
+ $O\7zStream.obj \
+ $O\Threads.obj \
+
+OBJS = \
+ $(LIB_OBJS) \
+ $(C_OBJS) \
+
+!include "../../CPP/Build.mak"
+
+$(LIB_OBJS): $(*B).c
+ $(COMPL_O2)
+$(C_OBJS): ../$(*B).c
+ $(COMPL_O2)
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/LzmaUtil/makefile.gcc squashfs-tools-patched/LZMA/lzma465/C/LzmaUtil/makefile.gcc
--- squashfs-tools/LZMA/lzma465/C/LzmaUtil/makefile.gcc 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/LzmaUtil/makefile.gcc 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,44 @@
+PROG = lzma
+CXX = g++
+LIB =
+RM = rm -f
+CFLAGS = -c -O2 -Wall
+
+OBJS = \
+ LzmaUtil.o \
+ Alloc.o \
+ LzFind.o \
+ LzmaDec.o \
+ LzmaEnc.o \
+ 7zFile.o \
+ 7zStream.o \
+
+
+all: $(PROG)
+
+$(PROG): $(OBJS)
+ $(CXX) -o $(PROG) $(LDFLAGS) $(OBJS) $(LIB) $(LIB2)
+
+LzmaUtil.o: LzmaUtil.c
+ $(CXX) $(CFLAGS) LzmaUtil.c
+
+Alloc.o: ../Alloc.c
+ $(CXX) $(CFLAGS) ../Alloc.c
+
+LzFind.o: ../LzFind.c
+ $(CXX) $(CFLAGS) ../LzFind.c
+
+LzmaDec.o: ../LzmaDec.c
+ $(CXX) $(CFLAGS) ../LzmaDec.c
+
+LzmaEnc.o: ../LzmaEnc.c
+ $(CXX) $(CFLAGS) ../LzmaEnc.c
+
+7zFile.o: ../7zFile.c
+ $(CXX) $(CFLAGS) ../7zFile.c
+
+7zStream.o: ../7zStream.c
+ $(CXX) $(CFLAGS) ../7zStream.c
+
+clean:
+ -$(RM) $(PROG) $(OBJS)
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/Threads.c squashfs-tools-patched/LZMA/lzma465/C/Threads.c
--- squashfs-tools/LZMA/lzma465/C/Threads.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/Threads.c 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,109 @@
+/* Threads.c -- multithreading library
+2008-08-05
+Igor Pavlov
+Public domain */
+
+#include "Threads.h"
+#include <process.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(); }
+
+static WRes MyCloseHandle(HANDLE *h)
+{
+ if (*h != NULL)
+ if (!CloseHandle(*h))
+ return GetError();
+ *h = NULL;
+ return 0;
+}
+
+WRes Thread_Create(CThread *thread, THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), LPVOID parameter)
+{
+ unsigned threadId; /* Windows Me/98/95: threadId parameter may not be NULL in _beginthreadex/CreateThread functions */
+ thread->handle =
+ /* CreateThread(0, 0, startAddress, parameter, 0, &threadId); */
+ (HANDLE)_beginthreadex(NULL, 0, startAddress, parameter, 0, &threadId);
+ /* maybe we must use errno here, but probably GetLastError() is also OK. */
+ return HandleToWRes(thread->handle);
+}
+
+WRes WaitObject(HANDLE h)
+{
+ return (WRes)WaitForSingleObject(h, INFINITE);
+}
+
+WRes Thread_Wait(CThread *thread)
+{
+ if (thread->handle == NULL)
+ return 1;
+ return WaitObject(thread->handle);
+}
+
+WRes Thread_Close(CThread *thread)
+{
+ return MyCloseHandle(&thread->handle);
+}
+
+WRes Event_Create(CEvent *p, BOOL manualReset, int initialSignaled)
+{
+ p->handle = CreateEvent(NULL, manualReset, (initialSignaled ? TRUE : FALSE), NULL);
+ return HandleToWRes(p->handle);
+}
+
+WRes ManualResetEvent_Create(CManualResetEvent *p, int initialSignaled)
+ { return Event_Create(p, TRUE, initialSignaled); }
+WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p)
+ { return ManualResetEvent_Create(p, 0); }
+
+WRes AutoResetEvent_Create(CAutoResetEvent *p, int initialSignaled)
+ { return Event_Create(p, FALSE, initialSignaled); }
+WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p)
+ { return AutoResetEvent_Create(p, 0); }
+
+WRes Event_Set(CEvent *p) { return BOOLToWRes(SetEvent(p->handle)); }
+WRes Event_Reset(CEvent *p) { return BOOLToWRes(ResetEvent(p->handle)); }
+WRes Event_Wait(CEvent *p) { return WaitObject(p->handle); }
+WRes Event_Close(CEvent *p) { return MyCloseHandle(&p->handle); }
+
+
+WRes Semaphore_Create(CSemaphore *p, UInt32 initiallyCount, UInt32 maxCount)
+{
+ p->handle = CreateSemaphore(NULL, (LONG)initiallyCount, (LONG)maxCount, NULL);
+ return HandleToWRes(p->handle);
+}
+
+WRes Semaphore_Release(CSemaphore *p, LONG releaseCount, LONG *previousCount)
+{
+ return BOOLToWRes(ReleaseSemaphore(p->handle, releaseCount, previousCount));
+}
+WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 releaseCount)
+{
+ return Semaphore_Release(p, (LONG)releaseCount, NULL);
+}
+WRes Semaphore_Release1(CSemaphore *p)
+{
+ return Semaphore_ReleaseN(p, 1);
+}
+
+WRes Semaphore_Wait(CSemaphore *p) { return WaitObject(p->handle); }
+WRes Semaphore_Close(CSemaphore *p) { return MyCloseHandle(&p->handle); }
+
+WRes CriticalSection_Init(CCriticalSection *p)
+{
+ /* InitializeCriticalSection can raise only STATUS_NO_MEMORY exception */
+ __try
+ {
+ InitializeCriticalSection(p);
+ /* InitializeCriticalSectionAndSpinCount(p, 0); */
+ }
+ __except (EXCEPTION_EXECUTE_HANDLER) { return 1; }
+ return 0;
+}
+
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/Threads.h squashfs-tools-patched/LZMA/lzma465/C/Threads.h
--- squashfs-tools/LZMA/lzma465/C/Threads.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/Threads.h 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,68 @@
+/* Threads.h -- multithreading library
+2008-11-22 : Igor Pavlov : Public domain */
+
+#ifndef __7Z_THRESDS_H
+#define __7Z_THRESDS_H
+
+#include "Types.h"
+
+typedef struct _CThread
+{
+ HANDLE handle;
+} CThread;
+
+#define Thread_Construct(thread) (thread)->handle = NULL
+#define Thread_WasCreated(thread) ((thread)->handle != NULL)
+
+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
+
+WRes Thread_Create(CThread *thread, THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), LPVOID parameter);
+WRes Thread_Wait(CThread *thread);
+WRes Thread_Close(CThread *thread);
+
+typedef struct _CEvent
+{
+ HANDLE handle;
+} CEvent;
+
+typedef CEvent CAutoResetEvent;
+typedef CEvent CManualResetEvent;
+
+#define Event_Construct(event) (event)->handle = NULL
+#define Event_IsCreated(event) ((event)->handle != NULL)
+
+WRes ManualResetEvent_Create(CManualResetEvent *event, int initialSignaled);
+WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *event);
+WRes AutoResetEvent_Create(CAutoResetEvent *event, int initialSignaled);
+WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *event);
+WRes Event_Set(CEvent *event);
+WRes Event_Reset(CEvent *event);
+WRes Event_Wait(CEvent *event);
+WRes Event_Close(CEvent *event);
+
+
+typedef struct _CSemaphore
+{
+ HANDLE handle;
+} CSemaphore;
+
+#define Semaphore_Construct(p) (p)->handle = NULL
+
+WRes Semaphore_Create(CSemaphore *p, UInt32 initiallyCount, UInt32 maxCount);
+WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num);
+WRes Semaphore_Release1(CSemaphore *p);
+WRes Semaphore_Wait(CSemaphore *p);
+WRes Semaphore_Close(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)
+
+#endif
+
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/C/Types.h squashfs-tools-patched/LZMA/lzma465/C/Types.h
--- squashfs-tools/LZMA/lzma465/C/Types.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/C/Types.h 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,208 @@
+/* Types.h -- Basic types
+2008-11-23 : Igor Pavlov : Public domain */
+
+#ifndef __7Z_TYPES_H
+#define __7Z_TYPES_H
+
+#include <stddef.h>
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+#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 _MSC_VER
+
+#if _MSC_VER >= 1300
+#define MY_NO_INLINE __declspec(noinline)
+#else
+#define MY_NO_INLINE
+#endif
+
+#define MY_CDECL __cdecl
+#define MY_STD_CALL __stdcall
+#define MY_FAST_CALL MY_NO_INLINE __fastcall
+
+#else
+
+#define MY_CDECL
+#define MY_STD_CALL
+#define MY_FAST_CALL
+
+#endif
+
+
+/* The following interfaces use first parameter as pointer to structure */
+
+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, 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;
+
+void LookToRead_CreateVTable(CLookToRead *p, int lookahead);
+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)
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/history.txt squashfs-tools-patched/LZMA/lzma465/history.txt
--- squashfs-tools/LZMA/lzma465/history.txt 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/history.txt 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,236 @@
+HISTORY of the LZMA SDK
+-----------------------
+
+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
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/lzma.txt squashfs-tools-patched/LZMA/lzma465/lzma.txt
--- squashfs-tools/LZMA/lzma465/lzma.txt 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/lzma.txt 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,594 @@
+LZMA SDK 4.65
+-------------
+
+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.
+
+
+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
+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
+
+ Copy - Copy coder
+ RangeCoder - Range Coder (special code of compression/decompression)
+ LZMA - LZMA compression/decompression on C++
+ LZMA_Alone - file->file LZMA compression/decompression
+ Branch - Filters for x86, IA-64, ARM, ARM-Thumb, PowerPC and SPARC code
+
+ 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.
+
+
+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)
+
+
+
+LZMA 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.
+
+
+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
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzma465/Methods.txt squashfs-tools-patched/LZMA/lzma465/Methods.txt
--- squashfs-tools/LZMA/lzma465/Methods.txt 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzma465/Methods.txt 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,137 @@
+7-Zip method IDs (4.65)
+-----------------------
+
+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
+
+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
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/7zC.txt squashfs-tools-patched/LZMA/lzmadaptive/7zC.txt
--- squashfs-tools/LZMA/lzmadaptive/7zC.txt 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/7zC.txt 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,235 @@
+7z ANSI-C Decoder 4.23
+----------------------
+
+7z ANSI-C Decoder 4.23 Copyright (C) 1999-2005 Igor Pavlov
+
+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
+-------
+
+Read lzma.txt for information about license.
+
+
+Files
+---------------------
+
+7zAlloc.* - Allocate and Free
+7zBuffer.* - Buffer structure
+7zCrc.* - CRC32 code
+7zDecode.* - Low level memory->memory decoding
+7zExtract.* - High level stream->memory decoding
+7zHeader.* - .7z format constants
+7zIn.* - .7z archive opening
+7zItem.* - .7z structures
+7zMain.c - Test application
+7zMethodID.* - MethodID structure
+7zTypes.h - Base types and constants
+
+
+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", and "CRC" information for each file in archive.
+ - It supports only LZMA and Copy (no compression) methods.
+ - 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
+----------------------
+
+.7z Decoder can be compiled in one of two modes:
+
+1) Default mode. In that mode 7z Decoder will read full compressed
+ block to RAM before decompressing.
+
+2) Mode with defined _LZMA_IN_CB. In that mode 7z Decoder can read
+ compressed block by parts. And you can specify desired buffer size.
+ So memory requirements can be reduced. But decompressing speed will
+ be 5-10% lower and code size is slightly larger.
+
+
+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 ISzInStream interface */
+ CArchiveDatabaseEx db; /* 7z archive database structure */
+ ISzAlloc allocImp; /* memory functions for main pool */
+ ISzAlloc allocTempImp; /* memory functions for temporary pool */
+
+2) call InitCrcTable(); function to initialize CRC structures.
+
+3) call SzArDbExInit(&db); function to initialize db structures.
+
+4) call SzArchiveOpen(inStream, &db, &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.
+SzArchiveOpen function allocates and frees temporary structures by "allocTemp" functions.
+
+5) List items or Extract items
+
+ Listing code:
+ ~~~~~~~~~~~~~
+ {
+ UInt32 i;
+ for (i = 0; i < db.Database.NumFiles; i++)
+ {
+ CFileItem *f = db.Database.Files + i;
+ printf("%10d %s\n", (int)f->Size, f->Name);
+ }
+ }
+
+ Extracting code:
+ ~~~~~~~~~~~~~~~~
+
+ SZ_RESULT SzExtract(
+ ISzInStream *inStream,
+ CArchiveDatabaseEx *db,
+ 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 SzArDbExFree(&db, allocImp.Free) to free allocated items in "db".
+
+
+
+
+Memory requirements for .7z decoding
+------------------------------------
+
+Memory usage for Archive opening:
+ - Temporary pool:
+ - Memory for compressed .7z headers (if _LZMA_IN_CB is not defined)
+ - 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)
+ - Some file information (4 bytes)
+ - File Name (variable length) + pointer + allocation structures
+
+Memory usage for archive Decompressing:
+ - Temporary pool:
+ - Memory for compressed solid block (if _LZMA_IN_CB is not defined)
+ - Memory for LZMA decompressing structures
+ - Main pool:
+ - Memory for decompressed solid block
+
+
+If _LZMA_IN_CB is defined, 7z Decoder will not allocate memory for
+compressed blocks. Instead of this, you must allocate buffer with desired
+size before calling 7z Decoder. Use 7zMain.c as example.
+
+
+
+EXIT codes
+-----------
+
+7z Decoder functions can return one of the following codes:
+
+#define SZ_OK (0)
+#define SZE_DATA_ERROR (1)
+#define SZE_OUTOFMEMORY (2)
+#define SZE_CRC_ERROR (3)
+
+#define SZE_NOTIMPL (4)
+#define SZE_FAIL (5)
+
+#define SZE_ARCHIVE_ERROR (6)
+
+
+
+LZMA Defines
+------------
+
+_LZMA_IN_CB - Use special callback mode for input stream to reduce memory requirements
+
+_SZ_FILE_SIZE_64 - define it if you need support for files larger than 4 GB
+_SZ_NO_INT_64 - define it if your compiler doesn't support long long int
+
+_LZMA_PROB32 - it can increase LZMA decompressing speed on some 32-bit CPUs.
+
+_SZ_ONE_DIRECTORY - define it if you want to locate all source files to one directory
+_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/support.html
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/7zFormat.txt squashfs-tools-patched/LZMA/lzmadaptive/7zFormat.txt
--- squashfs-tools/LZMA/lzmadaptive/7zFormat.txt 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/7zFormat.txt 2016-08-25 09:06:03.223530354 -0400
@@ -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)
+while(true)
+{
+ 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
+
+ while(true)
+ {
+ 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
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zAlloc.c squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zAlloc.c
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zAlloc.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zAlloc.c 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,70 @@
+/* 7zAlloc.c */
+
+#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(size_t size)
+{
+ 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 *address)
+{
+ #ifdef _SZ_ALLOC_DEBUG
+ if (address != 0)
+ {
+ g_allocCount--;
+ fprintf(stderr, "\nFree; count = %10d", g_allocCount);
+ }
+ #endif
+ free(address);
+}
+
+void *SzAllocTemp(size_t size)
+{
+ 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 *address)
+{
+ #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);
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zAlloc.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zAlloc.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zAlloc.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zAlloc.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,20 @@
+/* 7zAlloc.h */
+
+#ifndef __7Z_ALLOC_H
+#define __7Z_ALLOC_H
+
+#include <stddef.h>
+
+typedef struct _ISzAlloc
+{
+ void *(*Alloc)(size_t size);
+ void (*Free)(void *address); /* address can be 0 */
+} ISzAlloc;
+
+void *SzAlloc(size_t size);
+void SzFree(void *address);
+
+void *SzAllocTemp(size_t size);
+void SzFreeTemp(void *address);
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zBuffer.c squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zBuffer.c
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zBuffer.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zBuffer.c 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,29 @@
+/* 7zBuffer.c */
+
+#include "7zBuffer.h"
+#include "7zAlloc.h"
+
+void SzByteBufferInit(CSzByteBuffer *buffer)
+{
+ buffer->Capacity = 0;
+ buffer->Items = 0;
+}
+
+int SzByteBufferCreate(CSzByteBuffer *buffer, size_t newCapacity, void * (*allocFunc)(size_t size))
+{
+ buffer->Capacity = newCapacity;
+ if (newCapacity == 0)
+ {
+ buffer->Items = 0;
+ return 1;
+ }
+ buffer->Items = (Byte *)allocFunc(newCapacity);
+ return (buffer->Items != 0);
+}
+
+void SzByteBufferFree(CSzByteBuffer *buffer, void (*freeFunc)(void *))
+{
+ freeFunc(buffer->Items);
+ buffer->Items = 0;
+ buffer->Capacity = 0;
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zBuffer.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zBuffer.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zBuffer.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zBuffer.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,19 @@
+/* 7zBuffer.h */
+
+#ifndef __7Z_BUFFER_H
+#define __7Z_BUFFER_H
+
+#include <stddef.h>
+#include "7zTypes.h"
+
+typedef struct _CSzByteBuffer
+{
+ size_t Capacity;
+ Byte *Items;
+}CSzByteBuffer;
+
+void SzByteBufferInit(CSzByteBuffer *buffer);
+int SzByteBufferCreate(CSzByteBuffer *buffer, size_t newCapacity, void * (*allocFunc)(size_t size));
+void SzByteBufferFree(CSzByteBuffer *buffer, void (*freeFunc)(void *));
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7z_C.dsp squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7z_C.dsp
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7z_C.dsp 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7z_C.dsp 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,178 @@
+# Microsoft Developer Studio Project File - Name="7z_C" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=7z_C - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "7z_C.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "7z_C.mak" CFG="7z_C - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "7z_C - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "7z_C - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "7z_C - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W4 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_LZMA_PROB32" /D "_LZMA_IN_CB" /YX /FD /c
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"Release/7zDec.exe"
+
+!ELSEIF "$(CFG)" == "7z_C - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_LZMA_PROB32" /D "_LZMA_IN_CB" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x419 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"Debug/7zDec.exe" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "7z_C - Win32 Release"
+# Name "7z_C - Win32 Debug"
+# Begin Group "LZMA"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA_C\LzmaDecode.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA_C\LzmaDecode.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\7zAlloc.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zAlloc.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zBuffer.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zCrc.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zCrc.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zDecode.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zDecode.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zExtract.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zExtract.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zHeader.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zHeader.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zIn.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zIn.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zItem.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zItem.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zMain.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zMethodID.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zMethodID.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zTypes.h
+# End Source File
+# End Target
+# End Project
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7z_C.dsw squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7z_C.dsw
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7z_C.dsw 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7z_C.dsw 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "7z_C"=.\7z_C.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zCrc.c squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zCrc.c
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zCrc.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zCrc.c 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,76 @@
+/* 7zCrc.c */
+
+#include "7zCrc.h"
+
+#define kCrcPoly 0xEDB88320
+
+UInt32 g_CrcTable[256];
+
+void InitCrcTable()
+{
+ UInt32 i;
+ for (i = 0; i < 256; i++)
+ {
+ UInt32 r = i;
+ int j;
+ for (j = 0; j < 8; j++)
+ if (r & 1)
+ r = (r >> 1) ^ kCrcPoly;
+ else
+ r >>= 1;
+ g_CrcTable[i] = r;
+ }
+}
+
+void CrcInit(UInt32 *crc) { *crc = 0xFFFFFFFF; }
+UInt32 CrcGetDigest(UInt32 *crc) { return *crc ^ 0xFFFFFFFF; }
+
+void CrcUpdateByte(UInt32 *crc, Byte b)
+{
+ *crc = g_CrcTable[((Byte)(*crc)) ^ b] ^ (*crc >> 8);
+}
+
+void CrcUpdateUInt16(UInt32 *crc, UInt16 v)
+{
+ CrcUpdateByte(crc, (Byte)v);
+ CrcUpdateByte(crc, (Byte)(v >> 8));
+}
+
+void CrcUpdateUInt32(UInt32 *crc, UInt32 v)
+{
+ int i;
+ for (i = 0; i < 4; i++)
+ CrcUpdateByte(crc, (Byte)(v >> (8 * i)));
+}
+
+void CrcUpdateUInt64(UInt32 *crc, UInt64 v)
+{
+ int i;
+ for (i = 0; i < 8; i++)
+ {
+ CrcUpdateByte(crc, (Byte)(v));
+ v >>= 8;
+ }
+}
+
+void CrcUpdate(UInt32 *crc, const void *data, size_t size)
+{
+ UInt32 v = *crc;
+ const Byte *p = (const Byte *)data;
+ for (; size > 0 ; size--, p++)
+ v = g_CrcTable[((Byte)(v)) ^ *p] ^ (v >> 8);
+ *crc = v;
+}
+
+UInt32 CrcCalculateDigest(const void *data, size_t size)
+{
+ UInt32 crc;
+ CrcInit(&crc);
+ CrcUpdate(&crc, data, size);
+ return CrcGetDigest(&crc);
+}
+
+int CrcVerifyDigest(UInt32 digest, const void *data, size_t size)
+{
+ return (CrcCalculateDigest(data, size) == digest);
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zCrc.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zCrc.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zCrc.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zCrc.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,24 @@
+/* 7zCrc.h */
+
+#ifndef __7Z_CRC_H
+#define __7Z_CRC_H
+
+#include <stddef.h>
+
+#include "7zTypes.h"
+
+extern UInt32 g_CrcTable[256];
+void InitCrcTable();
+
+void CrcInit(UInt32 *crc);
+UInt32 CrcGetDigest(UInt32 *crc);
+void CrcUpdateByte(UInt32 *crc, Byte v);
+void CrcUpdateUInt16(UInt32 *crc, UInt16 v);
+void CrcUpdateUInt32(UInt32 *crc, UInt32 v);
+void CrcUpdateUInt64(UInt32 *crc, UInt64 v);
+void CrcUpdate(UInt32 *crc, const void *data, size_t size);
+
+UInt32 CrcCalculateDigest(const void *data, size_t size);
+int CrcVerifyDigest(UInt32 digest, const void *data, size_t size);
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zDecode.c squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zDecode.c
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zDecode.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zDecode.c 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,150 @@
+/* 7zDecode.c */
+
+#include "7zDecode.h"
+#ifdef _SZ_ONE_DIRECTORY
+#include "LzmaDecode.h"
+#else
+#include "../../Compress/LZMA_C/LzmaDecode.h"
+#endif
+
+CMethodID k_Copy = { { 0x0 }, 1 };
+CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 };
+
+#ifdef _LZMA_IN_CB
+
+typedef struct _CLzmaInCallbackImp
+{
+ ILzmaInCallback InCallback;
+ ISzInStream *InStream;
+ size_t Size;
+} CLzmaInCallbackImp;
+
+int LzmaReadImp(void *object, const unsigned char **buffer, SizeT *size)
+{
+ CLzmaInCallbackImp *cb = (CLzmaInCallbackImp *)object;
+ size_t processedSize;
+ SZ_RESULT res;
+ *size = 0;
+ res = cb->InStream->Read((void *)cb->InStream, (void **)buffer, cb->Size, &processedSize);
+ *size = (SizeT)processedSize;
+ if (processedSize > cb->Size)
+ return (int)SZE_FAIL;
+ cb->Size -= processedSize;
+ if (res == SZ_OK)
+ return 0;
+ return (int)res;
+}
+
+#endif
+
+SZ_RESULT SzDecode(const CFileSize *packSizes, const CFolder *folder,
+ #ifdef _LZMA_IN_CB
+ ISzInStream *inStream,
+ #else
+ const Byte *inBuffer,
+ #endif
+ Byte *outBuffer, size_t outSize,
+ size_t *outSizeProcessed, ISzAlloc *allocMain)
+{
+ UInt32 si;
+ size_t inSize = 0;
+ CCoderInfo *coder;
+ if (folder->NumPackStreams != 1)
+ return SZE_NOTIMPL;
+ if (folder->NumCoders != 1)
+ return SZE_NOTIMPL;
+ coder = folder->Coders;
+ *outSizeProcessed = 0;
+
+ for (si = 0; si < folder->NumPackStreams; si++)
+ inSize += (size_t)packSizes[si];
+
+ if (AreMethodsEqual(&coder->MethodID, &k_Copy))
+ {
+ size_t i;
+ if (inSize != outSize)
+ return SZE_DATA_ERROR;
+ #ifdef _LZMA_IN_CB
+ for (i = 0; i < inSize;)
+ {
+ size_t j;
+ Byte *inBuffer;
+ size_t bufferSize;
+ RINOK(inStream->Read((void *)inStream, (void **)&inBuffer, inSize - i, &bufferSize));
+ if (bufferSize == 0)
+ return SZE_DATA_ERROR;
+ if (bufferSize > inSize - i)
+ return SZE_FAIL;
+ *outSizeProcessed += bufferSize;
+ for (j = 0; j < bufferSize && i < inSize; j++, i++)
+ outBuffer[i] = inBuffer[j];
+ }
+ #else
+ for (i = 0; i < inSize; i++)
+ outBuffer[i] = inBuffer[i];
+ *outSizeProcessed = inSize;
+ #endif
+ return SZ_OK;
+ }
+
+ if (AreMethodsEqual(&coder->MethodID, &k_LZMA))
+ {
+ #ifdef _LZMA_IN_CB
+ CLzmaInCallbackImp lzmaCallback;
+ #else
+ SizeT inProcessed;
+ #endif
+
+ CLzmaDecoderState state; /* it's about 24-80 bytes structure, if int is 32-bit */
+ int result;
+ SizeT outSizeProcessedLoc;
+
+ #ifdef _LZMA_IN_CB
+ lzmaCallback.Size = inSize;
+ lzmaCallback.InStream = inStream;
+ lzmaCallback.InCallback.Read = LzmaReadImp;
+ #endif
+
+ if (LzmaDecodeProperties(&state.Properties, coder->Properties.Items,
+ coder->Properties.Capacity) != LZMA_RESULT_OK)
+ return SZE_FAIL;
+
+ state.Probs = (CProb *)allocMain->Alloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
+ if (state.Probs == 0)
+ return SZE_OUTOFMEMORY;
+
+ #ifdef _LZMA_OUT_READ
+ if (state.Properties.DictionarySize == 0)
+ state.Dictionary = 0;
+ else
+ {
+ state.Dictionary = (unsigned char *)allocMain->Alloc(state.Properties.DictionarySize);
+ if (state.Dictionary == 0)
+ {
+ allocMain->Free(state.Probs);
+ return SZE_OUTOFMEMORY;
+ }
+ }
+ LzmaDecoderInit(&state);
+ #endif
+
+ result = LzmaDecode(&state,
+ #ifdef _LZMA_IN_CB
+ &lzmaCallback.InCallback,
+ #else
+ inBuffer, (SizeT)inSize, &inProcessed,
+ #endif
+ outBuffer, (SizeT)outSize, &outSizeProcessedLoc);
+ *outSizeProcessed = (size_t)outSizeProcessedLoc;
+ allocMain->Free(state.Probs);
+ #ifdef _LZMA_OUT_READ
+ allocMain->Free(state.Dictionary);
+ #endif
+ if (result == LZMA_RESULT_DATA_ERROR)
+ return SZE_DATA_ERROR;
+ if (result != LZMA_RESULT_OK)
+ return SZE_FAIL;
+ return SZ_OK;
+ }
+ return SZE_NOTIMPL;
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zDecode.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zDecode.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zDecode.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zDecode.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,21 @@
+/* 7zDecode.h */
+
+#ifndef __7Z_DECODE_H
+#define __7Z_DECODE_H
+
+#include "7zItem.h"
+#include "7zAlloc.h"
+#ifdef _LZMA_IN_CB
+#include "7zIn.h"
+#endif
+
+SZ_RESULT SzDecode(const CFileSize *packSizes, const CFolder *folder,
+ #ifdef _LZMA_IN_CB
+ ISzInStream *stream,
+ #else
+ const Byte *inBuffer,
+ #endif
+ Byte *outBuffer, size_t outSize,
+ size_t *outSizeProcessed, ISzAlloc *allocMain);
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zExtract.c squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zExtract.c
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zExtract.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zExtract.c 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,116 @@
+/* 7zExtract.c */
+
+#include "7zExtract.h"
+#include "7zDecode.h"
+#include "7zCrc.h"
+
+SZ_RESULT SzExtract(
+ ISzInStream *inStream,
+ CArchiveDatabaseEx *db,
+ UInt32 fileIndex,
+ UInt32 *blockIndex,
+ Byte **outBuffer,
+ size_t *outBufferSize,
+ size_t *offset,
+ size_t *outSizeProcessed,
+ ISzAlloc *allocMain,
+ ISzAlloc *allocTemp)
+{
+ UInt32 folderIndex = db->FileIndexToFolderIndexMap[fileIndex];
+ SZ_RESULT res = SZ_OK;
+ *offset = 0;
+ *outSizeProcessed = 0;
+ if (folderIndex == (UInt32)-1)
+ {
+ allocMain->Free(*outBuffer);
+ *blockIndex = folderIndex;
+ *outBuffer = 0;
+ *outBufferSize = 0;
+ return SZ_OK;
+ }
+
+ if (*outBuffer == 0 || *blockIndex != folderIndex)
+ {
+ CFolder *folder = db->Database.Folders + folderIndex;
+ CFileSize unPackSize = SzFolderGetUnPackSize(folder);
+ #ifndef _LZMA_IN_CB
+ CFileSize packSize = SzArDbGetFolderFullPackSize(db, folderIndex);
+ Byte *inBuffer = 0;
+ size_t processedSize;
+ #endif
+ *blockIndex = folderIndex;
+ allocMain->Free(*outBuffer);
+ *outBuffer = 0;
+
+ RINOK(inStream->Seek(inStream, SzArDbGetFolderStreamPos(db, folderIndex, 0)));
+
+ #ifndef _LZMA_IN_CB
+ if (packSize != 0)
+ {
+ inBuffer = (Byte *)allocTemp->Alloc((size_t)packSize);
+ if (inBuffer == 0)
+ return SZE_OUTOFMEMORY;
+ }
+ res = inStream->Read(inStream, inBuffer, (size_t)packSize, &processedSize);
+ if (res == SZ_OK && processedSize != (size_t)packSize)
+ res = SZE_FAIL;
+ #endif
+ if (res == SZ_OK)
+ {
+ *outBufferSize = (size_t)unPackSize;
+ if (unPackSize != 0)
+ {
+ *outBuffer = (Byte *)allocMain->Alloc((size_t)unPackSize);
+ if (*outBuffer == 0)
+ res = SZE_OUTOFMEMORY;
+ }
+ if (res == SZ_OK)
+ {
+ size_t outRealSize;
+ res = SzDecode(db->Database.PackSizes +
+ db->FolderStartPackStreamIndex[folderIndex], folder,
+ #ifdef _LZMA_IN_CB
+ inStream,
+ #else
+ inBuffer,
+ #endif
+ *outBuffer, (size_t)unPackSize, &outRealSize, allocTemp);
+ if (res == SZ_OK)
+ {
+ if (outRealSize == (size_t)unPackSize)
+ {
+ if (folder->UnPackCRCDefined)
+ {
+ if (!CrcVerifyDigest(folder->UnPackCRC, *outBuffer, (size_t)unPackSize))
+ res = SZE_FAIL;
+ }
+ }
+ else
+ res = SZE_FAIL;
+ }
+ }
+ }
+ #ifndef _LZMA_IN_CB
+ allocTemp->Free(inBuffer);
+ #endif
+ }
+ if (res == SZ_OK)
+ {
+ UInt32 i;
+ CFileItem *fileItem = db->Database.Files + fileIndex;
+ *offset = 0;
+ for(i = db->FolderStartFileIndex[folderIndex]; i < fileIndex; i++)
+ *offset += (UInt32)db->Database.Files[i].Size;
+ *outSizeProcessed = (size_t)fileItem->Size;
+ if (*offset + *outSizeProcessed > *outBufferSize)
+ return SZE_FAIL;
+ {
+ if (fileItem->IsFileCRCDefined)
+ {
+ if (!CrcVerifyDigest(fileItem->FileCRC, *outBuffer + *offset, *outSizeProcessed))
+ res = SZE_FAIL;
+ }
+ }
+ }
+ return res;
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zExtract.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zExtract.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zExtract.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zExtract.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,40 @@
+/* 7zExtract.h */
+
+#ifndef __7Z_EXTRACT_H
+#define __7Z_EXTRACT_H
+
+#include "7zIn.h"
+
+/*
+ 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.
+*/
+
+SZ_RESULT SzExtract(
+ ISzInStream *inStream,
+ CArchiveDatabaseEx *db,
+ 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);
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zHeader.c squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zHeader.c
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zHeader.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zHeader.c 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,5 @@
+/* 7zHeader.c */
+
+#include "7zHeader.h"
+
+Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zHeader.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zHeader.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zHeader.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zHeader.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,55 @@
+/* 7zHeader.h */
+
+#ifndef __7Z_HEADER_H
+#define __7Z_HEADER_H
+
+#include "7zTypes.h"
+
+#define k7zSignatureSize 6
+extern Byte k7zSignature[k7zSignatureSize];
+
+#define k7zMajorVersion 0
+
+#define k7zStartHeaderSize 0x20
+
+enum EIdEnum
+{
+ k7zIdEnd,
+
+ k7zIdHeader,
+
+ k7zIdArchiveProperties,
+
+ k7zIdAdditionalStreamsInfo,
+ k7zIdMainStreamsInfo,
+ k7zIdFilesInfo,
+
+ k7zIdPackInfo,
+ k7zIdUnPackInfo,
+ k7zIdSubStreamsInfo,
+
+ k7zIdSize,
+ k7zIdCRC,
+
+ k7zIdFolder,
+
+ k7zIdCodersUnPackSize,
+ k7zIdNumUnPackStream,
+
+ k7zIdEmptyStream,
+ k7zIdEmptyFile,
+ k7zIdAnti,
+
+ k7zIdName,
+ k7zIdCreationTime,
+ k7zIdLastAccessTime,
+ k7zIdLastWriteTime,
+ k7zIdWinAttributes,
+ k7zIdComment,
+
+ k7zIdEncodedHeader,
+
+ k7zIdStartPos
+};
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zIn.c squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zIn.c
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zIn.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zIn.c 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,1292 @@
+/* 7zIn.c */
+
+#include "7zIn.h"
+#include "7zCrc.h"
+#include "7zDecode.h"
+
+#define RINOM(x) { if((x) == 0) return SZE_OUTOFMEMORY; }
+
+void SzArDbExInit(CArchiveDatabaseEx *db)
+{
+ SzArchiveDatabaseInit(&db->Database);
+ db->FolderStartPackStreamIndex = 0;
+ db->PackStreamStartPositions = 0;
+ db->FolderStartFileIndex = 0;
+ db->FileIndexToFolderIndexMap = 0;
+}
+
+void SzArDbExFree(CArchiveDatabaseEx *db, void (*freeFunc)(void *))
+{
+ freeFunc(db->FolderStartPackStreamIndex);
+ freeFunc(db->PackStreamStartPositions);
+ freeFunc(db->FolderStartFileIndex);
+ freeFunc(db->FileIndexToFolderIndexMap);
+ SzArchiveDatabaseFree(&db->Database, freeFunc);
+ SzArDbExInit(db);
+}
+
+/*
+CFileSize GetFolderPackStreamSize(int folderIndex, int streamIndex) const
+{
+ return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex];
+}
+
+CFileSize GetFilePackSize(int fileIndex) const
+{
+ int folderIndex = FileIndexToFolderIndexMap[fileIndex];
+ if (folderIndex >= 0)
+ {
+ const CFolder &folderInfo = Folders[folderIndex];
+ if (FolderStartFileIndex[folderIndex] == fileIndex)
+ return GetFolderFullPackSize(folderIndex);
+ }
+ return 0;
+}
+*/
+
+
+SZ_RESULT MySzInAlloc(void **p, size_t size, void * (*allocFunc)(size_t size))
+{
+ if (size == 0)
+ *p = 0;
+ else
+ {
+ *p = allocFunc(size);
+ RINOM(*p);
+ }
+ return SZ_OK;
+}
+
+SZ_RESULT SzArDbExFill(CArchiveDatabaseEx *db, void * (*allocFunc)(size_t size))
+{
+ UInt32 startPos = 0;
+ CFileSize startPosSize = 0;
+ UInt32 i;
+ UInt32 folderIndex = 0;
+ UInt32 indexInFolder = 0;
+ RINOK(MySzInAlloc((void **)&db->FolderStartPackStreamIndex, db->Database.NumFolders * sizeof(UInt32), allocFunc));
+ for(i = 0; i < db->Database.NumFolders; i++)
+ {
+ db->FolderStartPackStreamIndex[i] = startPos;
+ startPos += db->Database.Folders[i].NumPackStreams;
+ }
+
+ RINOK(MySzInAlloc((void **)&db->PackStreamStartPositions, db->Database.NumPackStreams * sizeof(CFileSize), allocFunc));
+
+ for(i = 0; i < db->Database.NumPackStreams; i++)
+ {
+ db->PackStreamStartPositions[i] = startPosSize;
+ startPosSize += db->Database.PackSizes[i];
+ }
+
+ RINOK(MySzInAlloc((void **)&db->FolderStartFileIndex, db->Database.NumFolders * sizeof(UInt32), allocFunc));
+ RINOK(MySzInAlloc((void **)&db->FileIndexToFolderIndexMap, db->Database.NumFiles * sizeof(UInt32), allocFunc));
+
+ for (i = 0; i < db->Database.NumFiles; i++)
+ {
+ CFileItem *file = db->Database.Files + i;
+ int emptyStream = !file->HasStream;
+ if (emptyStream && indexInFolder == 0)
+ {
+ db->FileIndexToFolderIndexMap[i] = (UInt32)-1;
+ continue;
+ }
+ if (indexInFolder == 0)
+ {
+ /*
+ v3.13 incorrectly worked with empty folders
+ v4.07: Loop for skipping empty folders
+ */
+ while(1)
+ {
+ if (folderIndex >= db->Database.NumFolders)
+ return SZE_ARCHIVE_ERROR;
+ db->FolderStartFileIndex[folderIndex] = i;
+ if (db->Database.Folders[folderIndex].NumUnPackStreams != 0)
+ break;
+ folderIndex++;
+ }
+ }
+ db->FileIndexToFolderIndexMap[i] = folderIndex;
+ if (emptyStream)
+ continue;
+ indexInFolder++;
+ if (indexInFolder >= db->Database.Folders[folderIndex].NumUnPackStreams)
+ {
+ folderIndex++;
+ indexInFolder = 0;
+ }
+ }
+ return SZ_OK;
+}
+
+
+CFileSize SzArDbGetFolderStreamPos(CArchiveDatabaseEx *db, UInt32 folderIndex, UInt32 indexInFolder)
+{
+ return db->ArchiveInfo.DataStartPosition +
+ db->PackStreamStartPositions[db->FolderStartPackStreamIndex[folderIndex] + indexInFolder];
+}
+
+CFileSize SzArDbGetFolderFullPackSize(CArchiveDatabaseEx *db, UInt32 folderIndex)
+{
+ UInt32 packStreamIndex = db->FolderStartPackStreamIndex[folderIndex];
+ CFolder *folder = db->Database.Folders + folderIndex;
+ CFileSize size = 0;
+ UInt32 i;
+ for (i = 0; i < folder->NumPackStreams; i++)
+ size += db->Database.PackSizes[packStreamIndex + i];
+ return size;
+}
+
+
+/*
+SZ_RESULT SzReadTime(const CObjectVector<CSzByteBuffer> &dataVector,
+ CObjectVector<CFileItem> &files, UInt64 type)
+{
+ CBoolVector boolVector;
+ RINOK(ReadBoolVector2(files.Size(), boolVector))
+
+ CStreamSwitch streamSwitch;
+ RINOK(streamSwitch.Set(this, &dataVector));
+
+ for(int i = 0; i < files.Size(); i++)
+ {
+ CFileItem &file = files[i];
+ CArchiveFileTime fileTime;
+ bool defined = boolVector[i];
+ if (defined)
+ {
+ UInt32 low, high;
+ RINOK(SzReadUInt32(low));
+ RINOK(SzReadUInt32(high));
+ fileTime.dwLowDateTime = low;
+ fileTime.dwHighDateTime = high;
+ }
+ switch(type)
+ {
+ case k7zIdCreationTime:
+ file.IsCreationTimeDefined = defined;
+ if (defined)
+ file.CreationTime = fileTime;
+ break;
+ case k7zIdLastWriteTime:
+ file.IsLastWriteTimeDefined = defined;
+ if (defined)
+ file.LastWriteTime = fileTime;
+ break;
+ case k7zIdLastAccessTime:
+ file.IsLastAccessTimeDefined = defined;
+ if (defined)
+ file.LastAccessTime = fileTime;
+ break;
+ }
+ }
+ return SZ_OK;
+}
+*/
+
+SZ_RESULT SafeReadDirect(ISzInStream *inStream, Byte *data, size_t size)
+{
+ #ifdef _LZMA_IN_CB
+ while (size > 0)
+ {
+ Byte *inBuffer;
+ size_t processedSize;
+ RINOK(inStream->Read(inStream, (void **)&inBuffer, size, &processedSize));
+ if (processedSize == 0 || processedSize > size)
+ return SZE_FAIL;
+ size -= processedSize;
+ do
+ {
+ *data++ = *inBuffer++;
+ }
+ while (--processedSize != 0);
+ }
+ #else
+ size_t processedSize;
+ RINOK(inStream->Read(inStream, data, size, &processedSize));
+ if (processedSize != size)
+ return SZE_FAIL;
+ #endif
+ return SZ_OK;
+}
+
+SZ_RESULT SafeReadDirectByte(ISzInStream *inStream, Byte *data)
+{
+ return SafeReadDirect(inStream, data, 1);
+}
+
+SZ_RESULT SafeReadDirectUInt32(ISzInStream *inStream, UInt32 *value)
+{
+ int i;
+ *value = 0;
+ for (i = 0; i < 4; i++)
+ {
+ Byte b;
+ RINOK(SafeReadDirectByte(inStream, &b));
+ *value |= ((UInt32)b << (8 * i));
+ }
+ return SZ_OK;
+}
+
+SZ_RESULT SafeReadDirectUInt64(ISzInStream *inStream, UInt64 *value)
+{
+ int i;
+ *value = 0;
+ for (i = 0; i < 8; i++)
+ {
+ Byte b;
+ RINOK(SafeReadDirectByte(inStream, &b));
+ *value |= ((UInt32)b << (8 * i));
+ }
+ return SZ_OK;
+}
+
+int TestSignatureCandidate(Byte *testBytes)
+{
+ size_t i;
+ for (i = 0; i < k7zSignatureSize; i++)
+ if (testBytes[i] != k7zSignature[i])
+ return 0;
+ return 1;
+}
+
+typedef struct _CSzState
+{
+ Byte *Data;
+ size_t Size;
+}CSzData;
+
+SZ_RESULT SzReadByte(CSzData *sd, Byte *b)
+{
+ if (sd->Size == 0)
+ return SZE_ARCHIVE_ERROR;
+ sd->Size--;
+ *b = *sd->Data++;
+ return SZ_OK;
+}
+
+SZ_RESULT SzReadBytes(CSzData *sd, Byte *data, size_t size)
+{
+ size_t i;
+ for (i = 0; i < size; i++)
+ {
+ RINOK(SzReadByte(sd, data + i));
+ }
+ return SZ_OK;
+}
+
+SZ_RESULT SzReadUInt32(CSzData *sd, UInt32 *value)
+{
+ int i;
+ *value = 0;
+ for (i = 0; i < 4; i++)
+ {
+ Byte b;
+ RINOK(SzReadByte(sd, &b));
+ *value |= ((UInt32)(b) << (8 * i));
+ }
+ return SZ_OK;
+}
+
+SZ_RESULT SzReadNumber(CSzData *sd, UInt64 *value)
+{
+ Byte firstByte;
+ Byte mask = 0x80;
+ int i;
+ RINOK(SzReadByte(sd, &firstByte));
+ *value = 0;
+ for (i = 0; i < 8; i++)
+ {
+ Byte b;
+ if ((firstByte & mask) == 0)
+ {
+ UInt64 highPart = firstByte & (mask - 1);
+ *value += (highPart << (8 * i));
+ return SZ_OK;
+ }
+ RINOK(SzReadByte(sd, &b));
+ *value |= ((UInt64)b << (8 * i));
+ mask >>= 1;
+ }
+ return SZ_OK;
+}
+
+SZ_RESULT SzReadSize(CSzData *sd, CFileSize *value)
+{
+ UInt64 value64;
+ RINOK(SzReadNumber(sd, &value64));
+ *value = (CFileSize)value64;
+ return SZ_OK;
+}
+
+SZ_RESULT SzReadNumber32(CSzData *sd, UInt32 *value)
+{
+ UInt64 value64;
+ RINOK(SzReadNumber(sd, &value64));
+ if (value64 >= 0x80000000)
+ return SZE_NOTIMPL;
+ if (value64 >= ((UInt64)(1) << ((sizeof(size_t) - 1) * 8 + 2)))
+ return SZE_NOTIMPL;
+ *value = (UInt32)value64;
+ return SZ_OK;
+}
+
+SZ_RESULT SzReadID(CSzData *sd, UInt64 *value)
+{
+ return SzReadNumber(sd, value);
+}
+
+SZ_RESULT SzSkeepDataSize(CSzData *sd, UInt64 size)
+{
+ if (size > sd->Size)
+ return SZE_ARCHIVE_ERROR;
+ sd->Size -= (size_t)size;
+ sd->Data += (size_t)size;
+ return SZ_OK;
+}
+
+SZ_RESULT SzSkeepData(CSzData *sd)
+{
+ UInt64 size;
+ RINOK(SzReadNumber(sd, &size));
+ return SzSkeepDataSize(sd, size);
+}
+
+SZ_RESULT SzReadArchiveProperties(CSzData *sd)
+{
+ while(1)
+ {
+ UInt64 type;
+ RINOK(SzReadID(sd, &type));
+ if (type == k7zIdEnd)
+ break;
+ SzSkeepData(sd);
+ }
+ return SZ_OK;
+}
+
+SZ_RESULT SzWaitAttribute(CSzData *sd, UInt64 attribute)
+{
+ while(1)
+ {
+ UInt64 type;
+ RINOK(SzReadID(sd, &type));
+ if (type == attribute)
+ return SZ_OK;
+ if (type == k7zIdEnd)
+ return SZE_ARCHIVE_ERROR;
+ RINOK(SzSkeepData(sd));
+ }
+}
+
+SZ_RESULT SzReadBoolVector(CSzData *sd, size_t numItems, Byte **v, void * (*allocFunc)(size_t size))
+{
+ Byte b = 0;
+ Byte mask = 0;
+ size_t i;
+ RINOK(MySzInAlloc((void **)v, numItems * sizeof(Byte), allocFunc));
+ for(i = 0; i < numItems; i++)
+ {
+ if (mask == 0)
+ {
+ RINOK(SzReadByte(sd, &b));
+ mask = 0x80;
+ }
+ (*v)[i] = (Byte)(((b & mask) != 0) ? 1 : 0);
+ mask >>= 1;
+ }
+ return SZ_OK;
+}
+
+SZ_RESULT SzReadBoolVector2(CSzData *sd, size_t numItems, Byte **v, void * (*allocFunc)(size_t size))
+{
+ Byte allAreDefined;
+ size_t i;
+ RINOK(SzReadByte(sd, &allAreDefined));
+ if (allAreDefined == 0)
+ return SzReadBoolVector(sd, numItems, v, allocFunc);
+ RINOK(MySzInAlloc((void **)v, numItems * sizeof(Byte), allocFunc));
+ for(i = 0; i < numItems; i++)
+ (*v)[i] = 1;
+ return SZ_OK;
+}
+
+SZ_RESULT SzReadHashDigests(
+ CSzData *sd,
+ size_t numItems,
+ Byte **digestsDefined,
+ UInt32 **digests,
+ void * (*allocFunc)(size_t size))
+{
+ size_t i;
+ RINOK(SzReadBoolVector2(sd, numItems, digestsDefined, allocFunc));
+ RINOK(MySzInAlloc((void **)digests, numItems * sizeof(UInt32), allocFunc));
+ for(i = 0; i < numItems; i++)
+ if ((*digestsDefined)[i])
+ {
+ RINOK(SzReadUInt32(sd, (*digests) + i));
+ }
+ return SZ_OK;
+}
+
+SZ_RESULT SzReadPackInfo(
+ CSzData *sd,
+ CFileSize *dataOffset,
+ UInt32 *numPackStreams,
+ CFileSize **packSizes,
+ Byte **packCRCsDefined,
+ UInt32 **packCRCs,
+ void * (*allocFunc)(size_t size))
+{
+ UInt32 i;
+ RINOK(SzReadSize(sd, dataOffset));
+ RINOK(SzReadNumber32(sd, numPackStreams));
+
+ RINOK(SzWaitAttribute(sd, k7zIdSize));
+
+ RINOK(MySzInAlloc((void **)packSizes, (size_t)*numPackStreams * sizeof(CFileSize), allocFunc));
+
+ for(i = 0; i < *numPackStreams; i++)
+ {
+ RINOK(SzReadSize(sd, (*packSizes) + i));
+ }
+
+ while(1)
+ {
+ UInt64 type;
+ RINOK(SzReadID(sd, &type));
+ if (type == k7zIdEnd)
+ break;
+ if (type == k7zIdCRC)
+ {
+ RINOK(SzReadHashDigests(sd, (size_t)*numPackStreams, packCRCsDefined, packCRCs, allocFunc));
+ continue;
+ }
+ RINOK(SzSkeepData(sd));
+ }
+ if (*packCRCsDefined == 0)
+ {
+ RINOK(MySzInAlloc((void **)packCRCsDefined, (size_t)*numPackStreams * sizeof(Byte), allocFunc));
+ RINOK(MySzInAlloc((void **)packCRCs, (size_t)*numPackStreams * sizeof(UInt32), allocFunc));
+ for(i = 0; i < *numPackStreams; i++)
+ {
+ (*packCRCsDefined)[i] = 0;
+ (*packCRCs)[i] = 0;
+ }
+ }
+ return SZ_OK;
+}
+
+SZ_RESULT SzReadSwitch(CSzData *sd)
+{
+ Byte external;
+ RINOK(SzReadByte(sd, &external));
+ return (external == 0) ? SZ_OK: SZE_ARCHIVE_ERROR;
+}
+
+SZ_RESULT SzGetNextFolderItem(CSzData *sd, CFolder *folder, void * (*allocFunc)(size_t size))
+{
+ UInt32 numCoders;
+ UInt32 numBindPairs;
+ UInt32 numPackedStreams;
+ UInt32 i;
+ UInt32 numInStreams = 0;
+ UInt32 numOutStreams = 0;
+ RINOK(SzReadNumber32(sd, &numCoders));
+ folder->NumCoders = numCoders;
+
+ RINOK(MySzInAlloc((void **)&folder->Coders, (size_t)numCoders * sizeof(CCoderInfo), allocFunc));
+
+ for (i = 0; i < numCoders; i++)
+ SzCoderInfoInit(folder->Coders + i);
+
+ for (i = 0; i < numCoders; i++)
+ {
+ Byte mainByte;
+ CCoderInfo *coder = folder->Coders + i;
+ {
+ RINOK(SzReadByte(sd, &mainByte));
+ coder->MethodID.IDSize = (Byte)(mainByte & 0xF);
+ RINOK(SzReadBytes(sd, coder->MethodID.ID, coder->MethodID.IDSize));
+ if ((mainByte & 0x10) != 0)
+ {
+ RINOK(SzReadNumber32(sd, &coder->NumInStreams));
+ RINOK(SzReadNumber32(sd, &coder->NumOutStreams));
+ }
+ else
+ {
+ coder->NumInStreams = 1;
+ coder->NumOutStreams = 1;
+ }
+ if ((mainByte & 0x20) != 0)
+ {
+ UInt64 propertiesSize = 0;
+ RINOK(SzReadNumber(sd, &propertiesSize));
+ if (!SzByteBufferCreate(&coder->Properties, (size_t)propertiesSize, allocFunc))
+ return SZE_OUTOFMEMORY;
+ RINOK(SzReadBytes(sd, coder->Properties.Items, (size_t)propertiesSize));
+ }
+ }
+ while ((mainByte & 0x80) != 0)
+ {
+ RINOK(SzReadByte(sd, &mainByte));
+ RINOK(SzSkeepDataSize(sd, (mainByte & 0xF)));
+ if ((mainByte & 0x10) != 0)
+ {
+ UInt32 n;
+ RINOK(SzReadNumber32(sd, &n));
+ RINOK(SzReadNumber32(sd, &n));
+ }
+ if ((mainByte & 0x20) != 0)
+ {
+ UInt64 propertiesSize = 0;
+ RINOK(SzReadNumber(sd, &propertiesSize));
+ RINOK(SzSkeepDataSize(sd, propertiesSize));
+ }
+ }
+ numInStreams += (UInt32)coder->NumInStreams;
+ numOutStreams += (UInt32)coder->NumOutStreams;
+ }
+
+ numBindPairs = numOutStreams - 1;
+ folder->NumBindPairs = numBindPairs;
+
+
+ RINOK(MySzInAlloc((void **)&folder->BindPairs, (size_t)numBindPairs * sizeof(CBindPair), allocFunc));
+
+ for (i = 0; i < numBindPairs; i++)
+ {
+ CBindPair *bindPair = folder->BindPairs + i;;
+ RINOK(SzReadNumber32(sd, &bindPair->InIndex));
+ RINOK(SzReadNumber32(sd, &bindPair->OutIndex));
+ }
+
+ numPackedStreams = numInStreams - (UInt32)numBindPairs;
+
+ folder->NumPackStreams = numPackedStreams;
+ RINOK(MySzInAlloc((void **)&folder->PackStreams, (size_t)numPackedStreams * sizeof(UInt32), allocFunc));
+
+ if (numPackedStreams == 1)
+ {
+ UInt32 j;
+ UInt32 pi = 0;
+ for (j = 0; j < numInStreams; j++)
+ if (SzFolderFindBindPairForInStream(folder, j) < 0)
+ {
+ folder->PackStreams[pi++] = j;
+ break;
+ }
+ }
+ else
+ for(i = 0; i < numPackedStreams; i++)
+ {
+ RINOK(SzReadNumber32(sd, folder->PackStreams + i));
+ }
+ return SZ_OK;
+}
+
+SZ_RESULT SzReadUnPackInfo(
+ CSzData *sd,
+ UInt32 *numFolders,
+ CFolder **folders, /* for allocFunc */
+ void * (*allocFunc)(size_t size),
+ ISzAlloc *allocTemp)
+{
+ UInt32 i;
+ RINOK(SzWaitAttribute(sd, k7zIdFolder));
+ RINOK(SzReadNumber32(sd, numFolders));
+ {
+ RINOK(SzReadSwitch(sd));
+
+
+ RINOK(MySzInAlloc((void **)folders, (size_t)*numFolders * sizeof(CFolder), allocFunc));
+
+ for(i = 0; i < *numFolders; i++)
+ SzFolderInit((*folders) + i);
+
+ for(i = 0; i < *numFolders; i++)
+ {
+ RINOK(SzGetNextFolderItem(sd, (*folders) + i, allocFunc));
+ }
+ }
+
+ RINOK(SzWaitAttribute(sd, k7zIdCodersUnPackSize));
+
+ for(i = 0; i < *numFolders; i++)
+ {
+ UInt32 j;
+ CFolder *folder = (*folders) + i;
+ UInt32 numOutStreams = SzFolderGetNumOutStreams(folder);
+
+ RINOK(MySzInAlloc((void **)&folder->UnPackSizes, (size_t)numOutStreams * sizeof(CFileSize), allocFunc));
+
+ for(j = 0; j < numOutStreams; j++)
+ {
+ RINOK(SzReadSize(sd, folder->UnPackSizes + j));
+ }
+ }
+
+ while(1)
+ {
+ UInt64 type;
+ RINOK(SzReadID(sd, &type));
+ if (type == k7zIdEnd)
+ return SZ_OK;
+ if (type == k7zIdCRC)
+ {
+ SZ_RESULT res;
+ Byte *crcsDefined = 0;
+ UInt32 *crcs = 0;
+ res = SzReadHashDigests(sd, *numFolders, &crcsDefined, &crcs, allocTemp->Alloc);
+ if (res == SZ_OK)
+ {
+ for(i = 0; i < *numFolders; i++)
+ {
+ CFolder *folder = (*folders) + i;
+ folder->UnPackCRCDefined = crcsDefined[i];
+ folder->UnPackCRC = crcs[i];
+ }
+ }
+ allocTemp->Free(crcs);
+ allocTemp->Free(crcsDefined);
+ RINOK(res);
+ continue;
+ }
+ RINOK(SzSkeepData(sd));
+ }
+}
+
+SZ_RESULT SzReadSubStreamsInfo(
+ CSzData *sd,
+ UInt32 numFolders,
+ CFolder *folders,
+ UInt32 *numUnPackStreams,
+ CFileSize **unPackSizes,
+ Byte **digestsDefined,
+ UInt32 **digests,
+ ISzAlloc *allocTemp)
+{
+ UInt64 type = 0;
+ UInt32 i;
+ UInt32 si = 0;
+ UInt32 numDigests = 0;
+
+ for(i = 0; i < numFolders; i++)
+ folders[i].NumUnPackStreams = 1;
+ *numUnPackStreams = numFolders;
+
+ while(1)
+ {
+ RINOK(SzReadID(sd, &type));
+ if (type == k7zIdNumUnPackStream)
+ {
+ *numUnPackStreams = 0;
+ for(i = 0; i < numFolders; i++)
+ {
+ UInt32 numStreams;
+ RINOK(SzReadNumber32(sd, &numStreams));
+ folders[i].NumUnPackStreams = numStreams;
+ *numUnPackStreams += numStreams;
+ }
+ continue;
+ }
+ if (type == k7zIdCRC || type == k7zIdSize)
+ break;
+ if (type == k7zIdEnd)
+ break;
+ RINOK(SzSkeepData(sd));
+ }
+
+ if (*numUnPackStreams == 0)
+ {
+ *unPackSizes = 0;
+ *digestsDefined = 0;
+ *digests = 0;
+ }
+ else
+ {
+ *unPackSizes = (CFileSize *)allocTemp->Alloc((size_t)*numUnPackStreams * sizeof(CFileSize));
+ RINOM(*unPackSizes);
+ *digestsDefined = (Byte *)allocTemp->Alloc((size_t)*numUnPackStreams * sizeof(Byte));
+ RINOM(*digestsDefined);
+ *digests = (UInt32 *)allocTemp->Alloc((size_t)*numUnPackStreams * sizeof(UInt32));
+ RINOM(*digests);
+ }
+
+ for(i = 0; i < numFolders; i++)
+ {
+ /*
+ v3.13 incorrectly worked with empty folders
+ v4.07: we check that folder is empty
+ */
+ CFileSize sum = 0;
+ UInt32 j;
+ UInt32 numSubstreams = folders[i].NumUnPackStreams;
+ if (numSubstreams == 0)
+ continue;
+ if (type == k7zIdSize)
+ for (j = 1; j < numSubstreams; j++)
+ {
+ CFileSize size;
+ RINOK(SzReadSize(sd, &size));
+ (*unPackSizes)[si++] = size;
+ sum += size;
+ }
+ (*unPackSizes)[si++] = SzFolderGetUnPackSize(folders + i) - sum;
+ }
+ if (type == k7zIdSize)
+ {
+ RINOK(SzReadID(sd, &type));
+ }
+
+ for(i = 0; i < *numUnPackStreams; i++)
+ {
+ (*digestsDefined)[i] = 0;
+ (*digests)[i] = 0;
+ }
+
+
+ for(i = 0; i < numFolders; i++)
+ {
+ UInt32 numSubstreams = folders[i].NumUnPackStreams;
+ if (numSubstreams != 1 || !folders[i].UnPackCRCDefined)
+ numDigests += numSubstreams;
+ }
+
+
+ si = 0;
+ while(1)
+ {
+ if (type == k7zIdCRC)
+ {
+ int digestIndex = 0;
+ Byte *digestsDefined2 = 0;
+ UInt32 *digests2 = 0;
+ SZ_RESULT res = SzReadHashDigests(sd, numDigests, &digestsDefined2, &digests2, allocTemp->Alloc);
+ if (res == SZ_OK)
+ {
+ for (i = 0; i < numFolders; i++)
+ {
+ CFolder *folder = folders + i;
+ UInt32 numSubstreams = folder->NumUnPackStreams;
+ if (numSubstreams == 1 && folder->UnPackCRCDefined)
+ {
+ (*digestsDefined)[si] = 1;
+ (*digests)[si] = folder->UnPackCRC;
+ si++;
+ }
+ else
+ {
+ UInt32 j;
+ for (j = 0; j < numSubstreams; j++, digestIndex++)
+ {
+ (*digestsDefined)[si] = digestsDefined2[digestIndex];
+ (*digests)[si] = digests2[digestIndex];
+ si++;
+ }
+ }
+ }
+ }
+ allocTemp->Free(digestsDefined2);
+ allocTemp->Free(digests2);
+ RINOK(res);
+ }
+ else if (type == k7zIdEnd)
+ return SZ_OK;
+ else
+ {
+ RINOK(SzSkeepData(sd));
+ }
+ RINOK(SzReadID(sd, &type));
+ }
+}
+
+
+SZ_RESULT SzReadStreamsInfo(
+ CSzData *sd,
+ CFileSize *dataOffset,
+ CArchiveDatabase *db,
+ UInt32 *numUnPackStreams,
+ CFileSize **unPackSizes, /* allocTemp */
+ Byte **digestsDefined, /* allocTemp */
+ UInt32 **digests, /* allocTemp */
+ void * (*allocFunc)(size_t size),
+ ISzAlloc *allocTemp)
+{
+ while(1)
+ {
+ UInt64 type;
+ RINOK(SzReadID(sd, &type));
+ if ((UInt64)(int)type != type)
+ return SZE_FAIL;
+ switch((int)type)
+ {
+ case k7zIdEnd:
+ return SZ_OK;
+ case k7zIdPackInfo:
+ {
+ RINOK(SzReadPackInfo(sd, dataOffset, &db->NumPackStreams,
+ &db->PackSizes, &db->PackCRCsDefined, &db->PackCRCs, allocFunc));
+ break;
+ }
+ case k7zIdUnPackInfo:
+ {
+ RINOK(SzReadUnPackInfo(sd, &db->NumFolders, &db->Folders, allocFunc, allocTemp));
+ break;
+ }
+ case k7zIdSubStreamsInfo:
+ {
+ RINOK(SzReadSubStreamsInfo(sd, db->NumFolders, db->Folders,
+ numUnPackStreams, unPackSizes, digestsDefined, digests, allocTemp));
+ break;
+ }
+ default:
+ return SZE_FAIL;
+ }
+ }
+}
+
+Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
+
+SZ_RESULT SzReadFileNames(CSzData *sd, UInt32 numFiles, CFileItem *files,
+ void * (*allocFunc)(size_t size))
+{
+ UInt32 i;
+ for(i = 0; i < numFiles; i++)
+ {
+ UInt32 len = 0;
+ UInt32 pos = 0;
+ CFileItem *file = files + i;
+ while(pos + 2 <= sd->Size)
+ {
+ int numAdds;
+ UInt32 value = (UInt32)(sd->Data[pos] | (((UInt32)sd->Data[pos + 1]) << 8));
+ pos += 2;
+ len++;
+ if (value == 0)
+ break;
+ if (value < 0x80)
+ continue;
+ if (value >= 0xD800 && value < 0xE000)
+ {
+ UInt32 c2;
+ if (value >= 0xDC00)
+ return SZE_ARCHIVE_ERROR;
+ if (pos + 2 > sd->Size)
+ return SZE_ARCHIVE_ERROR;
+ c2 = (UInt32)(sd->Data[pos] | (((UInt32)sd->Data[pos + 1]) << 8));
+ pos += 2;
+ if (c2 < 0xDC00 || c2 >= 0xE000)
+ return SZE_ARCHIVE_ERROR;
+ value = ((value - 0xD800) << 10) | (c2 - 0xDC00);
+ }
+ for (numAdds = 1; numAdds < 5; numAdds++)
+ if (value < (((UInt32)1) << (numAdds * 5 + 6)))
+ break;
+ len += numAdds;
+ }
+
+ RINOK(MySzInAlloc((void **)&file->Name, (size_t)len * sizeof(char), allocFunc));
+
+ len = 0;
+ while(2 <= sd->Size)
+ {
+ int numAdds;
+ UInt32 value = (UInt32)(sd->Data[0] | (((UInt32)sd->Data[1]) << 8));
+ SzSkeepDataSize(sd, 2);
+ if (value < 0x80)
+ {
+ file->Name[len++] = (char)value;
+ if (value == 0)
+ break;
+ continue;
+ }
+ if (value >= 0xD800 && value < 0xE000)
+ {
+ UInt32 c2 = (UInt32)(sd->Data[0] | (((UInt32)sd->Data[1]) << 8));
+ SzSkeepDataSize(sd, 2);
+ value = ((value - 0xD800) << 10) | (c2 - 0xDC00);
+ }
+ for (numAdds = 1; numAdds < 5; numAdds++)
+ if (value < (((UInt32)1) << (numAdds * 5 + 6)))
+ break;
+ file->Name[len++] = (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds)));
+ do
+ {
+ numAdds--;
+ file->Name[len++] = (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F));
+ }
+ while(numAdds > 0);
+
+ len += numAdds;
+ }
+ }
+ return SZ_OK;
+}
+
+SZ_RESULT SzReadHeader2(
+ CSzData *sd,
+ CArchiveDatabaseEx *db, /* allocMain */
+ CFileSize **unPackSizes, /* allocTemp */
+ Byte **digestsDefined, /* allocTemp */
+ UInt32 **digests, /* allocTemp */
+ Byte **emptyStreamVector, /* allocTemp */
+ Byte **emptyFileVector, /* allocTemp */
+ ISzAlloc *allocMain,
+ ISzAlloc *allocTemp)
+{
+ UInt64 type;
+ UInt32 numUnPackStreams = 0;
+ UInt32 numFiles = 0;
+ CFileItem *files = 0;
+ UInt32 numEmptyStreams = 0;
+ UInt32 i;
+
+ RINOK(SzReadID(sd, &type));
+
+ if (type == k7zIdArchiveProperties)
+ {
+ RINOK(SzReadArchiveProperties(sd));
+ RINOK(SzReadID(sd, &type));
+ }
+
+
+ if (type == k7zIdMainStreamsInfo)
+ {
+ RINOK(SzReadStreamsInfo(sd,
+ &db->ArchiveInfo.DataStartPosition,
+ &db->Database,
+ &numUnPackStreams,
+ unPackSizes,
+ digestsDefined,
+ digests, allocMain->Alloc, allocTemp));
+ db->ArchiveInfo.DataStartPosition += db->ArchiveInfo.StartPositionAfterHeader;
+ RINOK(SzReadID(sd, &type));
+ }
+
+ if (type == k7zIdEnd)
+ return SZ_OK;
+ if (type != k7zIdFilesInfo)
+ return SZE_ARCHIVE_ERROR;
+
+ RINOK(SzReadNumber32(sd, &numFiles));
+ db->Database.NumFiles = numFiles;
+
+ RINOK(MySzInAlloc((void **)&files, (size_t)numFiles * sizeof(CFileItem), allocMain->Alloc));
+
+ db->Database.Files = files;
+ for(i = 0; i < numFiles; i++)
+ SzFileInit(files + i);
+
+ while(1)
+ {
+ UInt64 type;
+ UInt64 size;
+ RINOK(SzReadID(sd, &type));
+ if (type == k7zIdEnd)
+ break;
+ RINOK(SzReadNumber(sd, &size));
+
+ if ((UInt64)(int)type != type)
+ {
+ RINOK(SzSkeepDataSize(sd, size));
+ }
+ else
+ switch((int)type)
+ {
+ case k7zIdName:
+ {
+ RINOK(SzReadSwitch(sd));
+ RINOK(SzReadFileNames(sd, numFiles, files, allocMain->Alloc))
+ break;
+ }
+ case k7zIdEmptyStream:
+ {
+ RINOK(SzReadBoolVector(sd, numFiles, emptyStreamVector, allocTemp->Alloc));
+ numEmptyStreams = 0;
+ for (i = 0; i < numFiles; i++)
+ if ((*emptyStreamVector)[i])
+ numEmptyStreams++;
+ break;
+ }
+ case k7zIdEmptyFile:
+ {
+ RINOK(SzReadBoolVector(sd, numEmptyStreams, emptyFileVector, allocTemp->Alloc));
+ break;
+ }
+ default:
+ {
+ RINOK(SzSkeepDataSize(sd, size));
+ }
+ }
+ }
+
+ {
+ UInt32 emptyFileIndex = 0;
+ UInt32 sizeIndex = 0;
+ for(i = 0; i < numFiles; i++)
+ {
+ CFileItem *file = files + i;
+ file->IsAnti = 0;
+ if (*emptyStreamVector == 0)
+ file->HasStream = 1;
+ else
+ file->HasStream = (Byte)((*emptyStreamVector)[i] ? 0 : 1);
+ if(file->HasStream)
+ {
+ file->IsDirectory = 0;
+ file->Size = (*unPackSizes)[sizeIndex];
+ file->FileCRC = (*digests)[sizeIndex];
+ file->IsFileCRCDefined = (Byte)(*digestsDefined)[sizeIndex];
+ sizeIndex++;
+ }
+ else
+ {
+ if (*emptyFileVector == 0)
+ file->IsDirectory = 1;
+ else
+ file->IsDirectory = (Byte)((*emptyFileVector)[emptyFileIndex] ? 0 : 1);
+ emptyFileIndex++;
+ file->Size = 0;
+ file->IsFileCRCDefined = 0;
+ }
+ }
+ }
+ return SzArDbExFill(db, allocMain->Alloc);
+}
+
+SZ_RESULT SzReadHeader(
+ CSzData *sd,
+ CArchiveDatabaseEx *db,
+ ISzAlloc *allocMain,
+ ISzAlloc *allocTemp)
+{
+ CFileSize *unPackSizes = 0;
+ Byte *digestsDefined = 0;
+ UInt32 *digests = 0;
+ Byte *emptyStreamVector = 0;
+ Byte *emptyFileVector = 0;
+ SZ_RESULT res = SzReadHeader2(sd, db,
+ &unPackSizes, &digestsDefined, &digests,
+ &emptyStreamVector, &emptyFileVector,
+ allocMain, allocTemp);
+ allocTemp->Free(unPackSizes);
+ allocTemp->Free(digestsDefined);
+ allocTemp->Free(digests);
+ allocTemp->Free(emptyStreamVector);
+ allocTemp->Free(emptyFileVector);
+ return res;
+}
+
+SZ_RESULT SzReadAndDecodePackedStreams2(
+ ISzInStream *inStream,
+ CSzData *sd,
+ CSzByteBuffer *outBuffer,
+ CFileSize baseOffset,
+ CArchiveDatabase *db,
+ CFileSize **unPackSizes,
+ Byte **digestsDefined,
+ UInt32 **digests,
+ #ifndef _LZMA_IN_CB
+ Byte **inBuffer,
+ #endif
+ ISzAlloc *allocTemp)
+{
+
+ UInt32 numUnPackStreams = 0;
+ CFileSize dataStartPos;
+ CFolder *folder;
+ #ifndef _LZMA_IN_CB
+ CFileSize packSize = 0;
+ UInt32 i = 0;
+ #endif
+ CFileSize unPackSize;
+ size_t outRealSize;
+ SZ_RESULT res;
+
+ RINOK(SzReadStreamsInfo(sd, &dataStartPos, db,
+ &numUnPackStreams, unPackSizes, digestsDefined, digests,
+ allocTemp->Alloc, allocTemp));
+
+ dataStartPos += baseOffset;
+ if (db->NumFolders != 1)
+ return SZE_ARCHIVE_ERROR;
+
+ folder = db->Folders;
+ unPackSize = SzFolderGetUnPackSize(folder);
+
+ RINOK(inStream->Seek(inStream, dataStartPos));
+
+ #ifndef _LZMA_IN_CB
+ for (i = 0; i < db->NumPackStreams; i++)
+ packSize += db->PackSizes[i];
+
+ RINOK(MySzInAlloc((void **)inBuffer, (size_t)packSize, allocTemp->Alloc));
+
+ RINOK(SafeReadDirect(inStream, *inBuffer, (size_t)packSize));
+ #endif
+
+ if (!SzByteBufferCreate(outBuffer, (size_t)unPackSize, allocTemp->Alloc))
+ return SZE_OUTOFMEMORY;
+
+ res = SzDecode(db->PackSizes, folder,
+ #ifdef _LZMA_IN_CB
+ inStream,
+ #else
+ *inBuffer,
+ #endif
+ outBuffer->Items, (size_t)unPackSize,
+ &outRealSize, allocTemp);
+ RINOK(res)
+ if (outRealSize != (UInt32)unPackSize)
+ return SZE_FAIL;
+ if (folder->UnPackCRCDefined)
+ if (!CrcVerifyDigest(folder->UnPackCRC, outBuffer->Items, (size_t)unPackSize))
+ return SZE_FAIL;
+ return SZ_OK;
+}
+
+SZ_RESULT SzReadAndDecodePackedStreams(
+ ISzInStream *inStream,
+ CSzData *sd,
+ CSzByteBuffer *outBuffer,
+ CFileSize baseOffset,
+ ISzAlloc *allocTemp)
+{
+ CArchiveDatabase db;
+ CFileSize *unPackSizes = 0;
+ Byte *digestsDefined = 0;
+ UInt32 *digests = 0;
+ #ifndef _LZMA_IN_CB
+ Byte *inBuffer = 0;
+ #endif
+ SZ_RESULT res;
+ SzArchiveDatabaseInit(&db);
+ res = SzReadAndDecodePackedStreams2(inStream, sd, outBuffer, baseOffset,
+ &db, &unPackSizes, &digestsDefined, &digests,
+ #ifndef _LZMA_IN_CB
+ &inBuffer,
+ #endif
+ allocTemp);
+ SzArchiveDatabaseFree(&db, allocTemp->Free);
+ allocTemp->Free(unPackSizes);
+ allocTemp->Free(digestsDefined);
+ allocTemp->Free(digests);
+ #ifndef _LZMA_IN_CB
+ allocTemp->Free(inBuffer);
+ #endif
+ return res;
+}
+
+SZ_RESULT SzArchiveOpen2(
+ ISzInStream *inStream,
+ CArchiveDatabaseEx *db,
+ ISzAlloc *allocMain,
+ ISzAlloc *allocTemp)
+{
+ Byte signature[k7zSignatureSize];
+ Byte version;
+ UInt32 crcFromArchive;
+ UInt64 nextHeaderOffset;
+ UInt64 nextHeaderSize;
+ UInt32 nextHeaderCRC;
+ UInt32 crc;
+ CFileSize pos = 0;
+ CSzByteBuffer buffer;
+ CSzData sd;
+ SZ_RESULT res;
+
+ RINOK(SafeReadDirect(inStream, signature, k7zSignatureSize));
+
+ if (!TestSignatureCandidate(signature))
+ return SZE_ARCHIVE_ERROR;
+
+ /*
+ db.Clear();
+ db.ArchiveInfo.StartPosition = _arhiveBeginStreamPosition;
+ */
+ RINOK(SafeReadDirectByte(inStream, &version));
+ if (version != k7zMajorVersion)
+ return SZE_ARCHIVE_ERROR;
+ RINOK(SafeReadDirectByte(inStream, &version));
+
+ RINOK(SafeReadDirectUInt32(inStream, &crcFromArchive));
+
+ CrcInit(&crc);
+ RINOK(SafeReadDirectUInt64(inStream, &nextHeaderOffset));
+ CrcUpdateUInt64(&crc, nextHeaderOffset);
+ RINOK(SafeReadDirectUInt64(inStream, &nextHeaderSize));
+ CrcUpdateUInt64(&crc, nextHeaderSize);
+ RINOK(SafeReadDirectUInt32(inStream, &nextHeaderCRC));
+ CrcUpdateUInt32(&crc, nextHeaderCRC);
+
+ pos = k7zStartHeaderSize;
+ db->ArchiveInfo.StartPositionAfterHeader = pos;
+
+ if (CrcGetDigest(&crc) != crcFromArchive)
+ return SZE_ARCHIVE_ERROR;
+
+ if (nextHeaderSize == 0)
+ return SZ_OK;
+
+ RINOK(inStream->Seek(inStream, (CFileSize)(pos + nextHeaderOffset)));
+
+ if (!SzByteBufferCreate(&buffer, (size_t)nextHeaderSize, allocTemp->Alloc))
+ return SZE_OUTOFMEMORY;
+
+ res = SafeReadDirect(inStream, buffer.Items, (size_t)nextHeaderSize);
+ if (res == SZ_OK)
+ {
+ if (CrcVerifyDigest(nextHeaderCRC, buffer.Items, (UInt32)nextHeaderSize))
+ {
+ while (1)
+ {
+ UInt64 type;
+ sd.Data = buffer.Items;
+ sd.Size = buffer.Capacity;
+ res = SzReadID(&sd, &type);
+ if (res != SZ_OK)
+ break;
+ if (type == k7zIdHeader)
+ {
+ res = SzReadHeader(&sd, db, allocMain, allocTemp);
+ break;
+ }
+ if (type != k7zIdEncodedHeader)
+ {
+ res = SZE_ARCHIVE_ERROR;
+ break;
+ }
+ {
+ CSzByteBuffer outBuffer;
+ res = SzReadAndDecodePackedStreams(inStream, &sd, &outBuffer,
+ db->ArchiveInfo.StartPositionAfterHeader,
+ allocTemp);
+ if (res != SZ_OK)
+ {
+ SzByteBufferFree(&outBuffer, allocTemp->Free);
+ break;
+ }
+ SzByteBufferFree(&buffer, allocTemp->Free);
+ buffer.Items = outBuffer.Items;
+ buffer.Capacity = outBuffer.Capacity;
+ }
+ }
+ }
+ }
+ SzByteBufferFree(&buffer, allocTemp->Free);
+ return res;
+}
+
+SZ_RESULT SzArchiveOpen(
+ ISzInStream *inStream,
+ CArchiveDatabaseEx *db,
+ ISzAlloc *allocMain,
+ ISzAlloc *allocTemp)
+{
+ SZ_RESULT res = SzArchiveOpen2(inStream, db, allocMain, allocTemp);
+ if (res != SZ_OK)
+ SzArDbExFree(db, allocMain->Free);
+ return res;
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zIn.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zIn.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zIn.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zIn.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,55 @@
+/* 7zIn.h */
+
+#ifndef __7Z_IN_H
+#define __7Z_IN_H
+
+#include "7zHeader.h"
+#include "7zItem.h"
+#include "7zAlloc.h"
+
+typedef struct _CInArchiveInfo
+{
+ CFileSize StartPositionAfterHeader;
+ CFileSize DataStartPosition;
+}CInArchiveInfo;
+
+typedef struct _CArchiveDatabaseEx
+{
+ CArchiveDatabase Database;
+ CInArchiveInfo ArchiveInfo;
+ UInt32 *FolderStartPackStreamIndex;
+ CFileSize *PackStreamStartPositions;
+ UInt32 *FolderStartFileIndex;
+ UInt32 *FileIndexToFolderIndexMap;
+}CArchiveDatabaseEx;
+
+void SzArDbExInit(CArchiveDatabaseEx *db);
+void SzArDbExFree(CArchiveDatabaseEx *db, void (*freeFunc)(void *));
+CFileSize SzArDbGetFolderStreamPos(CArchiveDatabaseEx *db, UInt32 folderIndex, UInt32 indexInFolder);
+CFileSize SzArDbGetFolderFullPackSize(CArchiveDatabaseEx *db, UInt32 folderIndex);
+
+typedef struct _ISzInStream
+{
+ #ifdef _LZMA_IN_CB
+ SZ_RESULT (*Read)(
+ void *object, /* pointer to ISzInStream itself */
+ void **buffer, /* out: pointer to buffer with data */
+ size_t maxRequiredSize, /* max required size to read */
+ size_t *processedSize); /* real processed size.
+ processedSize can be less than maxRequiredSize.
+ If processedSize == 0, then there are no more
+ bytes in stream. */
+ #else
+ SZ_RESULT (*Read)(void *object, void *buffer, size_t size, size_t *processedSize);
+ #endif
+ SZ_RESULT (*Seek)(void *object, CFileSize pos);
+} ISzInStream;
+
+
+int SzArchiveOpen(
+ ISzInStream *inStream,
+ CArchiveDatabaseEx *db,
+ ISzAlloc *allocMain,
+ ISzAlloc *allocTemp);
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zItem.c squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zItem.c
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zItem.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zItem.c 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,133 @@
+/* 7zItem.c */
+
+#include "7zItem.h"
+#include "7zAlloc.h"
+
+void SzCoderInfoInit(CCoderInfo *coder)
+{
+ SzByteBufferInit(&coder->Properties);
+}
+
+void SzCoderInfoFree(CCoderInfo *coder, void (*freeFunc)(void *p))
+{
+ SzByteBufferFree(&coder->Properties, freeFunc);
+ SzCoderInfoInit(coder);
+}
+
+void SzFolderInit(CFolder *folder)
+{
+ folder->NumCoders = 0;
+ folder->Coders = 0;
+ folder->NumBindPairs = 0;
+ folder->BindPairs = 0;
+ folder->NumPackStreams = 0;
+ folder->PackStreams = 0;
+ folder->UnPackSizes = 0;
+ folder->UnPackCRCDefined = 0;
+ folder->UnPackCRC = 0;
+ folder->NumUnPackStreams = 0;
+}
+
+void SzFolderFree(CFolder *folder, void (*freeFunc)(void *p))
+{
+ UInt32 i;
+ for (i = 0; i < folder->NumCoders; i++)
+ SzCoderInfoFree(&folder->Coders[i], freeFunc);
+ freeFunc(folder->Coders);
+ freeFunc(folder->BindPairs);
+ freeFunc(folder->PackStreams);
+ freeFunc(folder->UnPackSizes);
+ SzFolderInit(folder);
+}
+
+UInt32 SzFolderGetNumOutStreams(CFolder *folder)
+{
+ UInt32 result = 0;
+ UInt32 i;
+ for (i = 0; i < folder->NumCoders; i++)
+ result += folder->Coders[i].NumOutStreams;
+ return result;
+}
+
+int SzFolderFindBindPairForInStream(CFolder *folder, UInt32 inStreamIndex)
+{
+ UInt32 i;
+ for(i = 0; i < folder->NumBindPairs; i++)
+ if (folder->BindPairs[i].InIndex == inStreamIndex)
+ return i;
+ return -1;
+}
+
+
+int SzFolderFindBindPairForOutStream(CFolder *folder, UInt32 outStreamIndex)
+{
+ UInt32 i;
+ for(i = 0; i < folder->NumBindPairs; i++)
+ if (folder->BindPairs[i].OutIndex == outStreamIndex)
+ return i;
+ return -1;
+}
+
+CFileSize SzFolderGetUnPackSize(CFolder *folder)
+{
+ int i = (int)SzFolderGetNumOutStreams(folder);
+ if (i == 0)
+ return 0;
+ for (i--; i >= 0; i--)
+ if (SzFolderFindBindPairForOutStream(folder, i) < 0)
+ return folder->UnPackSizes[i];
+ /* throw 1; */
+ return 0;
+}
+
+/*
+int FindPackStreamArrayIndex(int inStreamIndex) const
+{
+ for(int i = 0; i < PackStreams.Size(); i++)
+ if (PackStreams[i] == inStreamIndex)
+ return i;
+ return -1;
+}
+*/
+
+void SzFileInit(CFileItem *fileItem)
+{
+ fileItem->IsFileCRCDefined = 0;
+ fileItem->HasStream = 1;
+ fileItem->IsDirectory = 0;
+ fileItem->IsAnti = 0;
+ fileItem->Name = 0;
+}
+
+void SzFileFree(CFileItem *fileItem, void (*freeFunc)(void *p))
+{
+ freeFunc(fileItem->Name);
+ SzFileInit(fileItem);
+}
+
+void SzArchiveDatabaseInit(CArchiveDatabase *db)
+{
+ db->NumPackStreams = 0;
+ db->PackSizes = 0;
+ db->PackCRCsDefined = 0;
+ db->PackCRCs = 0;
+ db->NumFolders = 0;
+ db->Folders = 0;
+ db->NumFiles = 0;
+ db->Files = 0;
+}
+
+void SzArchiveDatabaseFree(CArchiveDatabase *db, void (*freeFunc)(void *))
+{
+ UInt32 i;
+ for (i = 0; i < db->NumFolders; i++)
+ SzFolderFree(&db->Folders[i], freeFunc);
+ for (i = 0; i < db->NumFiles; i++)
+ SzFileFree(&db->Files[i], freeFunc);
+ freeFunc(db->PackSizes);
+ freeFunc(db->PackCRCsDefined);
+ freeFunc(db->PackCRCs);
+ freeFunc(db->Folders);
+ freeFunc(db->Files);
+ SzArchiveDatabaseInit(db);
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zItem.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zItem.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zItem.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zItem.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,90 @@
+/* 7zItem.h */
+
+#ifndef __7Z_ITEM_H
+#define __7Z_ITEM_H
+
+#include "7zMethodID.h"
+#include "7zHeader.h"
+#include "7zBuffer.h"
+
+typedef struct _CCoderInfo
+{
+ UInt32 NumInStreams;
+ UInt32 NumOutStreams;
+ CMethodID MethodID;
+ CSzByteBuffer Properties;
+}CCoderInfo;
+
+void SzCoderInfoInit(CCoderInfo *coder);
+void SzCoderInfoFree(CCoderInfo *coder, void (*freeFunc)(void *p));
+
+typedef struct _CBindPair
+{
+ UInt32 InIndex;
+ UInt32 OutIndex;
+}CBindPair;
+
+typedef struct _CFolder
+{
+ UInt32 NumCoders;
+ CCoderInfo *Coders;
+ UInt32 NumBindPairs;
+ CBindPair *BindPairs;
+ UInt32 NumPackStreams;
+ UInt32 *PackStreams;
+ CFileSize *UnPackSizes;
+ int UnPackCRCDefined;
+ UInt32 UnPackCRC;
+
+ UInt32 NumUnPackStreams;
+}CFolder;
+
+void SzFolderInit(CFolder *folder);
+CFileSize SzFolderGetUnPackSize(CFolder *folder);
+int SzFolderFindBindPairForInStream(CFolder *folder, UInt32 inStreamIndex);
+UInt32 SzFolderGetNumOutStreams(CFolder *folder);
+CFileSize SzFolderGetUnPackSize(CFolder *folder);
+
+/* #define CArchiveFileTime UInt64 */
+
+typedef struct _CFileItem
+{
+ /*
+ CArchiveFileTime LastWriteTime;
+ CFileSize StartPos;
+ UInt32 Attributes;
+ */
+ CFileSize Size;
+ UInt32 FileCRC;
+ char *Name;
+
+ Byte IsFileCRCDefined;
+ Byte HasStream;
+ Byte IsDirectory;
+ Byte IsAnti;
+ /*
+ int AreAttributesDefined;
+ int IsLastWriteTimeDefined;
+ int IsStartPosDefined;
+ */
+}CFileItem;
+
+void SzFileInit(CFileItem *fileItem);
+
+typedef struct _CArchiveDatabase
+{
+ UInt32 NumPackStreams;
+ CFileSize *PackSizes;
+ Byte *PackCRCsDefined;
+ UInt32 *PackCRCs;
+ UInt32 NumFolders;
+ CFolder *Folders;
+ UInt32 NumFiles;
+ CFileItem *Files;
+}CArchiveDatabase;
+
+void SzArchiveDatabaseInit(CArchiveDatabase *db);
+void SzArchiveDatabaseFree(CArchiveDatabase *db, void (*freeFunc)(void *));
+
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zMain.c squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zMain.c
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zMain.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zMain.c 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,223 @@
+/*
+7zMain.c
+Test application for 7z Decoder
+LZMA SDK 4.26 Copyright (c) 1999-2005 Igor Pavlov (2005-08-02)
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "7zCrc.h"
+#include "7zIn.h"
+#include "7zExtract.h"
+
+typedef struct _CFileInStream
+{
+ ISzInStream InStream;
+ FILE *File;
+} CFileInStream;
+
+#ifdef _LZMA_IN_CB
+
+#define kBufferSize (1 << 12)
+Byte g_Buffer[kBufferSize];
+
+SZ_RESULT SzFileReadImp(void *object, void **buffer, size_t maxRequiredSize, size_t *processedSize)
+{
+ CFileInStream *s = (CFileInStream *)object;
+ size_t processedSizeLoc;
+ if (maxRequiredSize > kBufferSize)
+ maxRequiredSize = kBufferSize;
+ processedSizeLoc = fread(g_Buffer, 1, maxRequiredSize, s->File);
+ *buffer = g_Buffer;
+ if (processedSize != 0)
+ *processedSize = processedSizeLoc;
+ return SZ_OK;
+}
+
+#else
+
+SZ_RESULT SzFileReadImp(void *object, void *buffer, size_t size, size_t *processedSize)
+{
+ CFileInStream *s = (CFileInStream *)object;
+ size_t processedSizeLoc = fread(buffer, 1, size, s->File);
+ if (processedSize != 0)
+ *processedSize = processedSizeLoc;
+ return SZ_OK;
+}
+
+#endif
+
+SZ_RESULT SzFileSeekImp(void *object, CFileSize pos)
+{
+ CFileInStream *s = (CFileInStream *)object;
+ int res = fseek(s->File, (long)pos, SEEK_SET);
+ if (res == 0)
+ return SZ_OK;
+ return SZE_FAIL;
+}
+
+void PrintError(char *sz)
+{
+ printf("\nERROR: %s\n", sz);
+}
+
+int main(int numargs, char *args[])
+{
+ CFileInStream archiveStream;
+ CArchiveDatabaseEx db;
+ SZ_RESULT res;
+ ISzAlloc allocImp;
+ ISzAlloc allocTempImp;
+
+ printf("\n7z ANSI-C Decoder 4.30 Copyright (c) 1999-2005 Igor Pavlov 2005-11-20\n");
+ if (numargs == 1)
+ {
+ printf(
+ "\nUsage: 7zDec <command> <archive_name>\n\n"
+ "<Commands>\n"
+ " e: Extract files from archive\n"
+ " l: List contents of archive\n"
+ " t: Test integrity of archive\n");
+ return 0;
+ }
+ if (numargs < 3)
+ {
+ PrintError("incorrect command");
+ return 1;
+ }
+
+ archiveStream.File = fopen(args[2], "rb");
+ if (archiveStream.File == 0)
+ {
+ PrintError("can not open input file");
+ return 1;
+ }
+
+ archiveStream.InStream.Read = SzFileReadImp;
+ archiveStream.InStream.Seek = SzFileSeekImp;
+
+ allocImp.Alloc = SzAlloc;
+ allocImp.Free = SzFree;
+
+ allocTempImp.Alloc = SzAllocTemp;
+ allocTempImp.Free = SzFreeTemp;
+
+ InitCrcTable();
+ SzArDbExInit(&db);
+ res = SzArchiveOpen(&archiveStream.InStream, &db, &allocImp, &allocTempImp);
+ if (res == SZ_OK)
+ {
+ char *command = args[1];
+ int listCommand = 0;
+ int testCommand = 0;
+ int extractCommand = 0;
+ if (strcmp(command, "l") == 0)
+ listCommand = 1;
+ if (strcmp(command, "t") == 0)
+ testCommand = 1;
+ else if (strcmp(command, "e") == 0)
+ extractCommand = 1;
+
+ if (listCommand)
+ {
+ UInt32 i;
+ for (i = 0; i < db.Database.NumFiles; i++)
+ {
+ CFileItem *f = db.Database.Files + i;
+ printf("%10d %s\n", (int)f->Size, f->Name);
+ }
+ }
+ else if (testCommand || extractCommand)
+ {
+ UInt32 i;
+
+ // if you need cache, use these 3 variables.
+ // if you use external function, you can make these variable as static.
+ UInt32 blockIndex = 0xFFFFFFFF; // it can have any value before first call (if outBuffer = 0)
+ Byte *outBuffer = 0; // it must be 0 before first call for each new archive.
+ size_t outBufferSize = 0; // it can have any value before first call (if outBuffer = 0)
+
+ printf("\n");
+ for (i = 0; i < db.Database.NumFiles; i++)
+ {
+ size_t offset;
+ size_t outSizeProcessed;
+ CFileItem *f = db.Database.Files + i;
+ if (f->IsDirectory)
+ printf("Directory ");
+ else
+ printf(testCommand ?
+ "Testing ":
+ "Extracting");
+ printf(" %s", f->Name);
+ if (f->IsDirectory)
+ {
+ printf("\n");
+ continue;
+ }
+ res = SzExtract(&archiveStream.InStream, &db, i,
+ &blockIndex, &outBuffer, &outBufferSize,
+ &offset, &outSizeProcessed,
+ &allocImp, &allocTempImp);
+ if (res != SZ_OK)
+ break;
+ if (!testCommand)
+ {
+ FILE *outputHandle;
+ UInt32 processedSize;
+ char *fileName = f->Name;
+ size_t nameLen = strlen(f->Name);
+ for (; nameLen > 0; nameLen--)
+ if (f->Name[nameLen - 1] == '/')
+ {
+ fileName = f->Name + nameLen;
+ break;
+ }
+
+ outputHandle = fopen(fileName, "wb+");
+ if (outputHandle == 0)
+ {
+ PrintError("can not open output file");
+ res = SZE_FAIL;
+ break;
+ }
+ processedSize = fwrite(outBuffer + offset, 1, outSizeProcessed, outputHandle);
+ if (processedSize != outSizeProcessed)
+ {
+ PrintError("can not write output file");
+ res = SZE_FAIL;
+ break;
+ }
+ if (fclose(outputHandle))
+ {
+ PrintError("can not close output file");
+ res = SZE_FAIL;
+ break;
+ }
+ }
+ printf("\n");
+ }
+ allocImp.Free(outBuffer);
+ }
+ else
+ {
+ PrintError("incorrect command");
+ res = SZE_FAIL;
+ }
+ }
+ SzArDbExFree(&db, allocImp.Free);
+
+ fclose(archiveStream.File);
+ if (res == SZ_OK)
+ {
+ printf("\nEverything is Ok\n");
+ return 0;
+ }
+ if (res == SZE_OUTOFMEMORY)
+ PrintError("can not allocate memory");
+ else
+ printf("\nERROR #%d\n", res);
+ return 1;
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zMethodID.c squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zMethodID.c
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zMethodID.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zMethodID.c 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,14 @@
+/* 7zMethodID.c */
+
+#include "7zMethodID.h"
+
+int AreMethodsEqual(CMethodID *a1, CMethodID *a2)
+{
+ int i;
+ if (a1->IDSize != a2->IDSize)
+ return 0;
+ for (i = 0; i < a1->IDSize; i++)
+ if (a1->ID[i] != a2->ID[i])
+ return 0;
+ return 1;
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zMethodID.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zMethodID.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zMethodID.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zMethodID.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,18 @@
+/* 7zMethodID.h */
+
+#ifndef __7Z_METHOD_ID_H
+#define __7Z_METHOD_ID_H
+
+#include "7zTypes.h"
+
+#define kMethodIDSize 15
+
+typedef struct _CMethodID
+{
+ Byte ID[kMethodIDSize];
+ Byte IDSize;
+} CMethodID;
+
+int AreMethodsEqual(CMethodID *a1, CMethodID *a2);
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zTypes.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zTypes.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zTypes.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/7zTypes.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,61 @@
+/* 7zTypes.h */
+
+#ifndef __COMMON_TYPES_H
+#define __COMMON_TYPES_H
+
+#ifndef UInt32
+#ifdef _LZMA_UINT32_IS_ULONG
+#define UInt32 unsigned long
+#else
+#define UInt32 unsigned int
+#endif
+#endif
+
+#ifndef Byte
+#define Byte unsigned char
+#endif
+
+#ifndef UInt16
+#define UInt16 unsigned short
+#endif
+
+/* #define _SZ_NO_INT_64 */
+/* define it your compiler doesn't support long long int */
+
+#ifdef _SZ_NO_INT_64
+#define UInt64 unsigned long
+#else
+#ifdef _MSC_VER
+#define UInt64 unsigned __int64
+#else
+#define UInt64 unsigned long long int
+#endif
+#endif
+
+
+/* #define _SZ_FILE_SIZE_64 */
+/* Use _SZ_FILE_SIZE_64 if you need support for files larger than 4 GB*/
+
+#ifndef CFileSize
+#ifdef _SZ_FILE_SIZE_64
+#define CFileSize UInt64
+#else
+#define CFileSize UInt32
+#endif
+#endif
+
+#define SZ_RESULT int
+
+#define SZ_OK (0)
+#define SZE_DATA_ERROR (1)
+#define SZE_OUTOFMEMORY (2)
+#define SZE_CRC_ERROR (3)
+
+#define SZE_NOTIMPL (4)
+#define SZE_FAIL (5)
+
+#define SZE_ARCHIVE_ERROR (6)
+
+#define RINOK(x) { int __result_ = (x); if(__result_ != 0) return __result_; }
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/makefile squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/makefile
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/makefile 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/makefile 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,55 @@
+PROG = 7zDec.exe
+
+!IFNDEF O
+!IFDEF CPU
+O=$(CPU)
+!ELSE
+O=O
+!ENDIF
+!ENDIF
+
+CFLAGS = $(CFLAGS) -nologo -c -Fo$O/ -GS-
+CFLAGS_O1 = $(CFLAGS) -O1
+CFLAGS_O2 = $(CFLAGS) -O2
+
+LFLAGS = $(LFLAGS) -nologo -OPT:NOWIN98
+
+PROGPATH = $O\$(PROG)
+
+COMPL_O1 = $(CPP) $(CFLAGS_O1) $**
+COMPL_O2 = $(CPP) $(CFLAGS_O2) $**
+COMPL = $(CPP) $(CFLAGS_O1) $**
+
+
+7Z_OBJS = \
+ $O\7zAlloc.obj \
+ $O\7zBuffer.obj \
+ $O\7zCrc.obj \
+ $O\7zDecode.obj \
+ $O\7zExtract.obj \
+ $O\7zHeader.obj \
+ $O\7zIn.obj \
+ $O\7zItem.obj \
+ $O\7zMain.obj \
+ $O\7zMethodID.obj \
+
+OBJS = \
+ $(7Z_OBJS) \
+ $O\LzmaDecode.obj \
+
+all: $(PROGPATH)
+
+clean:
+ -del /Q $(PROGPATH) $O\*.exe $O\*.dll $O\*.obj $O\*.lib $O\*.exp $O\*.res $O\*.pch
+
+$O:
+ if not exist "$O" mkdir "$O"
+
+$(PROGPATH): $O $(OBJS)
+ link $(LFLAGS) -out:$(PROGPATH) $(OBJS) $(LIBS)
+
+
+$(7Z_OBJS): $(*B).c
+ $(COMPL)
+$O\LzmaDecode.obj: ../../Compress/LZMA_C/$(*B).c
+ $(COMPL_O2)
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/makefile.gcc squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/makefile.gcc
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Archive/7z_C/makefile.gcc 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Archive/7z_C/makefile.gcc 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,50 @@
+PROG = 7zDec
+CXX = g++
+LIB =
+RM = rm -f
+CFLAGS = -c -O2 -Wall
+
+OBJS = 7zAlloc.o 7zBuffer.o 7zCrc.o 7zDecode.o 7zExtract.o 7zHeader.o 7zIn.o 7zItem.o 7zMain.o 7zMethodID.o LzmaDecode.o
+
+all: $(PROG)
+
+$(PROG): $(OBJS)
+ $(CXX) -o $(PROG) $(LDFLAGS) $(OBJS) $(LIB)
+
+7zAlloc.o: 7zAlloc.c
+ $(CXX) $(CFLAGS) 7zAlloc.c
+
+7zBuffer.o: 7zBuffer.c
+ $(CXX) $(CFLAGS) 7zBuffer.c
+
+7zCrc.o: 7zCrc.c
+ $(CXX) $(CFLAGS) 7zCrc.c
+
+7zDecode.o: 7zDecode.c
+ $(CXX) $(CFLAGS) 7zDecode.c
+
+7zExtract.o: 7zExtract.c
+ $(CXX) $(CFLAGS) 7zExtract.c
+
+7zHeader.o: 7zHeader.c
+ $(CXX) $(CFLAGS) 7zHeader.c
+
+7zIn.o: 7zIn.c
+ $(CXX) $(CFLAGS) 7zIn.c
+
+7zItem.o: 7zItem.c
+ $(CXX) $(CFLAGS) 7zItem.c
+
+7zMain.o: 7zMain.c
+ $(CXX) $(CFLAGS) 7zMain.c
+
+7zMethodID.o: 7zMethodID.c
+ $(CXX) $(CFLAGS) 7zMethodID.c
+
+LzmaDecode.o: ../../Compress/LZMA_C/LzmaDecode.c
+ $(CXX) $(CFLAGS) ../../Compress/LZMA_C/LzmaDecode.c
+
+
+clean:
+ -$(RM) $(PROG) $(OBJS)
+
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Common/FileStreams.cpp squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Common/FileStreams.cpp
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Common/FileStreams.cpp 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Common/FileStreams.cpp 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,251 @@
+// FileStreams.cpp
+
+#include "StdAfx.h"
+
+#ifndef _WIN32
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#endif
+
+#include "FileStreams.h"
+
+static inline HRESULT ConvertBoolToHRESULT(bool result)
+{
+ // return result ? S_OK: E_FAIL;
+ #ifdef _WIN32
+ return result ? S_OK: (::GetLastError());
+ #else
+ return result ? S_OK: E_FAIL;
+ #endif
+}
+
+bool CInFileStream::Open(LPCTSTR fileName)
+{
+ return File.Open(fileName);
+}
+
+#ifdef _WIN32
+#ifndef _UNICODE
+bool CInFileStream::Open(LPCWSTR fileName)
+{
+ return File.Open(fileName);
+}
+#endif
+#endif
+
+STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ #ifdef _WIN32
+
+ UInt32 realProcessedSize;
+ bool result = File.ReadPart(data, size, realProcessedSize);
+ if(processedSize != NULL)
+ *processedSize = realProcessedSize;
+ return ConvertBoolToHRESULT(result);
+
+ #else
+
+ if(processedSize != NULL)
+ *processedSize = 0;
+ ssize_t res = File.Read(data, (size_t)size);
+ if (res == -1)
+ return E_FAIL;
+ if(processedSize != NULL)
+ *processedSize = (UInt32)res;
+ return S_OK;
+
+ #endif
+}
+
+#ifndef _WIN32_WCE
+STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ #ifdef _WIN32
+ UInt32 realProcessedSize;
+ BOOL res = ::ReadFile(GetStdHandle(STD_INPUT_HANDLE),
+ data, size, (DWORD *)&realProcessedSize, NULL);
+ if(processedSize != NULL)
+ *processedSize = realProcessedSize;
+ if (res == FALSE && GetLastError() == ERROR_BROKEN_PIPE)
+ return S_OK;
+ return ConvertBoolToHRESULT(res != FALSE);
+
+ #else
+
+ if(processedSize != NULL)
+ *processedSize = 0;
+ ssize_t res;
+ do
+ {
+ res = read(0, data, (size_t)size);
+ }
+ while (res < 0 && (errno == EINTR));
+ if (res == -1)
+ return E_FAIL;
+ if(processedSize != NULL)
+ *processedSize = (UInt32)res;
+ return S_OK;
+
+ #endif
+}
+
+#endif
+
+STDMETHODIMP CInFileStream::Seek(Int64 offset, UInt32 seekOrigin,
+ UInt64 *newPosition)
+{
+ if(seekOrigin >= 3)
+ return STG_E_INVALIDFUNCTION;
+
+ #ifdef _WIN32
+
+ UInt64 realNewPosition;
+ bool result = File.Seek(offset, seekOrigin, realNewPosition);
+ if(newPosition != NULL)
+ *newPosition = realNewPosition;
+ return ConvertBoolToHRESULT(result);
+
+ #else
+
+ off_t res = File.Seek(offset, seekOrigin);
+ if (res == -1)
+ return E_FAIL;
+ if(newPosition != NULL)
+ *newPosition = (UInt64)res;
+ return S_OK;
+
+ #endif
+}
+
+STDMETHODIMP CInFileStream::GetSize(UInt64 *size)
+{
+ return ConvertBoolToHRESULT(File.GetLength(*size));
+}
+
+
+//////////////////////////
+// COutFileStream
+
+bool COutFileStream::Create(LPCTSTR fileName, bool createAlways)
+{
+ return File.Create(fileName, createAlways);
+}
+
+#ifdef _WIN32
+#ifndef _UNICODE
+bool COutFileStream::Create(LPCWSTR fileName, bool createAlways)
+{
+ return File.Create(fileName, createAlways);
+}
+#endif
+#endif
+
+STDMETHODIMP COutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ #ifdef _WIN32
+
+ UInt32 realProcessedSize;
+ bool result = File.WritePart(data, size, realProcessedSize);
+ if(processedSize != NULL)
+ *processedSize = realProcessedSize;
+ return ConvertBoolToHRESULT(result);
+
+ #else
+
+ if(processedSize != NULL)
+ *processedSize = 0;
+ ssize_t res = File.Write(data, (size_t)size);
+ if (res == -1)
+ return E_FAIL;
+ if(processedSize != NULL)
+ *processedSize = (UInt32)res;
+ return S_OK;
+
+ #endif
+}
+
+STDMETHODIMP COutFileStream::Seek(Int64 offset, UInt32 seekOrigin,
+ UInt64 *newPosition)
+{
+ if(seekOrigin >= 3)
+ return STG_E_INVALIDFUNCTION;
+ #ifdef _WIN32
+
+ UInt64 realNewPosition;
+ bool result = File.Seek(offset, seekOrigin, realNewPosition);
+ if(newPosition != NULL)
+ *newPosition = realNewPosition;
+ return ConvertBoolToHRESULT(result);
+
+ #else
+
+ off_t res = File.Seek(offset, seekOrigin);
+ if (res == -1)
+ return E_FAIL;
+ if(newPosition != NULL)
+ *newPosition = (UInt64)res;
+ return S_OK;
+
+ #endif
+}
+
+STDMETHODIMP COutFileStream::SetSize(Int64 newSize)
+{
+ #ifdef _WIN32
+ UInt64 currentPos;
+ if(!File.Seek(0, FILE_CURRENT, currentPos))
+ return E_FAIL;
+ bool result = File.SetLength(newSize);
+ UInt64 currentPos2;
+ result = result && File.Seek(currentPos, currentPos2);
+ return result ? S_OK : E_FAIL;
+ #else
+ return E_FAIL;
+ #endif
+}
+
+#ifndef _WIN32_WCE
+STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ if(processedSize != NULL)
+ *processedSize = 0;
+
+ #ifdef _WIN32
+ UInt32 realProcessedSize;
+ BOOL res = TRUE;
+ if (size > 0)
+ {
+ // Seems that Windows doesn't like big amounts writing to stdout.
+ // So we limit portions by 32KB.
+ UInt32 sizeTemp = (1 << 15);
+ if (sizeTemp > size)
+ sizeTemp = size;
+ res = ::WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),
+ data, sizeTemp, (DWORD *)&realProcessedSize, NULL);
+ size -= realProcessedSize;
+ data = (const void *)((const Byte *)data + realProcessedSize);
+ if(processedSize != NULL)
+ *processedSize += realProcessedSize;
+ }
+ return ConvertBoolToHRESULT(res != FALSE);
+
+ #else
+
+ ssize_t res;
+ do
+ {
+ res = write(1, data, (size_t)size);
+ }
+ while (res < 0 && (errno == EINTR));
+ if (res == -1)
+ return E_FAIL;
+ if(processedSize != NULL)
+ *processedSize = (UInt32)res;
+ return S_OK;
+
+ return S_OK;
+ #endif
+}
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Common/FileStreams.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Common/FileStreams.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Common/FileStreams.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Common/FileStreams.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,98 @@
+// FileStreams.h
+
+#ifndef __FILESTREAMS_H
+#define __FILESTREAMS_H
+
+#ifdef _WIN32
+#include "../../Windows/FileIO.h"
+#else
+#include "../../Common/C_FileIO.h"
+#endif
+
+#include "../IStream.h"
+#include "../../Common/MyCom.h"
+
+class CInFileStream:
+ public IInStream,
+ public IStreamGetSize,
+ public CMyUnknownImp
+{
+public:
+ #ifdef _WIN32
+ NWindows::NFile::NIO::CInFile File;
+ #else
+ NC::NFile::NIO::CInFile File;
+ #endif
+ CInFileStream() {}
+ virtual ~CInFileStream() {}
+
+ bool Open(LPCTSTR fileName);
+ #ifdef _WIN32
+ #ifndef _UNICODE
+ bool Open(LPCWSTR fileName);
+ #endif
+ #endif
+
+ MY_UNKNOWN_IMP2(IInStream, IStreamGetSize)
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
+
+ STDMETHOD(GetSize)(UInt64 *size);
+};
+
+#ifndef _WIN32_WCE
+class CStdInFileStream:
+ public ISequentialInStream,
+ public CMyUnknownImp
+{
+public:
+ // HANDLE File;
+ // CStdInFileStream() File(INVALID_HANDLE_VALUE): {}
+ // void Open() { File = GetStdHandle(STD_INPUT_HANDLE); };
+ MY_UNKNOWN_IMP
+
+ virtual ~CStdInFileStream() {}
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+};
+#endif
+
+class COutFileStream:
+ public IOutStream,
+ public CMyUnknownImp
+{
+public:
+ #ifdef _WIN32
+ NWindows::NFile::NIO::COutFile File;
+ #else
+ NC::NFile::NIO::COutFile File;
+ #endif
+ virtual ~COutFileStream() {}
+ bool Create(LPCTSTR fileName, bool createAlways);
+ #ifdef _WIN32
+ #ifndef _UNICODE
+ bool Create(LPCWSTR fileName, bool createAlways);
+ #endif
+ #endif
+
+ MY_UNKNOWN_IMP1(IOutStream)
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
+ STDMETHOD(SetSize)(Int64 newSize);
+};
+
+#ifndef _WIN32_WCE
+class CStdOutFileStream:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP
+
+ virtual ~CStdOutFileStream() {}
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+};
+#endif
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Common/InBuffer.cpp squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Common/InBuffer.cpp
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Common/InBuffer.cpp 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Common/InBuffer.cpp 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,80 @@
+// InBuffer.cpp
+
+#include "StdAfx.h"
+
+#include "InBuffer.h"
+
+#include "../../Common/Alloc.h"
+
+CInBuffer::CInBuffer():
+ _buffer(0),
+ _bufferLimit(0),
+ _bufferBase(0),
+ _stream(0),
+ _bufferSize(0)
+{}
+
+bool CInBuffer::Create(UInt32 bufferSize)
+{
+ const UInt32 kMinBlockSize = 1;
+ if (bufferSize < kMinBlockSize)
+ bufferSize = kMinBlockSize;
+ if (_bufferBase != 0 && _bufferSize == bufferSize)
+ return true;
+ Free();
+ _bufferSize = bufferSize;
+ _bufferBase = (Byte *)::MidAlloc(bufferSize);
+ return (_bufferBase != 0);
+}
+
+void CInBuffer::Free()
+{
+ ::MidFree(_bufferBase);
+ _bufferBase = 0;
+}
+
+void CInBuffer::SetStream(ISequentialInStream *stream)
+{
+ _stream = stream;
+}
+
+void CInBuffer::Init()
+{
+ _processedSize = 0;
+ _buffer = _bufferBase;
+ _bufferLimit = _buffer;
+ _wasFinished = false;
+ #ifdef _NO_EXCEPTIONS
+ ErrorCode = S_OK;
+ #endif
+}
+
+bool CInBuffer::ReadBlock()
+{
+ #ifdef _NO_EXCEPTIONS
+ if (ErrorCode != S_OK)
+ return false;
+ #endif
+ if (_wasFinished)
+ return false;
+ _processedSize += (_buffer - _bufferBase);
+ UInt32 numProcessedBytes;
+ HRESULT result = _stream->Read(_bufferBase, _bufferSize, &numProcessedBytes);
+ #ifdef _NO_EXCEPTIONS
+ ErrorCode = result;
+ #else
+ if (result != S_OK)
+ throw CInBufferException(result);
+ #endif
+ _buffer = _bufferBase;
+ _bufferLimit = _buffer + numProcessedBytes;
+ _wasFinished = (numProcessedBytes == 0);
+ return (!_wasFinished);
+}
+
+Byte CInBuffer::ReadBlock2()
+{
+ if(!ReadBlock())
+ return 0xFF;
+ return *_buffer++;
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Common/InBuffer.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Common/InBuffer.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Common/InBuffer.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Common/InBuffer.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,76 @@
+// InBuffer.h
+
+#ifndef __INBUFFER_H
+#define __INBUFFER_H
+
+#include "../IStream.h"
+#include "../../Common/MyCom.h"
+
+#ifndef _NO_EXCEPTIONS
+class CInBufferException
+{
+public:
+ HRESULT ErrorCode;
+ CInBufferException(HRESULT errorCode): ErrorCode(errorCode) {}
+};
+#endif
+
+class CInBuffer
+{
+ Byte *_buffer;
+ Byte *_bufferLimit;
+ Byte *_bufferBase;
+ CMyComPtr<ISequentialInStream> _stream;
+ UInt64 _processedSize;
+ UInt32 _bufferSize;
+ bool _wasFinished;
+
+ bool ReadBlock();
+ Byte ReadBlock2();
+
+public:
+ #ifdef _NO_EXCEPTIONS
+ HRESULT ErrorCode;
+ #endif
+
+ CInBuffer();
+ ~CInBuffer() { Free(); }
+
+ bool Create(UInt32 bufferSize);
+ void Free();
+
+ void SetStream(ISequentialInStream *stream);
+ void Init();
+ void ReleaseStream() { _stream.Release(); }
+
+ bool ReadByte(Byte &b)
+ {
+ if(_buffer >= _bufferLimit)
+ if(!ReadBlock())
+ return false;
+ b = *_buffer++;
+ return true;
+ }
+ Byte ReadByte()
+ {
+ if(_buffer >= _bufferLimit)
+ return ReadBlock2();
+ return *_buffer++;
+ }
+ void ReadBytes(void *data, UInt32 size, UInt32 &processedSize)
+ {
+ for(processedSize = 0; processedSize < size; processedSize++)
+ if (!ReadByte(((Byte *)data)[processedSize]))
+ return;
+ }
+ bool ReadBytes(void *data, UInt32 size)
+ {
+ UInt32 processedSize;
+ ReadBytes(data, size, processedSize);
+ return (processedSize == size);
+ }
+ UInt64 GetProcessedSize() const { return _processedSize + (_buffer - _bufferBase); }
+ bool WasFinished() const { return _wasFinished; }
+};
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Common/OutBuffer.cpp squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Common/OutBuffer.cpp
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Common/OutBuffer.cpp 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Common/OutBuffer.cpp 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,117 @@
+// OutByte.cpp
+
+#include "StdAfx.h"
+
+#include "OutBuffer.h"
+
+#include "../../Common/Alloc.h"
+
+bool COutBuffer::Create(UInt32 bufferSize)
+{
+ const UInt32 kMinBlockSize = 1;
+ if (bufferSize < kMinBlockSize)
+ bufferSize = kMinBlockSize;
+ if (_buffer != 0 && _bufferSize == bufferSize)
+ return true;
+ Free();
+ _bufferSize = bufferSize;
+ _buffer = (Byte *)::MidAlloc(bufferSize);
+ return (_buffer != 0);
+}
+
+void COutBuffer::Free()
+{
+ ::MidFree(_buffer);
+ _buffer = 0;
+}
+
+void COutBuffer::SetStream(ISequentialOutStream *stream)
+{
+ _stream = stream;
+}
+
+void COutBuffer::Init()
+{
+ _streamPos = 0;
+ _limitPos = _bufferSize;
+ _pos = 0;
+ _processedSize = 0;
+ _overDict = false;
+ #ifdef _NO_EXCEPTIONS
+ ErrorCode = S_OK;
+ #endif
+}
+
+UInt64 COutBuffer::GetProcessedSize() const
+{
+ UInt64 res = _processedSize + _pos - _streamPos;
+ if (_streamPos > _pos)
+ res += _bufferSize;
+ return res;
+}
+
+
+HRESULT COutBuffer::FlushPart()
+{
+ // _streamPos < _bufferSize
+ UInt32 size = (_streamPos >= _pos) ? (_bufferSize - _streamPos) : (_pos - _streamPos);
+ HRESULT result = S_OK;
+ #ifdef _NO_EXCEPTIONS
+ if (ErrorCode != S_OK)
+ result = ErrorCode;
+ #endif
+ if (_buffer2 != 0)
+ {
+ memmove(_buffer2, _buffer + _streamPos, size);
+ _buffer2 += size;
+ }
+
+ if (_stream != 0
+ #ifdef _NO_EXCEPTIONS
+ && (ErrorCode != S_OK)
+ #endif
+ )
+ {
+ UInt32 processedSize = 0;
+ result = _stream->Write(_buffer + _streamPos, size, &processedSize);
+ size = processedSize;
+ }
+ _streamPos += size;
+ if (_streamPos == _bufferSize)
+ _streamPos = 0;
+ if (_pos == _bufferSize)
+ {
+ _overDict = true;
+ _pos = 0;
+ }
+ _limitPos = (_streamPos > _pos) ? _streamPos : _bufferSize;
+ _processedSize += size;
+ return result;
+}
+
+HRESULT COutBuffer::Flush()
+{
+ #ifdef _NO_EXCEPTIONS
+ if (ErrorCode != S_OK)
+ return ErrorCode;
+ #endif
+
+ while(_streamPos != _pos)
+ {
+ HRESULT result = FlushPart();
+ if (result != S_OK)
+ return result;
+ }
+ return S_OK;
+}
+
+void COutBuffer::FlushWithCheck()
+{
+ HRESULT result = FlushPart();
+ #ifdef _NO_EXCEPTIONS
+ ErrorCode = result;
+ #else
+ if (result != S_OK)
+ throw COutBufferException(result);
+ #endif
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Common/OutBuffer.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Common/OutBuffer.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Common/OutBuffer.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Common/OutBuffer.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,64 @@
+// OutBuffer.h
+
+#ifndef __OUTBUFFER_H
+#define __OUTBUFFER_H
+
+#include "../IStream.h"
+#include "../../Common/MyCom.h"
+
+#ifndef _NO_EXCEPTIONS
+struct COutBufferException
+{
+ HRESULT ErrorCode;
+ COutBufferException(HRESULT errorCode): ErrorCode(errorCode) {}
+};
+#endif
+
+class COutBuffer
+{
+protected:
+ Byte *_buffer;
+ UInt32 _pos;
+ UInt32 _limitPos;
+ UInt32 _streamPos;
+ UInt32 _bufferSize;
+ CMyComPtr<ISequentialOutStream> _stream;
+ UInt64 _processedSize;
+ Byte *_buffer2;
+ bool _overDict;
+
+ HRESULT FlushPart();
+ void FlushWithCheck();
+public:
+ #ifdef _NO_EXCEPTIONS
+ HRESULT ErrorCode;
+ #endif
+
+ COutBuffer(): _buffer(0), _pos(0), _stream(0), _buffer2(0) {}
+ ~COutBuffer() { Free(); }
+
+ bool Create(UInt32 bufferSize);
+ void Free();
+
+ void SetMemStream(Byte *buffer) { _buffer2 = buffer; }
+ void SetStream(ISequentialOutStream *stream);
+ void Init();
+ HRESULT Flush();
+ void ReleaseStream() { _stream.Release(); }
+
+ void WriteByte(Byte b)
+ {
+ _buffer[_pos++] = b;
+ if(_pos == _limitPos)
+ FlushWithCheck();
+ }
+ void WriteBytes(const void *data, size_t size)
+ {
+ for (size_t i = 0; i < size; i++)
+ WriteByte(((const Byte *)data)[i]);
+ }
+
+ UInt64 GetProcessedSize() const;
+};
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Common/StdAfx.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Common/StdAfx.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Common/StdAfx.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Common/StdAfx.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,9 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../Common/MyWindows.h"
+#include "../../Common/NewHandler.h"
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Common/StreamUtils.cpp squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Common/StreamUtils.cpp
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Common/StreamUtils.cpp 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Common/StreamUtils.cpp 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,44 @@
+// StreamUtils.cpp
+
+#include "StdAfx.h"
+
+#include "../../Common/MyCom.h"
+#include "StreamUtils.h"
+
+HRESULT ReadStream(ISequentialInStream *stream, void *data, UInt32 size, UInt32 *processedSize)
+{
+ if (processedSize != 0)
+ *processedSize = 0;
+ while(size != 0)
+ {
+ UInt32 processedSizeLoc;
+ HRESULT res = stream->Read(data, size, &processedSizeLoc);
+ if (processedSize != 0)
+ *processedSize += processedSizeLoc;
+ data = (Byte *)((Byte *)data + processedSizeLoc);
+ size -= processedSizeLoc;
+ RINOK(res);
+ if (processedSizeLoc == 0)
+ return S_OK;
+ }
+ return S_OK;
+}
+
+HRESULT WriteStream(ISequentialOutStream *stream, const void *data, UInt32 size, UInt32 *processedSize)
+{
+ if (processedSize != 0)
+ *processedSize = 0;
+ while(size != 0)
+ {
+ UInt32 processedSizeLoc;
+ HRESULT res = stream->Write(data, size, &processedSizeLoc);
+ if (processedSize != 0)
+ *processedSize += processedSizeLoc;
+ data = (const void *)((const Byte *)data + processedSizeLoc);
+ size -= processedSizeLoc;
+ RINOK(res);
+ if (processedSizeLoc == 0)
+ break;
+ }
+ return S_OK;
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Common/StreamUtils.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Common/StreamUtils.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Common/StreamUtils.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Common/StreamUtils.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,11 @@
+// StreamUtils.h
+
+#ifndef __STREAMUTILS_H
+#define __STREAMUTILS_H
+
+#include "../IStream.h"
+
+HRESULT ReadStream(ISequentialInStream *stream, void *data, UInt32 size, UInt32 *processedSize);
+HRESULT WriteStream(ISequentialOutStream *stream, const void *data, UInt32 size, UInt32 *processedSize);
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/ARM.cpp squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/ARM.cpp
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/ARM.cpp 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/ARM.cpp 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,16 @@
+// ARM.cpp
+
+#include "StdAfx.h"
+#include "ARM.h"
+
+#include "BranchARM.c"
+
+UInt32 CBC_ARM_Encoder::SubFilter(Byte *data, UInt32 size)
+{
+ return ::ARM_Convert(data, size, _bufferPos, 1);
+}
+
+UInt32 CBC_ARM_Decoder::SubFilter(Byte *data, UInt32 size)
+{
+ return ::ARM_Convert(data, size, _bufferPos, 0);
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/ARM.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/ARM.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/ARM.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/ARM.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,10 @@
+// ARM.h
+
+#ifndef __ARM_H
+#define __ARM_H
+
+#include "BranchCoder.h"
+
+MyClassA(BC_ARM, 0x05, 1)
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/ARMThumb.cpp squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/ARMThumb.cpp
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/ARMThumb.cpp 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/ARMThumb.cpp 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,16 @@
+// ARMThumb.cpp
+
+#include "StdAfx.h"
+#include "ARMThumb.h"
+
+#include "BranchARMThumb.c"
+
+UInt32 CBC_ARMThumb_Encoder::SubFilter(Byte *data, UInt32 size)
+{
+ return ::ARMThumb_Convert(data, size, _bufferPos, 1);
+}
+
+UInt32 CBC_ARMThumb_Decoder::SubFilter(Byte *data, UInt32 size)
+{
+ return ::ARMThumb_Convert(data, size, _bufferPos, 0);
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/ARMThumb.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/ARMThumb.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/ARMThumb.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/ARMThumb.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,10 @@
+// ARMThumb.h
+
+#ifndef __ARMTHUMB_H
+#define __ARMTHUMB_H
+
+#include "BranchCoder.h"
+
+MyClassA(BC_ARMThumb, 0x07, 1)
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchARM.c squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchARM.c
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchARM.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchARM.c 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,26 @@
+// BranchARM.c
+
+#include "BranchARM.h"
+
+UInt32 ARM_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding)
+{
+ UInt32 i;
+ for (i = 0; i + 4 <= size; i += 4)
+ {
+ if (data[i + 3] == 0xEB)
+ {
+ UInt32 src = (data[i + 2] << 16) | (data[i + 1] << 8) | (data[i + 0]);
+ src <<= 2;
+ UInt32 dest;
+ if (encoding)
+ dest = nowPos + i + 8 + src;
+ else
+ dest = src - (nowPos + i + 8);
+ dest >>= 2;
+ data[i + 2] = (dest >> 16);
+ data[i + 1] = (dest >> 8);
+ data[i + 0] = dest;
+ }
+ }
+ return i;
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchARM.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchARM.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchARM.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchARM.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,10 @@
+// BranchARM.h
+
+#ifndef __BRANCH_ARM_H
+#define __BRANCH_ARM_H
+
+#include "Common/Types.h"
+
+UInt32 ARM_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding);
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchARMThumb.c squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchARMThumb.c
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchARMThumb.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchARMThumb.c 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,35 @@
+// BranchARMThumb.c
+
+#include "BranchARMThumb.h"
+
+UInt32 ARMThumb_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding)
+{
+ UInt32 i;
+ for (i = 0; i + 4 <= size; i += 2)
+ {
+ if ((data[i + 1] & 0xF8) == 0xF0 &&
+ (data[i + 3] & 0xF8) == 0xF8)
+ {
+ UInt32 src =
+ ((data[i + 1] & 0x7) << 19) |
+ (data[i + 0] << 11) |
+ ((data[i + 3] & 0x7) << 8) |
+ (data[i + 2]);
+
+ src <<= 1;
+ UInt32 dest;
+ if (encoding)
+ dest = nowPos + i + 4 + src;
+ else
+ dest = src - (nowPos + i + 4);
+ dest >>= 1;
+
+ data[i + 1] = 0xF0 | ((dest >> 19) & 0x7);
+ data[i + 0] = (dest >> 11);
+ data[i + 3] = 0xF8 | ((dest >> 8) & 0x7);
+ data[i + 2] = (dest);
+ i += 2;
+ }
+ }
+ return i;
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchARMThumb.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchARMThumb.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchARMThumb.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchARMThumb.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,10 @@
+// BranchARMThumb.h
+
+#ifndef __BRANCH_ARM_THUMB_H
+#define __BRANCH_ARM_THUMB_H
+
+#include "Common/Types.h"
+
+UInt32 ARMThumb_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding);
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchCoder.cpp squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchCoder.cpp
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchCoder.cpp 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchCoder.cpp 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,18 @@
+// BranchCoder.cpp
+
+#include "StdAfx.h"
+#include "BranchCoder.h"
+
+STDMETHODIMP CBranchConverter::Init()
+{
+ _bufferPos = 0;
+ SubInit();
+ return S_OK;
+}
+
+STDMETHODIMP_(UInt32) CBranchConverter::Filter(Byte *data, UInt32 size)
+{
+ UInt32 processedSize = SubFilter(data, size);
+ _bufferPos += processedSize;
+ return processedSize;
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchCoder.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchCoder.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchCoder.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchCoder.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,54 @@
+// BranchCoder.h
+
+#ifndef __BRANCH_CODER_H
+#define __BRANCH_CODER_H
+
+#include "Common/MyCom.h"
+#include "Common/Types.h"
+#include "Common/Alloc.h"
+
+#include "../../ICoder.h"
+
+class CBranchConverter:
+ public ICompressFilter,
+ public CMyUnknownImp
+{
+protected:
+ UInt32 _bufferPos;
+ virtual void SubInit() {}
+ virtual UInt32 SubFilter(Byte *data, UInt32 size) = 0;
+public:
+ MY_UNKNOWN_IMP;
+ STDMETHOD(Init)();
+ STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
+};
+
+#define MyClassEncoderA(Name) class C ## Name: public CBranchConverter \
+ { public: UInt32 SubFilter(Byte *data, UInt32 size); };
+
+#define MyClassDecoderA(Name) class C ## Name: public CBranchConverter \
+ { public: UInt32 SubFilter(Byte *data, UInt32 size); };
+
+#define MyClassEncoderB(Name, ADD_ITEMS, ADD_INIT) class C ## Name: public CBranchConverter, public ADD_ITEMS \
+ { public: UInt32 SubFilter(Byte *data, UInt32 size); ADD_INIT};
+
+#define MyClassDecoderB(Name, ADD_ITEMS, ADD_INIT) class C ## Name: public CBranchConverter, public ADD_ITEMS \
+ { public: UInt32 SubFilter(Byte *data, UInt32 size); ADD_INIT};
+
+#define MyClass2b(Name, id, subId, encodingId) \
+DEFINE_GUID(CLSID_CCompressConvert ## Name, \
+0x23170F69, 0x40C1, 0x278B, 0x03, 0x03, id, subId, 0x00, 0x00, encodingId, 0x00);
+
+#define MyClassA(Name, id, subId) \
+MyClass2b(Name ## _Encoder, id, subId, 0x01) \
+MyClassEncoderA(Name ## _Encoder) \
+MyClass2b(Name ## _Decoder, id, subId, 0x00) \
+MyClassDecoderA(Name ## _Decoder)
+
+#define MyClassB(Name, id, subId, ADD_ITEMS, ADD_INIT) \
+MyClass2b(Name ## _Encoder, id, subId, 0x01) \
+MyClassEncoderB(Name ## _Encoder, ADD_ITEMS, ADD_INIT) \
+MyClass2b(Name ## _Decoder, id, subId, 0x00) \
+MyClassDecoderB(Name ## _Decoder, ADD_ITEMS, ADD_INIT)
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchIA64.c squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchIA64.c
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchIA64.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchIA64.c 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,65 @@
+// BranchIA64.c
+
+#include "BranchIA64.h"
+
+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
+};
+
+UInt32 IA64_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding)
+{
+ UInt32 i;
+ for (i = 0; i + 16 <= size; i += 16)
+ {
+ UInt32 instrTemplate = data[i] & 0x1F;
+ UInt32 mask = kBranchTable[instrTemplate];
+ UInt32 bitPos = 5;
+ for (int slot = 0; slot < 3; slot++, bitPos += 41)
+ {
+ if (((mask >> slot) & 1) == 0)
+ continue;
+ UInt32 bytePos = (bitPos >> 3);
+ UInt32 bitRes = bitPos & 0x7;
+ // UInt64 instruction = *(UInt64 *)(data + i + bytePos);
+ UInt64 instruction = 0;
+ int j;
+ for (j = 0; j < 6; j++)
+ instruction += (UInt64)(data[i + j + bytePos]) << (8 * j);
+
+ UInt64 instNorm = instruction >> bitRes;
+ if (((instNorm >> 37) & 0xF) == 0x5
+ && ((instNorm >> 9) & 0x7) == 0
+ // && (instNorm & 0x3F)== 0
+ )
+ {
+ UInt32 src = UInt32((instNorm >> 13) & 0xFFFFF);
+ src |= ((instNorm >> 36) & 1) << 20;
+
+ src <<= 4;
+
+ UInt32 dest;
+ if (encoding)
+ dest = nowPos + i + src;
+ else
+ dest = src - (nowPos + 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);
+ // *(UInt64 *)(data + i + bytePos) = instruction;
+ for (j = 0; j < 6; j++)
+ data[i + j + bytePos] = Byte(instruction >> (8 * j));
+ }
+ }
+ }
+ return i;
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchIA64.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchIA64.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchIA64.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchIA64.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,10 @@
+// BranchIA64.h
+
+#ifndef __BRANCH_IA64_H
+#define __BRANCH_IA64_H
+
+#include "Common/Types.h"
+
+UInt32 IA64_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding);
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchPPC.c squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchPPC.c
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchPPC.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchPPC.c 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,36 @@
+// BranchPPC.c
+
+#include "BranchPPC.h"
+
+UInt32 PPC_B_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding)
+{
+ UInt32 i;
+ for (i = 0; i + 4 <= size; i += 4)
+ {
+ // PowerPC branch 6(48) 24(Offset) 1(Abs) 1(Link)
+ if ((data[i] >> 2) == 0x12 &&
+ (
+ (data[i + 3] & 3) == 1
+ // || (data[i+3] & 3) == 3
+ )
+ )
+ {
+ UInt32 src = ((data[i + 0] & 3) << 24) |
+ (data[i + 1] << 16) |
+ (data[i + 2] << 8) |
+ (data[i + 3] & (~3));
+
+ UInt32 dest;
+ if (encoding)
+ dest = nowPos + i + src;
+ else
+ dest = src - (nowPos + i);
+ data[i + 0] = 0x48 | ((dest >> 24) & 0x3);
+ data[i + 1] = (dest >> 16);
+ data[i + 2] = (dest >> 8);
+ data[i + 3] &= 0x3;
+ data[i + 3] |= dest;
+ }
+ }
+ return i;
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchPPC.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchPPC.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchPPC.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchPPC.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,10 @@
+// BranchPPC.h
+
+#ifndef __BRANCH_PPC_H
+#define __BRANCH_PPC_H
+
+#include "Common/Types.h"
+
+UInt32 PPC_B_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding);
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchSPARC.c squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchSPARC.c
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchSPARC.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchSPARC.c 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,36 @@
+// BranchSPARC.c
+
+#include "BranchSPARC.h"
+
+UInt32 SPARC_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding)
+{
+ UInt32 i;
+ for (i = 0; i + 4 <= 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]);
+
+ src <<= 2;
+ UInt32 dest;
+ if (encoding)
+ dest = nowPos + i + src;
+ else
+ dest = src - (nowPos + 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;
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchSPARC.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchSPARC.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchSPARC.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchSPARC.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,10 @@
+// BranchSPARC.h
+
+#ifndef __BRANCH_SPARC_H
+#define __BRANCH_SPARC_H
+
+#include "Common/Types.h"
+
+UInt32 SPARC_B_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding);
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchX86.c squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchX86.c
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchX86.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchX86.c 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,101 @@
+/* BranchX86.c */
+
+#include "BranchX86.h"
+
+/*
+static int inline Test86MSByte(Byte b)
+{
+ return (b == 0 || b == 0xFF);
+}
+*/
+#define Test86MSByte(b) ((b) == 0 || (b) == 0xFF)
+
+const int kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0};
+const Byte kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3};
+
+/*
+void x86_Convert_Init(UInt32 *prevMask, UInt32 *prevPos)
+{
+ *prevMask = 0;
+ *prevPos = (UInt32)(-5);
+}
+*/
+
+UInt32 x86_Convert(Byte *buffer, UInt32 endPos, UInt32 nowPos,
+ UInt32 *prevMask, UInt32 *prevPos, int encoding)
+{
+ UInt32 bufferPos = 0;
+ UInt32 limit;
+
+ if (endPos < 5)
+ return 0;
+
+ if (nowPos - *prevPos > 5)
+ *prevPos = nowPos - 5;
+
+ limit = endPos - 5;
+ while(bufferPos <= limit)
+ {
+ Byte b = buffer[bufferPos];
+ UInt32 offset;
+ if (b != 0xE8 && b != 0xE9)
+ {
+ bufferPos++;
+ continue;
+ }
+ offset = (nowPos + bufferPos - *prevPos);
+ *prevPos = (nowPos + bufferPos);
+ if (offset > 5)
+ *prevMask = 0;
+ else
+ {
+ UInt32 i;
+ for (i = 0; i < offset; i++)
+ {
+ *prevMask &= 0x77;
+ *prevMask <<= 1;
+ }
+ }
+ b = buffer[bufferPos + 4];
+ if (Test86MSByte(b) && kMaskToAllowedStatus[(*prevMask >> 1) & 0x7] &&
+ (*prevMask >> 1) < 0x10)
+ {
+ UInt32 src =
+ ((UInt32)(b) << 24) |
+ ((UInt32)(buffer[bufferPos + 3]) << 16) |
+ ((UInt32)(buffer[bufferPos + 2]) << 8) |
+ (buffer[bufferPos + 1]);
+
+ UInt32 dest;
+ while(1)
+ {
+ UInt32 index;
+ if (encoding)
+ dest = (nowPos + bufferPos + 5) + src;
+ else
+ dest = src - (nowPos + bufferPos + 5);
+ if (*prevMask == 0)
+ break;
+ index = kMaskToBitNumber[*prevMask >> 1];
+ b = (Byte)(dest >> (24 - index * 8));
+ if (!Test86MSByte(b))
+ break;
+ src = dest ^ ((1 << (32 - index * 8)) - 1);
+ }
+ buffer[bufferPos + 4] = (Byte)(~(((dest >> 24) & 1) - 1));
+ buffer[bufferPos + 3] = (Byte)(dest >> 16);
+ buffer[bufferPos + 2] = (Byte)(dest >> 8);
+ buffer[bufferPos + 1] = (Byte)dest;
+ bufferPos += 5;
+ *prevMask = 0;
+ }
+ else
+ {
+ bufferPos++;
+ *prevMask |= 1;
+ if (Test86MSByte(b))
+ *prevMask |= 0x10;
+ }
+ }
+ return bufferPos;
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchX86.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchX86.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchX86.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/BranchX86.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,19 @@
+/* BranchX86.h */
+
+#ifndef __BRANCHX86_H
+#define __BRANCHX86_H
+
+#ifndef UInt32
+#define UInt32 unsigned int
+#endif
+
+#ifndef Byte
+#define Byte unsigned char
+#endif
+
+#define x86_Convert_Init(prevMask, prevPos) { prevMask = 0; prevPos = (UInt32)(-5); }
+
+UInt32 x86_Convert(Byte *buffer, UInt32 endPos, UInt32 nowPos,
+ UInt32 *prevMask, UInt32 *prevPos, int encoding);
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/IA64.cpp squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/IA64.cpp
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/IA64.cpp 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/IA64.cpp 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,16 @@
+// IA64.cpp
+
+#include "StdAfx.h"
+#include "IA64.h"
+
+#include "BranchIA64.c"
+
+UInt32 CBC_IA64_Encoder::SubFilter(Byte *data, UInt32 size)
+{
+ return ::IA64_Convert(data, size, _bufferPos, 1);
+}
+
+UInt32 CBC_IA64_Decoder::SubFilter(Byte *data, UInt32 size)
+{
+ return ::IA64_Convert(data, size, _bufferPos, 0);
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/IA64.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/IA64.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/IA64.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/IA64.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,10 @@
+// IA64.h
+
+#ifndef __IA64_H
+#define __IA64_H
+
+#include "BranchCoder.h"
+
+MyClassA(BC_IA64, 0x04, 1)
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/PPC.cpp squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/PPC.cpp
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/PPC.cpp 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/PPC.cpp 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,17 @@
+// PPC.cpp
+
+#include "StdAfx.h"
+#include "PPC.h"
+
+#include "Windows/Defs.h"
+#include "BranchPPC.c"
+
+UInt32 CBC_PPC_B_Encoder::SubFilter(Byte *data, UInt32 size)
+{
+ return ::PPC_B_Convert(data, size, _bufferPos, 1);
+}
+
+UInt32 CBC_PPC_B_Decoder::SubFilter(Byte *data, UInt32 size)
+{
+ return ::PPC_B_Convert(data, size, _bufferPos, 0);
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/PPC.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/PPC.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/PPC.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/PPC.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,10 @@
+// PPC.h
+
+#ifndef __PPC_H
+#define __PPC_H
+
+#include "BranchCoder.h"
+
+MyClassA(BC_PPC_B, 0x02, 5)
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/SPARC.cpp squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/SPARC.cpp
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/SPARC.cpp 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/SPARC.cpp 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,17 @@
+// SPARC.cpp
+
+#include "StdAfx.h"
+#include "SPARC.h"
+
+#include "Windows/Defs.h"
+#include "BranchSPARC.c"
+
+UInt32 CBC_SPARC_Encoder::SubFilter(Byte *data, UInt32 size)
+{
+ return ::SPARC_Convert(data, size, _bufferPos, 1);
+}
+
+UInt32 CBC_SPARC_Decoder::SubFilter(Byte *data, UInt32 size)
+{
+ return ::SPARC_Convert(data, size, _bufferPos, 0);
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/SPARC.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/SPARC.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/SPARC.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/SPARC.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,10 @@
+// SPARC.h
+
+#ifndef __SPARC_H
+#define __SPARC_H
+
+#include "BranchCoder.h"
+
+MyClassA(BC_SPARC, 0x08, 5)
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/StdAfx.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/StdAfx.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/StdAfx.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/StdAfx.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/x86_2.cpp squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/x86_2.cpp
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/x86_2.cpp 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/x86_2.cpp 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,412 @@
+// x86_2.cpp
+
+#include "StdAfx.h"
+#include "x86_2.h"
+
+#include "../../../Common/Alloc.h"
+
+static const int kBufferSize = 1 << 17;
+
+inline bool IsJcc(Byte b0, Byte b1)
+{
+ return (b0 == 0x0F && (b1 & 0xF0) == 0x80);
+}
+
+#ifndef EXTRACT_ONLY
+
+static bool inline Test86MSByte(Byte b)
+{
+ return (b == 0 || b == 0xFF);
+}
+
+bool CBCJ2_x86_Encoder::Create()
+{
+ if (!_mainStream.Create(1 << 16))
+ return false;
+ if (!_callStream.Create(1 << 20))
+ return false;
+ if (!_jumpStream.Create(1 << 20))
+ return false;
+ if (!_rangeEncoder.Create(1 << 20))
+ return false;
+ if (_buffer == 0)
+ {
+ _buffer = (Byte *)MidAlloc(kBufferSize);
+ if (_buffer == 0)
+ return false;
+ }
+ return true;
+}
+
+CBCJ2_x86_Encoder::~CBCJ2_x86_Encoder()
+{
+ ::MidFree(_buffer);
+}
+
+HRESULT CBCJ2_x86_Encoder::Flush()
+{
+ RINOK(_mainStream.Flush());
+ RINOK(_callStream.Flush());
+ RINOK(_jumpStream.Flush());
+ _rangeEncoder.FlushData();
+ return _rangeEncoder.FlushStream();
+}
+
+const UInt32 kDefaultLimit = (1 << 24);
+
+HRESULT CBCJ2_x86_Encoder::CodeReal(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 **outSizes,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress)
+{
+ if (numInStreams != 1 || numOutStreams != 4)
+ return E_INVALIDARG;
+
+ if (!Create())
+ return E_OUTOFMEMORY;
+
+ bool sizeIsDefined = false;
+ UInt64 inSize;
+ if (inSizes != NULL)
+ if (inSizes[0] != NULL)
+ {
+ inSize = *inSizes[0];
+ if (inSize <= kDefaultLimit)
+ sizeIsDefined = true;
+ }
+
+ ISequentialInStream *inStream = inStreams[0];
+
+ _mainStream.SetStream(outStreams[0]);
+ _mainStream.Init();
+ _callStream.SetStream(outStreams[1]);
+ _callStream.Init();
+ _jumpStream.SetStream(outStreams[2]);
+ _jumpStream.Init();
+ _rangeEncoder.SetStream(outStreams[3]);
+ _rangeEncoder.Init();
+ for (int i = 0; i < 256; i++)
+ _statusE8Encoder[i].Init();
+ _statusE9Encoder.Init();
+ _statusJccEncoder.Init();
+ CCoderReleaser releaser(this);
+
+ CMyComPtr<ICompressGetSubStreamSize> getSubStreamSize;
+ {
+ inStream->QueryInterface(IID_ICompressGetSubStreamSize, (void **)&getSubStreamSize);
+ }
+
+ UInt32 nowPos = 0;
+ UInt64 nowPos64 = 0;
+ UInt32 bufferPos = 0;
+
+ Byte prevByte = 0;
+
+ UInt64 subStreamIndex = 0;
+ UInt64 subStreamStartPos = 0;
+ UInt64 subStreamEndPos = 0;
+
+ while(true)
+ {
+ UInt32 processedSize = 0;
+ while(true)
+ {
+ UInt32 size = kBufferSize - (bufferPos + processedSize);
+ UInt32 processedSizeLoc;
+ if (size == 0)
+ break;
+ RINOK(inStream->Read(_buffer + bufferPos + processedSize, size, &processedSizeLoc));
+ if (processedSizeLoc == 0)
+ break;
+ processedSize += processedSizeLoc;
+ }
+ UInt32 endPos = bufferPos + processedSize;
+
+ if (endPos < 5)
+ {
+ // change it
+ for (bufferPos = 0; bufferPos < endPos; bufferPos++)
+ {
+ Byte b = _buffer[bufferPos];
+ _mainStream.WriteByte(b);
+ if (b == 0xE8)
+ _statusE8Encoder[prevByte].Encode(&_rangeEncoder, 0);
+ else if (b == 0xE9)
+ _statusE9Encoder.Encode(&_rangeEncoder, 0);
+ else if (IsJcc(prevByte, b))
+ _statusJccEncoder.Encode(&_rangeEncoder, 0);
+ prevByte = b;
+ }
+ return Flush();
+ }
+
+ bufferPos = 0;
+
+ UInt32 limit = endPos - 5;
+ while(bufferPos <= limit)
+ {
+ Byte b = _buffer[bufferPos];
+ _mainStream.WriteByte(b);
+ if (b != 0xE8 && b != 0xE9 && !IsJcc(prevByte, b))
+ {
+ bufferPos++;
+ prevByte = b;
+ continue;
+ }
+ Byte nextByte = _buffer[bufferPos + 4];
+ UInt32 src =
+ (UInt32(nextByte) << 24) |
+ (UInt32(_buffer[bufferPos + 3]) << 16) |
+ (UInt32(_buffer[bufferPos + 2]) << 8) |
+ (_buffer[bufferPos + 1]);
+ UInt32 dest = (nowPos + bufferPos + 5) + src;
+ // if (Test86MSByte(nextByte))
+ bool convert;
+ if (getSubStreamSize != NULL)
+ {
+ UInt64 currentPos = (nowPos64 + bufferPos);
+ while (subStreamEndPos < currentPos)
+ {
+ UInt64 subStreamSize;
+ HRESULT result = getSubStreamSize->GetSubStreamSize(subStreamIndex, &subStreamSize);
+ if (result == S_OK)
+ {
+ subStreamStartPos = subStreamEndPos;
+ subStreamEndPos += subStreamSize;
+ subStreamIndex++;
+ }
+ else if (result == S_FALSE || result == E_NOTIMPL)
+ {
+ getSubStreamSize.Release();
+ subStreamStartPos = 0;
+ subStreamEndPos = subStreamStartPos - 1;
+ }
+ else
+ return result;
+ }
+ if (getSubStreamSize == NULL)
+ {
+ if (sizeIsDefined)
+ convert = (dest < inSize);
+ else
+ convert = Test86MSByte(nextByte);
+ }
+ else if (subStreamEndPos - subStreamStartPos > kDefaultLimit)
+ convert = Test86MSByte(nextByte);
+ else
+ {
+ UInt64 dest64 = (currentPos + 5) + Int64(Int32(src));
+ convert = (dest64 >= subStreamStartPos && dest64 < subStreamEndPos);
+ }
+ }
+ else if (sizeIsDefined)
+ convert = (dest < inSize);
+ else
+ convert = Test86MSByte(nextByte);
+ if (convert)
+ {
+ if (b == 0xE8)
+ _statusE8Encoder[prevByte].Encode(&_rangeEncoder, 1);
+ else if (b == 0xE9)
+ _statusE9Encoder.Encode(&_rangeEncoder, 1);
+ else
+ _statusJccEncoder.Encode(&_rangeEncoder, 1);
+
+ bufferPos += 5;
+ if (b == 0xE8)
+ {
+ _callStream.WriteByte((Byte)(dest >> 24));
+ _callStream.WriteByte((Byte)(dest >> 16));
+ _callStream.WriteByte((Byte)(dest >> 8));
+ _callStream.WriteByte((Byte)(dest));
+ }
+ else
+ {
+ _jumpStream.WriteByte((Byte)(dest >> 24));
+ _jumpStream.WriteByte((Byte)(dest >> 16));
+ _jumpStream.WriteByte((Byte)(dest >> 8));
+ _jumpStream.WriteByte((Byte)(dest));
+ }
+ prevByte = nextByte;
+ }
+ else
+ {
+ if (b == 0xE8)
+ _statusE8Encoder[prevByte].Encode(&_rangeEncoder, 0);
+ else if (b == 0xE9)
+ _statusE9Encoder.Encode(&_rangeEncoder, 0);
+ else
+ _statusJccEncoder.Encode(&_rangeEncoder, 0);
+ bufferPos++;
+ prevByte = b;
+ }
+ }
+ nowPos += bufferPos;
+ nowPos64 += bufferPos;
+
+ if (progress != NULL)
+ {
+ RINOK(progress->SetRatioInfo(&nowPos64, NULL));
+ }
+
+ UInt32 i = 0;
+ while(bufferPos < endPos)
+ _buffer[i++] = _buffer[bufferPos++];
+ bufferPos = i;
+ }
+}
+
+STDMETHODIMP CBCJ2_x86_Encoder::Code(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 **outSizes,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress)
+{
+ try
+ {
+ return CodeReal(inStreams, inSizes, numInStreams,
+ outStreams, outSizes,numOutStreams, progress);
+ }
+ catch(const COutBufferException &e) { return e.ErrorCode; }
+ catch(...) { return S_FALSE; }
+}
+
+#endif
+
+HRESULT CBCJ2_x86_Decoder::CodeReal(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 **outSizes,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress)
+{
+ if (numInStreams != 4 || numOutStreams != 1)
+ return E_INVALIDARG;
+
+ if (!_mainInStream.Create(1 << 16))
+ return E_OUTOFMEMORY;
+ if (!_callStream.Create(1 << 20))
+ return E_OUTOFMEMORY;
+ if (!_jumpStream.Create(1 << 16))
+ return E_OUTOFMEMORY;
+ if (!_rangeDecoder.Create(1 << 20))
+ return E_OUTOFMEMORY;
+ if (!_outStream.Create(1 << 16))
+ return E_OUTOFMEMORY;
+
+ _mainInStream.SetStream(inStreams[0]);
+ _callStream.SetStream(inStreams[1]);
+ _jumpStream.SetStream(inStreams[2]);
+ _rangeDecoder.SetStream(inStreams[3]);
+ _outStream.SetStream(outStreams[0]);
+
+ _mainInStream.Init();
+ _callStream.Init();
+ _jumpStream.Init();
+ _rangeDecoder.Init();
+ _outStream.Init();
+
+ for (int i = 0; i < 256; i++)
+ _statusE8Decoder[i].Init();
+ _statusE9Decoder.Init();
+ _statusJccDecoder.Init();
+
+ CCoderReleaser releaser(this);
+
+ Byte prevByte = 0;
+ UInt32 processedBytes = 0;
+ while(true)
+ {
+ if (processedBytes > (1 << 20) && progress != NULL)
+ {
+ UInt64 nowPos64 = _outStream.GetProcessedSize();
+ RINOK(progress->SetRatioInfo(NULL, &nowPos64));
+ processedBytes = 0;
+ }
+ processedBytes++;
+ Byte b;
+ if (!_mainInStream.ReadByte(b))
+ return Flush();
+ _outStream.WriteByte(b);
+ if (b != 0xE8 && b != 0xE9 && !IsJcc(prevByte, b))
+ {
+ prevByte = b;
+ continue;
+ }
+ bool status;
+ if (b == 0xE8)
+ status = (_statusE8Decoder[prevByte].Decode(&_rangeDecoder) == 1);
+ else if (b == 0xE9)
+ status = (_statusE9Decoder.Decode(&_rangeDecoder) == 1);
+ else
+ status = (_statusJccDecoder.Decode(&_rangeDecoder) == 1);
+ if (status)
+ {
+ UInt32 src;
+ if (b == 0xE8)
+ {
+ Byte b0;
+ if(!_callStream.ReadByte(b0))
+ return S_FALSE;
+ src = ((UInt32)b0) << 24;
+ if(!_callStream.ReadByte(b0))
+ return S_FALSE;
+ src |= ((UInt32)b0) << 16;
+ if(!_callStream.ReadByte(b0))
+ return S_FALSE;
+ src |= ((UInt32)b0) << 8;
+ if(!_callStream.ReadByte(b0))
+ return S_FALSE;
+ src |= ((UInt32)b0);
+ }
+ else
+ {
+ Byte b0;
+ if(!_jumpStream.ReadByte(b0))
+ return S_FALSE;
+ src = ((UInt32)b0) << 24;
+ if(!_jumpStream.ReadByte(b0))
+ return S_FALSE;
+ src |= ((UInt32)b0) << 16;
+ if(!_jumpStream.ReadByte(b0))
+ return S_FALSE;
+ src |= ((UInt32)b0) << 8;
+ if(!_jumpStream.ReadByte(b0))
+ return S_FALSE;
+ src |= ((UInt32)b0);
+ }
+ UInt32 dest = src - (UInt32(_outStream.GetProcessedSize()) + 4) ;
+ _outStream.WriteByte((Byte)(dest));
+ _outStream.WriteByte((Byte)(dest >> 8));
+ _outStream.WriteByte((Byte)(dest >> 16));
+ _outStream.WriteByte((Byte)(dest >> 24));
+ prevByte = (dest >> 24);
+ processedBytes += 4;
+ }
+ else
+ prevByte = b;
+ }
+}
+
+STDMETHODIMP CBCJ2_x86_Decoder::Code(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 **outSizes,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress)
+{
+ try
+ {
+ return CodeReal(inStreams, inSizes, numInStreams,
+ outStreams, outSizes,numOutStreams, progress);
+ }
+ catch(const COutBufferException &e) { return e.ErrorCode; }
+ catch(...) { return S_FALSE; }
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/x86_2.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/x86_2.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/x86_2.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/x86_2.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,133 @@
+// x86_2.h
+
+#ifndef __BRANCH_X86_2_H
+#define __BRANCH_X86_2_H
+
+#include "../../../Common/MyCom.h"
+#include "../RangeCoder/RangeCoderBit.h"
+#include "../../ICoder.h"
+
+// {23170F69-40C1-278B-0303-010100000100}
+#define MyClass2_a(Name, id, subId, encodingId) \
+DEFINE_GUID(CLSID_CCompressConvert ## Name, \
+0x23170F69, 0x40C1, 0x278B, 0x03, 0x03, id, subId, 0x00, 0x00, encodingId, 0x00);
+
+#define MyClass_a(Name, id, subId) \
+MyClass2_a(Name ## _Encoder, id, subId, 0x01) \
+MyClass2_a(Name ## _Decoder, id, subId, 0x00)
+
+MyClass_a(BCJ2_x86, 0x01, 0x1B)
+
+const int kNumMoveBits = 5;
+
+#ifndef EXTRACT_ONLY
+
+class CBCJ2_x86_Encoder:
+ public ICompressCoder2,
+ public CMyUnknownImp
+{
+ Byte *_buffer;
+public:
+ CBCJ2_x86_Encoder(): _buffer(0) {};
+ ~CBCJ2_x86_Encoder();
+ bool Create();
+
+ COutBuffer _mainStream;
+ COutBuffer _callStream;
+ COutBuffer _jumpStream;
+ NCompress::NRangeCoder::CEncoder _rangeEncoder;
+ NCompress::NRangeCoder::CBitEncoder<kNumMoveBits> _statusE8Encoder[256];
+ NCompress::NRangeCoder::CBitEncoder<kNumMoveBits> _statusE9Encoder;
+ NCompress::NRangeCoder::CBitEncoder<kNumMoveBits> _statusJccEncoder;
+
+ HRESULT Flush();
+ void ReleaseStreams()
+ {
+ _mainStream.ReleaseStream();
+ _callStream.ReleaseStream();
+ _jumpStream.ReleaseStream();
+ _rangeEncoder.ReleaseStream();
+ }
+
+ class CCoderReleaser
+ {
+ CBCJ2_x86_Encoder *_coder;
+ public:
+ CCoderReleaser(CBCJ2_x86_Encoder *coder): _coder(coder) {}
+ ~CCoderReleaser() { _coder->ReleaseStreams(); }
+ };
+
+public:
+
+ MY_UNKNOWN_IMP
+
+ HRESULT CodeReal(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 **outSizes,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress);
+ STDMETHOD(Code)(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 **outSizes,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress);
+};
+
+#endif
+
+class CBCJ2_x86_Decoder:
+ public ICompressCoder2,
+ public CMyUnknownImp
+{
+public:
+ CInBuffer _mainInStream;
+ CInBuffer _callStream;
+ CInBuffer _jumpStream;
+ NCompress::NRangeCoder::CDecoder _rangeDecoder;
+ NCompress::NRangeCoder::CBitDecoder<kNumMoveBits> _statusE8Decoder[256];
+ NCompress::NRangeCoder::CBitDecoder<kNumMoveBits> _statusE9Decoder;
+ NCompress::NRangeCoder::CBitDecoder<kNumMoveBits> _statusJccDecoder;
+
+ COutBuffer _outStream;
+
+ void ReleaseStreams()
+ {
+ _mainInStream.ReleaseStream();
+ _callStream.ReleaseStream();
+ _jumpStream.ReleaseStream();
+ _rangeDecoder.ReleaseStream();
+ _outStream.ReleaseStream();
+ }
+
+ HRESULT Flush() { return _outStream.Flush(); }
+ class CCoderReleaser
+ {
+ CBCJ2_x86_Decoder *_coder;
+ public:
+ CCoderReleaser(CBCJ2_x86_Decoder *coder): _coder(coder) {}
+ ~CCoderReleaser() { _coder->ReleaseStreams(); }
+ };
+
+public:
+ MY_UNKNOWN_IMP
+ HRESULT CodeReal(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 **outSizes,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress);
+ STDMETHOD(Code)(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 **outSizes,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress);
+};
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/x86.cpp squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/x86.cpp
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/x86.cpp 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/x86.cpp 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,18 @@
+// x86.cpp
+
+#include "StdAfx.h"
+#include "x86.h"
+
+#include "Windows/Defs.h"
+
+#include "BranchX86.c"
+
+UInt32 CBCJ_x86_Encoder::SubFilter(Byte *data, UInt32 size)
+{
+ return ::x86_Convert(data, size, _bufferPos, &_prevMask, &_prevPos, 1);
+}
+
+UInt32 CBCJ_x86_Decoder::SubFilter(Byte *data, UInt32 size)
+{
+ return ::x86_Convert(data, size, _bufferPos, &_prevMask, &_prevPos, 0);
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/x86.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/x86.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/Branch/x86.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/Branch/x86.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,19 @@
+// x86.h
+
+#ifndef __X86_H
+#define __X86_H
+
+#include "BranchCoder.h"
+#include "BranchX86.h"
+
+struct CBranch86
+{
+ UInt32 _prevMask;
+ UInt32 _prevPos;
+ void x86Init() { x86_Convert_Init(_prevMask, _prevPos); }
+};
+
+MyClassB(BCJ_x86, 0x01, 3, CBranch86 ,
+ virtual void SubInit() { x86Init(); })
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/BinTree/BinTree2.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/BinTree/BinTree2.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/BinTree/BinTree2.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/BinTree/BinTree2.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,12 @@
+// BinTree2.h
+
+#ifndef __BINTREE2_H
+#define __BINTREE2_H
+
+#undef BT_NAMESPACE
+#define BT_NAMESPACE NBT2
+
+#include "BinTree.h"
+#include "BinTreeMain.h"
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/BinTree/BinTree3.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/BinTree/BinTree3.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/BinTree/BinTree3.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/BinTree/BinTree3.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,16 @@
+// BinTree3.h
+
+#ifndef __BINTREE3_H
+#define __BINTREE3_H
+
+#undef BT_NAMESPACE
+#define BT_NAMESPACE NBT3
+
+#define HASH_ARRAY_2
+
+#include "BinTree.h"
+#include "BinTreeMain.h"
+
+#undef HASH_ARRAY_2
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/BinTree/BinTree3Z.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/BinTree/BinTree3Z.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/BinTree/BinTree3Z.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/BinTree/BinTree3Z.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,16 @@
+// BinTree3Z.h
+
+#ifndef __BINTREE3Z_H
+#define __BINTREE3Z_H
+
+#undef BT_NAMESPACE
+#define BT_NAMESPACE NBT3Z
+
+#define HASH_ZIP
+
+#include "BinTree.h"
+#include "BinTreeMain.h"
+
+#undef HASH_ZIP
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/BinTree/BinTree4b.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/BinTree/BinTree4b.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/BinTree/BinTree4b.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/BinTree/BinTree4b.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,20 @@
+// BinTree4b.h
+
+#ifndef __BINTREE4B_H
+#define __BINTREE4B_H
+
+#undef BT_NAMESPACE
+#define BT_NAMESPACE NBT4B
+
+#define HASH_ARRAY_2
+#define HASH_ARRAY_3
+#define HASH_BIG
+
+#include "BinTree.h"
+#include "BinTreeMain.h"
+
+#undef HASH_ARRAY_2
+#undef HASH_ARRAY_3
+#undef HASH_BIG
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/BinTree/BinTree4.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/BinTree/BinTree4.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/BinTree/BinTree4.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/BinTree/BinTree4.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,18 @@
+// BinTree4.h
+
+#ifndef __BINTREE4_H
+#define __BINTREE4_H
+
+#undef BT_NAMESPACE
+#define BT_NAMESPACE NBT4
+
+#define HASH_ARRAY_2
+#define HASH_ARRAY_3
+
+#include "BinTree.h"
+#include "BinTreeMain.h"
+
+#undef HASH_ARRAY_2
+#undef HASH_ARRAY_3
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/BinTree/BinTree.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/BinTree/BinTree.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/BinTree/BinTree.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/BinTree/BinTree.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,55 @@
+// BinTree.h
+
+#include "../LZInWindow.h"
+#include "../IMatchFinder.h"
+
+namespace BT_NAMESPACE {
+
+typedef UInt32 CIndex;
+const UInt32 kMaxValForNormalize = (UInt32(1) << 31) - 1;
+
+class CMatchFinderBinTree:
+ public IMatchFinder,
+ public IMatchFinderSetCallback,
+ public CLZInWindow,
+ public CMyUnknownImp
+{
+ UInt32 _cyclicBufferPos;
+ UInt32 _cyclicBufferSize; // it must be historySize + 1
+ UInt32 _matchMaxLen;
+ CIndex *_hash;
+ UInt32 _cutValue;
+
+ CMyComPtr<IMatchFinderCallback> m_Callback;
+
+ void Normalize();
+ void FreeThisClassMemory();
+ void FreeMemory();
+
+ MY_UNKNOWN_IMP1(IMatchFinderSetCallback)
+
+ STDMETHOD(Init)(ISequentialInStream *inStream);
+ STDMETHOD_(void, ReleaseStream)();
+ STDMETHOD(MovePos)();
+ STDMETHOD_(Byte, GetIndexByte)(Int32 index);
+ STDMETHOD_(UInt32, GetMatchLen)(Int32 index, UInt32 back, UInt32 limit);
+ STDMETHOD_(UInt32, GetNumAvailableBytes)();
+ STDMETHOD_(const Byte *, GetPointerToCurrentPos)();
+ STDMETHOD(Create)(UInt32 historySize, UInt32 keepAddBufferBefore,
+ UInt32 matchMaxLen, UInt32 keepAddBufferAfter);
+ STDMETHOD_(UInt32, GetLongestMatch)(UInt32 *distances);
+ STDMETHOD_(void, DummyLongestMatch)();
+
+ // IMatchFinderSetCallback
+ STDMETHOD(SetCallback)(IMatchFinderCallback *callback);
+
+ virtual void BeforeMoveBlock();
+ virtual void AfterMoveBlock();
+
+public:
+ CMatchFinderBinTree();
+ virtual ~CMatchFinderBinTree();
+ void SetCutValue(UInt32 cutValue) { _cutValue = cutValue; }
+};
+
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/BinTree/BinTreeMain.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/BinTree/BinTreeMain.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/BinTree/BinTreeMain.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/BinTree/BinTreeMain.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,444 @@
+// BinTreeMain.h
+
+#include "../../../../Common/Defs.h"
+#include "../../../../Common/CRC.h"
+#include "../../../../Common/Alloc.h"
+
+namespace BT_NAMESPACE {
+
+#ifdef HASH_ARRAY_2
+ static const UInt32 kHash2Size = 1 << 10;
+ #ifdef HASH_ARRAY_3
+ static const UInt32 kNumHashDirectBytes = 0;
+ static const UInt32 kNumHashBytes = 4;
+ static const UInt32 kHash3Size = 1 << 18;
+ #ifdef HASH_BIG
+ static const UInt32 kHashSize = 1 << 23;
+ #else
+ static const UInt32 kHashSize = 1 << 20;
+ #endif
+ #else
+ static const UInt32 kNumHashDirectBytes = 3;
+ static const UInt32 kNumHashBytes = 3;
+ static const UInt32 kHashSize = 1 << (8 * kNumHashBytes);
+ #endif
+#else
+ #ifdef HASH_ZIP
+ static const UInt32 kNumHashDirectBytes = 0;
+ static const UInt32 kNumHashBytes = 3;
+ static const UInt32 kHashSize = 1 << 16;
+ #else
+ #define THERE_ARE_DIRECT_HASH_BYTES
+ static const UInt32 kNumHashDirectBytes = 2;
+ static const UInt32 kNumHashBytes = 2;
+ static const UInt32 kHashSize = 1 << (8 * kNumHashBytes);
+ #endif
+#endif
+
+static const UInt32 kHashSizeSum = kHashSize
+ #ifdef HASH_ARRAY_2
+ + kHash2Size
+ #ifdef HASH_ARRAY_3
+ + kHash3Size
+ #endif
+ #endif
+ ;
+
+#ifdef HASH_ARRAY_2
+static const UInt32 kHash2Offset = kHashSize;
+#ifdef HASH_ARRAY_3
+static const UInt32 kHash3Offset = kHashSize + kHash2Size;
+#endif
+#endif
+
+CMatchFinderBinTree::CMatchFinderBinTree():
+ _hash(0),
+ _cutValue(0xFF)
+{
+}
+
+void CMatchFinderBinTree::FreeThisClassMemory()
+{
+ BigFree(_hash);
+ _hash = 0;
+}
+
+void CMatchFinderBinTree::FreeMemory()
+{
+ FreeThisClassMemory();
+ CLZInWindow::Free();
+}
+
+CMatchFinderBinTree::~CMatchFinderBinTree()
+{
+ FreeMemory();
+}
+
+STDMETHODIMP CMatchFinderBinTree::Create(UInt32 historySize, UInt32 keepAddBufferBefore,
+ UInt32 matchMaxLen, UInt32 keepAddBufferAfter)
+{
+ UInt32 sizeReserv = (historySize + keepAddBufferBefore +
+ matchMaxLen + keepAddBufferAfter) / 2 + 256;
+ if (CLZInWindow::Create(historySize + keepAddBufferBefore,
+ matchMaxLen + keepAddBufferAfter, sizeReserv))
+ {
+ if (historySize + 256 > kMaxValForNormalize)
+ {
+ FreeMemory();
+ return E_INVALIDARG;
+ }
+ _matchMaxLen = matchMaxLen;
+ UInt32 newCyclicBufferSize = historySize + 1;
+ if (_hash != 0 && newCyclicBufferSize == _cyclicBufferSize)
+ return S_OK;
+ FreeThisClassMemory();
+ _cyclicBufferSize = newCyclicBufferSize; // don't change it
+ _hash = (CIndex *)BigAlloc((kHashSizeSum + _cyclicBufferSize * 2) * sizeof(CIndex));
+ if (_hash != 0)
+ return S_OK;
+ }
+ FreeMemory();
+ return E_OUTOFMEMORY;
+}
+
+static const UInt32 kEmptyHashValue = 0;
+
+STDMETHODIMP CMatchFinderBinTree::Init(ISequentialInStream *stream)
+{
+ RINOK(CLZInWindow::Init(stream));
+ for(UInt32 i = 0; i < kHashSizeSum; i++)
+ _hash[i] = kEmptyHashValue;
+ _cyclicBufferPos = 0;
+ ReduceOffsets(-1);
+ return S_OK;
+}
+
+STDMETHODIMP_(void) CMatchFinderBinTree::ReleaseStream()
+{
+ // ReleaseStream();
+}
+
+#ifdef HASH_ARRAY_2
+#ifdef HASH_ARRAY_3
+inline UInt32 Hash(const Byte *pointer, UInt32 &hash2Value, UInt32 &hash3Value)
+{
+ UInt32 temp = CCRC::Table[pointer[0]] ^ pointer[1];
+ hash2Value = temp & (kHash2Size - 1);
+ hash3Value = (temp ^ (UInt32(pointer[2]) << 8)) & (kHash3Size - 1);
+ return (temp ^ (UInt32(pointer[2]) << 8) ^ (CCRC::Table[pointer[3]] << 5)) &
+ (kHashSize - 1);
+}
+#else // no HASH_ARRAY_3
+inline UInt32 Hash(const Byte *pointer, UInt32 &hash2Value)
+{
+ hash2Value = (CCRC::Table[pointer[0]] ^ pointer[1]) & (kHash2Size - 1);
+ return ((UInt32(pointer[0]) << 16)) | ((UInt32(pointer[1]) << 8)) | pointer[2];
+}
+#endif // HASH_ARRAY_3
+#else // no HASH_ARRAY_2
+#ifdef HASH_ZIP
+inline UInt32 Hash(const Byte *pointer)
+{
+ return ((UInt32(pointer[0]) << 8) ^
+ CCRC::Table[pointer[1]] ^ pointer[2]) & (kHashSize - 1);
+}
+#else // no HASH_ZIP
+inline UInt32 Hash(const Byte *pointer)
+{
+ return pointer[0] ^ (UInt32(pointer[1]) << 8);
+}
+#endif // HASH_ZIP
+#endif // HASH_ARRAY_2
+
+STDMETHODIMP_(UInt32) CMatchFinderBinTree::GetLongestMatch(UInt32 *distances)
+{
+ UInt32 lenLimit;
+ if (_pos + _matchMaxLen <= _streamPos)
+ lenLimit = _matchMaxLen;
+ else
+ {
+ lenLimit = _streamPos - _pos;
+ if(lenLimit < kNumHashBytes)
+ return 0;
+ }
+
+ UInt32 matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0;
+ Byte *cur = _buffer + _pos;
+
+ UInt32 maxLen = 0;
+
+ #ifdef HASH_ARRAY_2
+ UInt32 hash2Value;
+ #ifdef HASH_ARRAY_3
+ UInt32 hash3Value;
+ UInt32 hashValue = Hash(cur, hash2Value, hash3Value);
+ #else
+ UInt32 hashValue = Hash(cur, hash2Value);
+ #endif
+ #else
+ UInt32 hashValue = Hash(cur);
+ #endif
+
+ UInt32 curMatch = _hash[hashValue];
+ #ifdef HASH_ARRAY_2
+ UInt32 curMatch2 = _hash[kHash2Offset + hash2Value];
+ #ifdef HASH_ARRAY_3
+ UInt32 curMatch3 = _hash[kHash3Offset + hash3Value];
+ #endif
+ _hash[kHash2Offset + hash2Value] = _pos;
+ distances[2] = 0xFFFFFFFF;
+ if(curMatch2 > matchMinPos)
+ if (_buffer[curMatch2] == cur[0])
+ {
+ distances[2] = _pos - curMatch2 - 1;
+ maxLen = 2;
+ }
+
+ #ifdef HASH_ARRAY_3
+ _hash[kHash3Offset + hash3Value] = _pos;
+ distances[3] = 0xFFFFFFFF;
+ if(curMatch3 > matchMinPos)
+ if (_buffer[curMatch3] == cur[0])
+ {
+ distances[3] = _pos - curMatch3 - 1;
+ maxLen = 3;
+ }
+ #endif
+ #endif
+
+ _hash[hashValue] = _pos;
+
+ CIndex *son = _hash + kHashSizeSum;
+ CIndex *ptr0 = son + (_cyclicBufferPos << 1) + 1;
+ CIndex *ptr1 = son + (_cyclicBufferPos << 1);
+
+ distances[kNumHashBytes] = 0xFFFFFFFF;
+
+ #ifdef THERE_ARE_DIRECT_HASH_BYTES
+ if (lenLimit == kNumHashDirectBytes)
+ {
+ if(curMatch > matchMinPos)
+ while (maxLen < kNumHashDirectBytes)
+ distances[++maxLen] = _pos - curMatch - 1;
+ // We don't need tree in this case
+ }
+ else
+ #endif
+ {
+ UInt32 len0, len1;
+ len0 = len1 = kNumHashDirectBytes;
+ UInt32 count = _cutValue;
+ while(true)
+ {
+ if(curMatch <= matchMinPos || count-- == 0)
+ {
+ *ptr0 = kEmptyHashValue;
+ *ptr1 = kEmptyHashValue;
+ break;
+ }
+ Byte *pb = _buffer + curMatch;
+ UInt32 len = MyMin(len0, len1);
+ do
+ {
+ if (pb[len] != cur[len])
+ break;
+ }
+ while(++len != lenLimit);
+
+ UInt32 delta = _pos - curMatch;
+ while (maxLen < len)
+ distances[++maxLen] = delta - 1;
+
+ UInt32 cyclicPos = (delta <= _cyclicBufferPos) ?
+ (_cyclicBufferPos - delta):
+ (_cyclicBufferPos - delta + _cyclicBufferSize);
+ CIndex *pair = son + (cyclicPos << 1);
+
+ if (len != lenLimit)
+ {
+ if (pb[len] < cur[len])
+ {
+ *ptr1 = curMatch;
+ ptr1 = pair + 1;
+ curMatch = *ptr1;
+ len1 = len;
+ }
+ else
+ {
+ *ptr0 = curMatch;
+ ptr0 = pair;
+ curMatch = *ptr0;
+ len0 = len;
+ }
+ }
+ else
+ {
+ *ptr1 = pair[0];
+ *ptr0 = pair[1];
+ break;
+ }
+ }
+ }
+ #ifdef HASH_ARRAY_2
+ #ifdef HASH_ARRAY_3
+ if (distances[4] < distances[3])
+ distances[3] = distances[4];
+ #endif
+ if (distances[3] < distances[2])
+ distances[2] = distances[3];
+ #endif
+ return maxLen;
+}
+
+STDMETHODIMP_(void) CMatchFinderBinTree::DummyLongestMatch()
+{
+ UInt32 lenLimit;
+ if (_pos + _matchMaxLen <= _streamPos)
+ lenLimit = _matchMaxLen;
+ else
+ {
+ lenLimit = _streamPos - _pos;
+ if(lenLimit < kNumHashBytes)
+ return;
+ }
+ UInt32 matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0;
+ Byte *cur = _buffer + _pos;
+
+ #ifdef HASH_ARRAY_2
+ UInt32 hash2Value;
+ #ifdef HASH_ARRAY_3
+ UInt32 hash3Value;
+ UInt32 hashValue = Hash(cur, hash2Value, hash3Value);
+ _hash[kHash3Offset + hash3Value] = _pos;
+ #else
+ UInt32 hashValue = Hash(cur, hash2Value);
+ #endif
+ _hash[kHash2Offset + hash2Value] = _pos;
+ #else
+ UInt32 hashValue = Hash(cur);
+ #endif
+
+ UInt32 curMatch = _hash[hashValue];
+ _hash[hashValue] = _pos;
+
+ CIndex *son = _hash + kHashSizeSum;
+ CIndex *ptr0 = son + (_cyclicBufferPos << 1) + 1;
+ CIndex *ptr1 = son + (_cyclicBufferPos << 1);
+
+ #ifdef THERE_ARE_DIRECT_HASH_BYTES
+ if (lenLimit != kNumHashDirectBytes)
+ #endif
+ {
+ UInt32 len0, len1;
+ len0 = len1 = kNumHashDirectBytes;
+ UInt32 count = _cutValue;
+ while(true)
+ {
+ if(curMatch <= matchMinPos || count-- == 0)
+ break;
+ Byte *pb = _buffer + curMatch;
+ UInt32 len = MyMin(len0, len1);
+ do
+ {
+ if (pb[len] != cur[len])
+ break;
+ }
+ while(++len != lenLimit);
+
+ UInt32 delta = _pos - curMatch;
+ UInt32 cyclicPos = (delta <= _cyclicBufferPos) ?
+ (_cyclicBufferPos - delta):
+ (_cyclicBufferPos - delta + _cyclicBufferSize);
+ CIndex *pair = son + (cyclicPos << 1);
+
+ if (len != lenLimit)
+ {
+ if (pb[len] < cur[len])
+ {
+ *ptr1 = curMatch;
+ ptr1 = pair + 1;
+ curMatch = *ptr1;
+ len1 = len;
+ }
+ else
+ {
+ *ptr0 = curMatch;
+ ptr0 = pair;
+ curMatch = *ptr0;
+ len0 = len;
+ }
+ }
+ else
+ {
+ *ptr1 = pair[0];
+ *ptr0 = pair[1];
+ return;
+ }
+ }
+ }
+ *ptr0 = kEmptyHashValue;
+ *ptr1 = kEmptyHashValue;
+}
+
+void CMatchFinderBinTree::Normalize()
+{
+ UInt32 subValue = _pos - _cyclicBufferSize;
+ CIndex *items = _hash;
+ UInt32 numItems = (kHashSizeSum + _cyclicBufferSize * 2);
+ for (UInt32 i = 0; i < numItems; i++)
+ {
+ UInt32 value = items[i];
+ if (value <= subValue)
+ value = kEmptyHashValue;
+ else
+ value -= subValue;
+ items[i] = value;
+ }
+ ReduceOffsets(subValue);
+}
+
+STDMETHODIMP CMatchFinderBinTree::MovePos()
+{
+ if (++_cyclicBufferPos == _cyclicBufferSize)
+ _cyclicBufferPos = 0;
+ RINOK(CLZInWindow::MovePos());
+ if (_pos == kMaxValForNormalize)
+ Normalize();
+ return S_OK;
+}
+
+STDMETHODIMP_(Byte) CMatchFinderBinTree::GetIndexByte(Int32 index)
+ { return CLZInWindow::GetIndexByte(index); }
+
+STDMETHODIMP_(UInt32) CMatchFinderBinTree::GetMatchLen(Int32 index,
+ UInt32 back, UInt32 limit)
+ { return CLZInWindow::GetMatchLen(index, back, limit); }
+
+STDMETHODIMP_(UInt32) CMatchFinderBinTree::GetNumAvailableBytes()
+ { return CLZInWindow::GetNumAvailableBytes(); }
+
+STDMETHODIMP_(const Byte *) CMatchFinderBinTree::GetPointerToCurrentPos()
+ { return CLZInWindow::GetPointerToCurrentPos(); }
+
+// IMatchFinderSetCallback
+STDMETHODIMP CMatchFinderBinTree::SetCallback(IMatchFinderCallback *callback)
+{
+ m_Callback = callback;
+ return S_OK;
+}
+
+void CMatchFinderBinTree::BeforeMoveBlock()
+{
+ if (m_Callback)
+ m_Callback->BeforeChangingBufferPos();
+ CLZInWindow::BeforeMoveBlock();
+}
+
+void CMatchFinderBinTree::AfterMoveBlock()
+{
+ if (m_Callback)
+ m_Callback->AfterChangingBufferPos();
+ CLZInWindow::AfterMoveBlock();
+}
+
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/HashChain/HC2.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/HashChain/HC2.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/HashChain/HC2.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/HashChain/HC2.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,13 @@
+// HC2.h
+
+#ifndef __HC2_H
+#define __HC2_H
+
+#undef HC_NAMESPACE
+#define HC_NAMESPACE NHC2
+
+#include "HCMF.h"
+#include "HCMFMain.h"
+
+#endif
+
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/HashChain/HC3.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/HashChain/HC3.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/HashChain/HC3.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/HashChain/HC3.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,17 @@
+// HC3.h
+
+#ifndef __HC3_H
+#define __HC3_H
+
+#undef HC_NAMESPACE
+#define HC_NAMESPACE NHC3
+
+#define HASH_ARRAY_2
+
+#include "HC.h"
+#include "HCMain.h"
+
+#undef HASH_ARRAY_2
+
+#endif
+
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/HashChain/HC4b.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/HashChain/HC4b.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/HashChain/HC4b.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/HashChain/HC4b.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,21 @@
+// HC4b.h
+
+#ifndef __HC4B__H
+#define __HC4B__H
+
+#undef HC_NAMESPACE
+#define HC_NAMESPACE NHC4b
+
+#define HASH_ARRAY_2
+#define HASH_ARRAY_3
+#define HASH_BIG
+
+#include "HC.h"
+#include "HCMain.h"
+
+#undef HASH_ARRAY_2
+#undef HASH_ARRAY_3
+#undef HASH_BIG
+
+#endif
+
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/HashChain/HC4.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/HashChain/HC4.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/HashChain/HC4.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/HashChain/HC4.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,19 @@
+// HC4.h
+
+#ifndef __HC4_H
+#define __HC4_H
+
+#undef HC_NAMESPACE
+#define HC_NAMESPACE NHC4
+
+#define HASH_ARRAY_2
+#define HASH_ARRAY_3
+
+#include "HC.h"
+#include "HCMain.h"
+
+#undef HASH_ARRAY_2
+#undef HASH_ARRAY_3
+
+#endif
+
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/HashChain/HC.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/HashChain/HC.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/HashChain/HC.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/HashChain/HC.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,55 @@
+// HC.h
+
+#include "../LZInWindow.h"
+#include "../IMatchFinder.h"
+
+namespace HC_NAMESPACE {
+
+typedef UInt32 CIndex;
+const UInt32 kMaxValForNormalize = (UInt32(1) << 31) - 1;
+
+class CMatchFinderHC:
+ public IMatchFinder,
+ public IMatchFinderSetCallback,
+ public CLZInWindow,
+ public CMyUnknownImp
+{
+ UInt32 _cyclicBufferPos;
+ UInt32 _cyclicBufferSize; // it must be historySize + 1
+ UInt32 _matchMaxLen;
+ CIndex *_hash;
+ UInt32 _cutValue;
+
+ CMyComPtr<IMatchFinderCallback> m_Callback;
+
+ void Normalize();
+ void FreeThisClassMemory();
+ void FreeMemory();
+
+ MY_UNKNOWN_IMP1(IMatchFinderSetCallback)
+
+ STDMETHOD(Init)(ISequentialInStream *inStream);
+ STDMETHOD_(void, ReleaseStream)();
+ STDMETHOD(MovePos)();
+ STDMETHOD_(Byte, GetIndexByte)(Int32 index);
+ STDMETHOD_(UInt32, GetMatchLen)(Int32 index, UInt32 back, UInt32 limit);
+ STDMETHOD_(UInt32, GetNumAvailableBytes)();
+ STDMETHOD_(const Byte *, GetPointerToCurrentPos)();
+ STDMETHOD(Create)(UInt32 historySize, UInt32 keepAddBufferBefore,
+ UInt32 matchMaxLen, UInt32 keepAddBufferAfter);
+ STDMETHOD_(UInt32, GetLongestMatch)(UInt32 *distances);
+ STDMETHOD_(void, DummyLongestMatch)();
+
+ // IMatchFinderSetCallback
+ STDMETHOD(SetCallback)(IMatchFinderCallback *callback);
+
+ virtual void BeforeMoveBlock();
+ virtual void AfterMoveBlock();
+
+public:
+ CMatchFinderHC();
+ virtual ~CMatchFinderHC();
+ void SetCutValue(UInt32 cutValue) { _cutValue = cutValue; }
+};
+
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/HashChain/HCMain.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/HashChain/HCMain.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/HashChain/HCMain.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/HashChain/HCMain.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,350 @@
+// HC.h
+
+#include "../../../../Common/Defs.h"
+#include "../../../../Common/CRC.h"
+#include "../../../../Common/Alloc.h"
+
+namespace HC_NAMESPACE {
+
+#ifdef HASH_ARRAY_2
+ static const UInt32 kHash2Size = 1 << 10;
+ #ifdef HASH_ARRAY_3
+ static const UInt32 kNumHashDirectBytes = 0;
+ static const UInt32 kNumHashBytes = 4;
+ static const UInt32 kHash3Size = 1 << 18;
+ #ifdef HASH_BIG
+ static const UInt32 kHashSize = 1 << 23;
+ #else
+ static const UInt32 kHashSize = 1 << 20;
+ #endif
+ #else
+ static const UInt32 kNumHashDirectBytes = 0;
+ static const UInt32 kNumHashBytes = 3;
+ static const UInt32 kHashSize = 1 << (16);
+ #endif
+#else
+ #ifdef HASH_ZIP
+ static const UInt32 kNumHashDirectBytes = 0;
+ static const UInt32 kNumHashBytes = 3;
+ static const UInt32 kHashSize = 1 << 16;
+ #else
+ #define THERE_ARE_DIRECT_HASH_BYTES
+ static const UInt32 kNumHashDirectBytes = 2;
+ static const UInt32 kNumHashBytes = 2;
+ static const UInt32 kHashSize = 1 << (8 * kNumHashBytes);
+ #endif
+#endif
+
+static const UInt32 kHashSizeSum = kHashSize
+ #ifdef HASH_ARRAY_2
+ + kHash2Size
+ #ifdef HASH_ARRAY_3
+ + kHash3Size
+ #endif
+ #endif
+ ;
+
+#ifdef HASH_ARRAY_2
+static const UInt32 kHash2Offset = kHashSize;
+#ifdef HASH_ARRAY_3
+static const UInt32 kHash3Offset = kHashSize + kHash2Size;
+#endif
+#endif
+
+CMatchFinderHC::CMatchFinderHC():
+ _hash(0),
+ _cutValue(16)
+{
+}
+
+void CMatchFinderHC::FreeThisClassMemory()
+{
+ BigFree(_hash);
+ _hash = 0;
+}
+
+void CMatchFinderHC::FreeMemory()
+{
+ FreeThisClassMemory();
+ CLZInWindow::Free();
+}
+
+CMatchFinderHC::~CMatchFinderHC()
+{
+ FreeMemory();
+}
+
+STDMETHODIMP CMatchFinderHC::Create(UInt32 historySize, UInt32 keepAddBufferBefore,
+ UInt32 matchMaxLen, UInt32 keepAddBufferAfter)
+{
+ UInt32 sizeReserv = (historySize + keepAddBufferBefore +
+ matchMaxLen + keepAddBufferAfter) / 2 + 256;
+ if (CLZInWindow::Create(historySize + keepAddBufferBefore,
+ matchMaxLen + keepAddBufferAfter, sizeReserv))
+ {
+ if (historySize + 256 > kMaxValForNormalize)
+ {
+ FreeMemory();
+ return E_INVALIDARG;
+ }
+ _matchMaxLen = matchMaxLen;
+ UInt32 newCyclicBufferSize = historySize + 1;
+ if (_hash != 0 && newCyclicBufferSize == _cyclicBufferSize)
+ return S_OK;
+ FreeThisClassMemory();
+ _cyclicBufferSize = newCyclicBufferSize; // don't change it
+ _hash = (CIndex *)BigAlloc((kHashSizeSum + _cyclicBufferSize) * sizeof(CIndex));
+ if (_hash != 0)
+ return S_OK;
+ }
+ FreeMemory();
+ return E_OUTOFMEMORY;
+}
+
+static const UInt32 kEmptyHashValue = 0;
+
+STDMETHODIMP CMatchFinderHC::Init(ISequentialInStream *stream)
+{
+ RINOK(CLZInWindow::Init(stream));
+ for(UInt32 i = 0; i < kHashSizeSum; i++)
+ _hash[i] = kEmptyHashValue;
+ _cyclicBufferPos = 0;
+ ReduceOffsets(-1);
+ return S_OK;
+}
+
+STDMETHODIMP_(void) CMatchFinderHC::ReleaseStream()
+{
+ // ReleaseStream();
+}
+
+#ifdef HASH_ARRAY_2
+#ifdef HASH_ARRAY_3
+inline UInt32 Hash(const Byte *pointer, UInt32 &hash2Value, UInt32 &hash3Value)
+{
+ UInt32 temp = CCRC::Table[pointer[0]] ^ pointer[1];
+ hash2Value = temp & (kHash2Size - 1);
+ hash3Value = (temp ^ (UInt32(pointer[2]) << 8)) & (kHash3Size - 1);
+ return (temp ^ (UInt32(pointer[2]) << 8) ^ (CCRC::Table[pointer[3]] << 5)) &
+ (kHashSize - 1);
+}
+#else // no HASH_ARRAY_3
+inline UInt32 Hash(const Byte *pointer, UInt32 &hash2Value)
+{
+ UInt32 temp = CCRC::Table[pointer[0]] ^ pointer[1];
+ hash2Value = temp & (kHash2Size - 1);
+ return (temp ^ (UInt32(pointer[2]) << 8)) & (kHashSize - 1);;
+}
+#endif // HASH_ARRAY_3
+#else // no HASH_ARRAY_2
+#ifdef HASH_ZIP
+inline UInt32 Hash(const Byte *pointer)
+{
+ return ((UInt32(pointer[0]) << 8) ^
+ CCRC::Table[pointer[1]] ^ pointer[2]) & (kHashSize - 1);
+}
+#else // no HASH_ZIP
+inline UInt32 Hash(const Byte *pointer)
+{
+ return pointer[0] ^ (UInt32(pointer[1]) << 8);
+}
+#endif // HASH_ZIP
+#endif // HASH_ARRAY_2
+
+
+STDMETHODIMP_(UInt32) CMatchFinderHC::GetLongestMatch(UInt32 *distances)
+{
+ UInt32 lenLimit;
+ if (_pos + _matchMaxLen <= _streamPos)
+ lenLimit = _matchMaxLen;
+ else
+ {
+ lenLimit = _streamPos - _pos;
+ if(lenLimit < kNumHashBytes)
+ return 0;
+ }
+
+ UInt32 matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0;
+ Byte *cur = _buffer + _pos;
+
+ UInt32 maxLen = 0;
+
+ #ifdef HASH_ARRAY_2
+ UInt32 hash2Value;
+ #ifdef HASH_ARRAY_3
+ UInt32 hash3Value;
+ UInt32 hashValue = Hash(cur, hash2Value, hash3Value);
+ #else
+ UInt32 hashValue = Hash(cur, hash2Value);
+ #endif
+ #else
+ UInt32 hashValue = Hash(cur);
+ #endif
+ #ifdef HASH_ARRAY_2
+
+ UInt32 curMatch2 = _hash[kHash2Offset + hash2Value];
+ _hash[kHash2Offset + hash2Value] = _pos;
+ distances[2] = 0xFFFFFFFF;
+ if(curMatch2 > matchMinPos)
+ if (_buffer[curMatch2] == cur[0])
+ {
+ distances[2] = _pos - curMatch2 - 1;
+ maxLen = 2;
+ }
+
+ #ifdef HASH_ARRAY_3
+
+ UInt32 curMatch3 = _hash[kHash3Offset + hash3Value];
+ _hash[kHash3Offset + hash3Value] = _pos;
+ distances[3] = 0xFFFFFFFF;
+ if(curMatch3 > matchMinPos)
+ if (_buffer[curMatch3] == cur[0])
+ {
+ distances[3] = _pos - curMatch3 - 1;
+ maxLen = 3;
+ }
+
+ #endif
+ #endif
+
+ UInt32 curMatch = _hash[hashValue];
+ _hash[hashValue] = _pos;
+ CIndex *chain = _hash + kHashSizeSum;
+ chain[_cyclicBufferPos] = curMatch;
+ distances[kNumHashBytes] = 0xFFFFFFFF;
+ #ifdef THERE_ARE_DIRECT_HASH_BYTES
+ if (lenLimit == kNumHashDirectBytes)
+ {
+ if(curMatch > matchMinPos)
+ while (maxLen < kNumHashDirectBytes)
+ distances[++maxLen] = _pos - curMatch - 1;
+ }
+ else
+ #endif
+ {
+ UInt32 count = _cutValue;
+ do
+ {
+ if(curMatch <= matchMinPos)
+ break;
+ Byte *pby1 = _buffer + curMatch;
+ UInt32 currentLen = kNumHashDirectBytes;
+ do
+ {
+ if (pby1[currentLen] != cur[currentLen])
+ break;
+ }
+ while(++currentLen != lenLimit);
+
+ UInt32 delta = _pos - curMatch;
+ while (maxLen < currentLen)
+ distances[++maxLen] = delta - 1;
+ if(currentLen == lenLimit)
+ break;
+
+ UInt32 cyclicPos = (delta <= _cyclicBufferPos) ?
+ (_cyclicBufferPos - delta):
+ (_cyclicBufferPos - delta + _cyclicBufferSize);
+
+ curMatch = chain[cyclicPos];
+ }
+ while(--count != 0);
+ }
+ #ifdef HASH_ARRAY_2
+ #ifdef HASH_ARRAY_3
+ if (distances[4] < distances[3])
+ distances[3] = distances[4];
+ #endif
+ if (distances[3] < distances[2])
+ distances[2] = distances[3];
+ #endif
+ return maxLen;
+}
+
+STDMETHODIMP_(void) CMatchFinderHC::DummyLongestMatch()
+{
+ if (_streamPos - _pos < kNumHashBytes)
+ return;
+
+ Byte *cur = _buffer + _pos;
+
+ #ifdef HASH_ARRAY_2
+ UInt32 hash2Value;
+ #ifdef HASH_ARRAY_3
+ UInt32 hash3Value;
+ UInt32 hashValue = Hash(cur, hash2Value, hash3Value);
+ _hash[kHash3Offset + hash3Value] = _pos;
+ #else
+ UInt32 hashValue = Hash(cur, hash2Value);
+ #endif
+ _hash[kHash2Offset + hash2Value] = _pos;
+ #else
+ UInt32 hashValue = Hash(cur);
+ #endif
+
+ _hash[kHashSizeSum + _cyclicBufferPos] = _hash[hashValue];
+ _hash[hashValue] = _pos;
+}
+
+void CMatchFinderHC::Normalize()
+{
+ UInt32 subValue = _pos - _cyclicBufferSize;
+ CIndex *items = _hash;
+ UInt32 numItems = kHashSizeSum + _cyclicBufferSize;
+ for (UInt32 i = 0; i < numItems; i++)
+ {
+ UInt32 value = items[i];
+ if (value <= subValue)
+ value = kEmptyHashValue;
+ else
+ value -= subValue;
+ items[i] = value;
+ }
+ ReduceOffsets(subValue);
+}
+
+STDMETHODIMP CMatchFinderHC::MovePos()
+{
+ if (++_cyclicBufferPos == _cyclicBufferSize)
+ _cyclicBufferPos = 0;
+ RINOK(CLZInWindow::MovePos());
+ if (_pos == kMaxValForNormalize)
+ Normalize();
+ return S_OK;
+}
+
+STDMETHODIMP_(Byte) CMatchFinderHC::GetIndexByte(Int32 index)
+ { return CLZInWindow::GetIndexByte(index); }
+
+STDMETHODIMP_(UInt32) CMatchFinderHC::GetMatchLen(Int32 index,
+ UInt32 back, UInt32 limit)
+ { return CLZInWindow::GetMatchLen(index, back, limit); }
+
+STDMETHODIMP_(UInt32) CMatchFinderHC::GetNumAvailableBytes()
+ { return CLZInWindow::GetNumAvailableBytes(); }
+
+STDMETHODIMP_(const Byte *) CMatchFinderHC::GetPointerToCurrentPos()
+ { return CLZInWindow::GetPointerToCurrentPos(); }
+
+// IMatchFinderSetCallback
+STDMETHODIMP CMatchFinderHC::SetCallback(IMatchFinderCallback *callback)
+{
+ m_Callback = callback;
+ return S_OK;
+}
+
+void CMatchFinderHC::BeforeMoveBlock()
+{
+ if (m_Callback)
+ m_Callback->BeforeChangingBufferPos();
+ CLZInWindow::BeforeMoveBlock();
+}
+
+void CMatchFinderHC::AfterMoveBlock()
+{
+ if (m_Callback)
+ m_Callback->AfterChangingBufferPos();
+ CLZInWindow::AfterMoveBlock();
+}
+
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/IMatchFinder.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/IMatchFinder.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/IMatchFinder.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/IMatchFinder.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,63 @@
+// MatchFinders/IMatchFinder.h
+
+#ifndef __IMATCHFINDER_H
+#define __IMATCHFINDER_H
+
+// {23170F69-40C1-278A-0000-000200010000}
+DEFINE_GUID(IID_IInWindowStream,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000200010000")
+IInWindowStream: public IUnknown
+{
+ STDMETHOD(Init)(ISequentialInStream *inStream) PURE;
+ STDMETHOD_(void, ReleaseStream)() PURE;
+ STDMETHOD(MovePos)() PURE;
+ STDMETHOD_(Byte, GetIndexByte)(Int32 index) PURE;
+ STDMETHOD_(UInt32, GetMatchLen)(Int32 index, UInt32 distance, UInt32 limit) PURE;
+ STDMETHOD_(UInt32, GetNumAvailableBytes)() PURE;
+ STDMETHOD_(const Byte *, GetPointerToCurrentPos)() PURE;
+};
+
+// {23170F69-40C1-278A-0000-000200020000}
+DEFINE_GUID(IID_IMatchFinder,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000200020000")
+IMatchFinder: public IInWindowStream
+{
+ STDMETHOD(Create)(UInt32 historySize, UInt32 keepAddBufferBefore,
+ UInt32 matchMaxLen, UInt32 keepAddBufferAfter) PURE;
+ STDMETHOD_(UInt32, GetLongestMatch)(UInt32 *distances) PURE;
+ STDMETHOD_(void, DummyLongestMatch)() PURE;
+};
+
+// {23170F69-40C1-278A-0000-000200020100}
+DEFINE_GUID(IID_IMatchFinderCallback,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x01, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000200020100")
+IMatchFinderCallback: public IUnknown
+{
+ STDMETHOD(BeforeChangingBufferPos)() PURE;
+ STDMETHOD(AfterChangingBufferPos)() PURE;
+};
+
+// {23170F69-40C1-278A-0000-000200020200}
+DEFINE_GUID(IID_IMatchFinderSetCallback,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x02, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000200020200")
+IMatchFinderSetCallback: public IUnknown
+{
+ STDMETHOD(SetCallback)(IMatchFinderCallback *callback) PURE;
+};
+
+/*
+// {23170F69-40C1-278A-0000-000200030000}
+DEFINE_GUID(IID_IInitMatchFinder,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000200030000")
+IMatchFinderInit: public IUnknown
+{
+ STDMETHOD(InitMatchFinder)(IMatchFinder *matchFinder) PURE;
+};
+*/
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/LZInWindow.cpp squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/LZInWindow.cpp
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/LZInWindow.cpp 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/LZInWindow.cpp 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,102 @@
+// LZInWindow.cpp
+
+#include "StdAfx.h"
+
+#include "LZInWindow.h"
+#include "../../../Common/MyCom.h"
+#include "../../../Common/Alloc.h"
+
+void CLZInWindow::Free()
+{
+ ::BigFree(_bufferBase);
+ _bufferBase = 0;
+}
+
+bool CLZInWindow::Create(UInt32 keepSizeBefore, UInt32 keepSizeAfter, UInt32 keepSizeReserv)
+{
+ _keepSizeBefore = keepSizeBefore;
+ _keepSizeAfter = keepSizeAfter;
+ _keepSizeReserv = keepSizeReserv;
+ UInt32 blockSize = keepSizeBefore + keepSizeAfter + keepSizeReserv;
+ if (_bufferBase == 0 || _blockSize != blockSize)
+ {
+ Free();
+ _blockSize = blockSize;
+ if (_blockSize != 0)
+ _bufferBase = (Byte *)::BigAlloc(_blockSize);
+ }
+ _pointerToLastSafePosition = _bufferBase + _blockSize - keepSizeAfter;
+ if (_blockSize == 0)
+ return true;
+ return (_bufferBase != 0);
+}
+
+
+HRESULT CLZInWindow::Init(ISequentialInStream *stream)
+{
+ _stream = stream;
+ _buffer = _bufferBase;
+ _pos = 0;
+ _streamPos = 0;
+ _streamEndWasReached = false;
+ return ReadBlock();
+}
+
+/*
+void CLZInWindow::ReleaseStream()
+{
+ _stream.Release();
+}
+*/
+
+///////////////////////////////////////////
+// ReadBlock
+
+// In State:
+// (_buffer + _streamPos) <= (_bufferBase + _blockSize)
+// Out State:
+// _posLimit <= _blockSize - _keepSizeAfter;
+// if(_streamEndWasReached == false):
+// _streamPos >= _pos + _keepSizeAfter
+// _posLimit = _streamPos - _keepSizeAfter;
+// else
+//
+
+HRESULT CLZInWindow::ReadBlock()
+{
+ if(_streamEndWasReached)
+ return S_OK;
+ while(true)
+ {
+ UInt32 size = UInt32(_bufferBase - _buffer) + _blockSize - _streamPos;
+ if(size == 0)
+ return S_OK;
+ UInt32 numReadBytes;
+ RINOK(_stream->Read(_buffer + _streamPos, size, &numReadBytes));
+ if(numReadBytes == 0)
+ {
+ _posLimit = _streamPos;
+ const Byte *pointerToPostion = _buffer + _posLimit;
+ if(pointerToPostion > _pointerToLastSafePosition)
+ _posLimit = (UInt32)(_pointerToLastSafePosition - _buffer);
+ _streamEndWasReached = true;
+ return S_OK;
+ }
+ _streamPos += numReadBytes;
+ if(_streamPos >= _pos + _keepSizeAfter)
+ {
+ _posLimit = _streamPos - _keepSizeAfter;
+ return S_OK;
+ }
+ }
+}
+
+void CLZInWindow::MoveBlock()
+{
+ BeforeMoveBlock();
+ UInt32 offset = UInt32(_buffer - _bufferBase) + _pos - _keepSizeBefore;
+ UInt32 numBytes = UInt32(_buffer - _bufferBase) + _streamPos - offset;
+ memmove(_bufferBase, _bufferBase + offset, numBytes);
+ _buffer -= offset;
+ AfterMoveBlock();
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/LZInWindow.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/LZInWindow.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/LZInWindow.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/LZInWindow.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,84 @@
+// LZInWindow.h
+
+#ifndef __LZ_IN_WINDOW_H
+#define __LZ_IN_WINDOW_H
+
+#include "../../IStream.h"
+
+class CLZInWindow
+{
+ Byte *_bufferBase; // pointer to buffer with data
+ ISequentialInStream *_stream;
+ UInt32 _posLimit; // offset (from _buffer) of first byte when new block reading must be done
+ bool _streamEndWasReached; // if (true) then _streamPos shows real end of stream
+ const Byte *_pointerToLastSafePosition;
+protected:
+ Byte *_buffer; // Pointer to virtual Buffer begin
+ UInt32 _blockSize; // Size of Allocated memory block
+ UInt32 _pos; // offset (from _buffer) of curent byte
+ UInt32 _keepSizeBefore; // how many BYTEs must be kept in buffer before _pos
+ UInt32 _keepSizeAfter; // how many BYTEs must be kept buffer after _pos
+ UInt32 _keepSizeReserv; // how many BYTEs must be kept as reserv
+ UInt32 _streamPos; // offset (from _buffer) of first not read byte from Stream
+
+ virtual void BeforeMoveBlock() {};
+ virtual void AfterMoveBlock() {};
+ void MoveBlock();
+ virtual HRESULT ReadBlock();
+ void Free();
+public:
+ CLZInWindow(): _bufferBase(0) {}
+ virtual ~CLZInWindow() { Free(); }
+
+ bool Create(UInt32 keepSizeBefore, UInt32 keepSizeAfter,
+ UInt32 keepSizeReserv = (1<<17));
+
+ HRESULT Init(ISequentialInStream *stream);
+ // void ReleaseStream();
+
+ Byte *GetBuffer() const { return _buffer; }
+
+ const Byte *GetPointerToCurrentPos() const { return _buffer + _pos; }
+
+ HRESULT MovePos()
+ {
+ _pos++;
+ if (_pos > _posLimit)
+ {
+ const Byte *pointerToPostion = _buffer + _pos;
+ if(pointerToPostion > _pointerToLastSafePosition)
+ MoveBlock();
+ return ReadBlock();
+ }
+ else
+ return S_OK;
+ }
+ Byte GetIndexByte(Int32 index)const
+ { return _buffer[(size_t)_pos + index]; }
+
+ // index + limit have not to exceed _keepSizeAfter;
+ UInt32 GetMatchLen(Int32 index, UInt32 distance, UInt32 limit) const
+ {
+ if(_streamEndWasReached)
+ if ((_pos + index) + limit > _streamPos)
+ limit = _streamPos - (_pos + index);
+ distance++;
+ Byte *pby = _buffer + (size_t)_pos + index;
+ UInt32 i;
+ for(i = 0; i < limit && pby[i] == pby[(size_t)i - distance]; i++);
+ return i;
+ }
+
+ UInt32 GetNumAvailableBytes() const { return _streamPos - _pos; }
+
+ void ReduceOffsets(Int32 subValue)
+ {
+ _buffer += subValue;
+ _posLimit -= subValue;
+ _pos -= subValue;
+ _streamPos -= subValue;
+ }
+
+};
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/LZOutWindow.cpp squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/LZOutWindow.cpp
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/LZOutWindow.cpp 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/LZOutWindow.cpp 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,17 @@
+// LZOutWindow.cpp
+
+#include "StdAfx.h"
+
+#include "../../../Common/Alloc.h"
+#include "LZOutWindow.h"
+
+void CLZOutWindow::Init(bool solid)
+{
+ if(!solid)
+ COutBuffer::Init();
+ #ifdef _NO_EXCEPTIONS
+ ErrorCode = S_OK;
+ #endif
+}
+
+
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/LZOutWindow.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/LZOutWindow.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/LZOutWindow.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/LZOutWindow.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,64 @@
+// LZOutWindow.h
+
+#ifndef __LZ_OUT_WINDOW_H
+#define __LZ_OUT_WINDOW_H
+
+#include "../../IStream.h"
+#include "../../Common/OutBuffer.h"
+
+/*
+#ifndef _NO_EXCEPTIONS
+class CLZOutWindowException
+{
+public:
+ HRESULT ErrorCode;
+ CLZOutWindowException(HRESULT errorCode): ErrorCode(errorCode) {}
+};
+#endif
+*/
+typedef COutBufferException CLZOutWindowException;
+
+class CLZOutWindow: public COutBuffer
+{
+public:
+ void Init(bool solid = false);
+
+ // distance >= 0, len > 0,
+ bool CopyBlock(UInt32 distance, UInt32 len)
+ {
+ UInt32 pos = _pos - distance - 1;
+ if (pos >= _bufferSize)
+ {
+ if (!_overDict)
+ return false;
+ pos += _bufferSize;
+ }
+ do
+ {
+ if (pos == _bufferSize)
+ pos = 0;
+ _buffer[_pos++] = _buffer[pos++];
+ if (_pos == _limitPos)
+ FlushWithCheck();
+ }
+ while(--len != 0);
+ return true;
+ }
+
+ void PutByte(Byte b)
+ {
+ _buffer[_pos++] = b;
+ if (_pos == _limitPos)
+ FlushWithCheck();
+ }
+
+ Byte GetByte(UInt32 distance) const
+ {
+ UInt32 pos = _pos - distance - 1;
+ if (pos >= _bufferSize)
+ pos += _bufferSize;
+ return _buffer[pos];
+ }
+};
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/Patricia/Pat2.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/Patricia/Pat2.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/Patricia/Pat2.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/Patricia/Pat2.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,22 @@
+// Pat2.h
+
+#ifndef __PAT2__H
+#define __PAT2__H
+
+#undef PAT_CLSID
+#define PAT_CLSID CLSID_CMatchFinderPat2
+
+#undef PAT_NAMESPACE
+#define PAT_NAMESPACE NPat2
+
+#define __AUTO_REMOVE
+#define __NODE_2_BITS
+
+#include "Pat.h"
+#include "PatMain.h"
+
+#undef __AUTO_REMOVE
+#undef __NODE_2_BITS
+
+#endif
+
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/Patricia/Pat2H.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/Patricia/Pat2H.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/Patricia/Pat2H.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/Patricia/Pat2H.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,24 @@
+// Pat2H.h
+
+#ifndef __PAT2H__H
+#define __PAT2H__H
+
+#undef PAT_CLSID
+#define PAT_CLSID CLSID_CMatchFinderPat2H
+
+#undef PAT_NAMESPACE
+#define PAT_NAMESPACE NPat2H
+
+#define __AUTO_REMOVE
+#define __NODE_2_BITS
+#define __HASH_3
+
+#include "Pat.h"
+#include "PatMain.h"
+
+#undef __AUTO_REMOVE
+#undef __NODE_2_BITS
+#undef __HASH_3
+
+#endif
+
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/Patricia/Pat2R.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/Patricia/Pat2R.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/Patricia/Pat2R.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/Patricia/Pat2R.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,20 @@
+// Pat2R.h
+
+#ifndef __PAT2R__H
+#define __PAT2R__H
+
+#undef PAT_CLSID
+#define PAT_CLSID CLSID_CMatchFinderPat2R
+
+#undef PAT_NAMESPACE
+#define PAT_NAMESPACE NPat2R
+
+#define __NODE_2_BITS
+
+#include "Pat.h"
+#include "PatMain.h"
+
+#undef __NODE_2_BITS
+
+#endif
+
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/Patricia/Pat3H.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/Patricia/Pat3H.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/Patricia/Pat3H.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/Patricia/Pat3H.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,24 @@
+// Pat3H.h
+
+#ifndef __PAT3H__H
+#define __PAT3H__H
+
+#undef PAT_CLSID
+#define PAT_CLSID CLSID_CMatchFinderPat3H
+
+#undef PAT_NAMESPACE
+#define PAT_NAMESPACE NPat3H
+
+#define __AUTO_REMOVE
+#define __NODE_3_BITS
+#define __HASH_3
+
+#include "Pat.h"
+#include "PatMain.h"
+
+#undef __AUTO_REMOVE
+#undef __NODE_3_BITS
+#undef __HASH_3
+
+#endif
+
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/Patricia/Pat4H.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/Patricia/Pat4H.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/Patricia/Pat4H.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/Patricia/Pat4H.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,24 @@
+// Pat4H.h
+
+#ifndef __PAT4H__H
+#define __PAT4H__H
+
+#undef PAT_CLSID
+#define PAT_CLSID CLSID_CMatchFinderPat4H
+
+#undef PAT_NAMESPACE
+#define PAT_NAMESPACE NPat4H
+
+#define __AUTO_REMOVE
+#define __NODE_4_BITS
+#define __HASH_3
+
+#include "Pat.h"
+#include "PatMain.h"
+
+#undef __AUTO_REMOVE
+#undef __NODE_4_BITS
+#undef __HASH_3
+
+#endif
+
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/Patricia/Pat.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/Patricia/Pat.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/Patricia/Pat.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/Patricia/Pat.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,318 @@
+// Pat.h
+
+// #ifndef __PATRICIA__H
+// #define __PATRICIA__H
+
+#include "../../../../Common/MyCom.h"
+#include "../../../../Common/Types.h"
+#include "../LZInWindow.h"
+
+namespace PAT_NAMESPACE {
+
+struct CNode;
+
+typedef CNode *CNodePointer;
+
+// #define __AUTO_REMOVE
+
+// #define __NODE_4_BITS
+// #define __NODE_3_BITS
+// #define __NODE_2_BITS
+// #define __NODE_2_BITS_PADDING
+
+// #define __HASH_3
+
+
+typedef UInt32 CIndex;
+
+#ifdef __NODE_4_BITS
+ typedef UInt32 CIndex2;
+ typedef UInt32 CSameBitsType;
+#else
+#ifdef __NODE_3_BITS
+ typedef UInt32 CIndex2;
+ typedef UInt32 CSameBitsType;
+#else
+
+ typedef UInt32 CIndex;
+ typedef UInt32 CSameBitsType;
+
+ typedef CIndex CIndex2;
+#endif
+#endif
+
+const UInt32 kNumBitsInIndex = sizeof(CIndex) * 8;
+const UInt32 kMatchStartValue = UInt32(1) << (kNumBitsInIndex - 1);
+// don't change kMatchStartValue definition, since it is used in
+// PatMain.h:
+
+typedef CIndex CMatchPointer;
+
+const UInt32 kDescendantEmptyValue = kMatchStartValue - 1;
+
+union CDescendant
+{
+ CIndex NodePointer;
+ CMatchPointer MatchPointer;
+ bool IsEmpty() const { return NodePointer == kDescendantEmptyValue; }
+ bool IsNode() const { return NodePointer < kDescendantEmptyValue; }
+ bool IsMatch() const { return NodePointer > kDescendantEmptyValue; }
+ void MakeEmpty() { NodePointer = kDescendantEmptyValue; }
+};
+
+#undef MY_BYTE_SIZE
+
+#ifdef __NODE_4_BITS
+ #define MY_BYTE_SIZE 8
+ const UInt32 kNumSubBits = 4;
+#else
+#ifdef __NODE_3_BITS
+ #define MY_BYTE_SIZE 9
+ const UInt32 kNumSubBits = 3;
+#else
+ #define MY_BYTE_SIZE 8
+ #ifdef __NODE_2_BITS
+ const UInt32 kNumSubBits = 2;
+ #else
+ const UInt32 kNumSubBits = 1;
+ #endif
+#endif
+#endif
+
+const UInt32 kNumSubNodes = 1 << kNumSubBits;
+const UInt32 kSubNodesMask = kNumSubNodes - 1;
+
+struct CNode
+{
+ CIndex2 LastMatch;
+ CSameBitsType NumSameBits;
+ union
+ {
+ CDescendant Descendants[kNumSubNodes];
+ UInt32 NextFreeNode;
+ };
+ #ifdef __NODE_2_BITS
+ #ifdef __NODE_2_BITS_PADDING
+ UInt32 Padding[2];
+ #endif
+ #endif
+};
+
+#undef kIDNumBitsByte
+#undef kIDNumBitsString
+
+#ifdef __NODE_4_BITS
+ #define kIDNumBitsByte 0x30
+ #define kIDNumBitsString TEXT("4")
+#else
+#ifdef __NODE_3_BITS
+ #define kIDNumBitsByte 0x20
+ #define kIDNumBitsString TEXT("3")
+#else
+#ifdef __NODE_2_BITS
+ #define kIDNumBitsByte 0x10
+ #define kIDNumBitsString TEXT("2")
+#else
+ #define kIDNumBitsByte 0x00
+ #define kIDNumBitsString TEXT("1")
+#endif
+#endif
+#endif
+
+#undef kIDManualRemoveByte
+#undef kIDManualRemoveString
+
+#ifdef __AUTO_REMOVE
+ #define kIDManualRemoveByte 0x00
+ #define kIDManualRemoveString TEXT("")
+#else
+ #define kIDManualRemoveByte 0x08
+ #define kIDManualRemoveString TEXT("R")
+#endif
+
+#undef kIDHash3Byte
+#undef kIDHash3String
+
+#ifdef __HASH_3
+ #define kIDHash3Byte 0x04
+ #define kIDHash3String TEXT("H")
+#else
+ #define kIDHash3Byte 0x00
+ #define kIDHash3String TEXT("")
+#endif
+
+#undef kIDUse3BytesByte
+#undef kIDUse3BytesString
+
+#define kIDUse3BytesByte 0x00
+#define kIDUse3BytesString TEXT("")
+
+#undef kIDPaddingByte
+#undef kIDPaddingString
+
+#ifdef __NODE_2_BITS_PADDING
+ #define kIDPaddingByte 0x01
+ #define kIDPaddingString TEXT("P")
+#else
+ #define kIDPaddingByte 0x00
+ #define kIDPaddingString TEXT("")
+#endif
+
+
+// #undef kIDString
+// #define kIDString TEXT("Compress.MatchFinderPat") kIDNumBitsString kIDManualRemoveString kIDUse3BytesString kIDPaddingString kIDHash3String
+
+// {23170F69-40C1-278C-01XX-0000000000}
+
+DEFINE_GUID(PAT_CLSID,
+0x23170F69, 0x40C1, 0x278C, 0x01,
+kIDNumBitsByte |
+kIDManualRemoveByte | kIDHash3Byte | kIDUse3BytesByte | kIDPaddingByte,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
+
+// III(PAT_NAMESPACE)
+
+class CPatricia:
+ public IMatchFinder,
+ public IMatchFinderSetCallback,
+ public CMyUnknownImp,
+ CLZInWindow
+{
+ MY_UNKNOWN_IMP1(IMatchFinderSetCallback)
+
+ STDMETHOD(Init)(ISequentialInStream *aStream);
+ STDMETHOD_(void, ReleaseStream)();
+ STDMETHOD(MovePos)();
+ STDMETHOD_(Byte, GetIndexByte)(Int32 index);
+ STDMETHOD_(UInt32, GetMatchLen)(Int32 index, UInt32 back, UInt32 limit);
+ STDMETHOD_(UInt32, GetNumAvailableBytes)();
+ STDMETHOD(Create)(UInt32 historySize,
+ UInt32 keepAddBufferBefore, UInt32 matchMaxLen,
+ UInt32 keepAddBufferAfter);
+ STDMETHOD_(UInt32, GetLongestMatch)(UInt32 *distances);
+ STDMETHOD_(void, DummyLongestMatch)();
+ STDMETHOD_(const Byte *, GetPointerToCurrentPos)();
+
+ void FreeMemory();
+public:
+ CPatricia();
+ ~CPatricia();
+
+ UInt32 _sizeHistory;
+ UInt32 _matchMaxLen;
+
+ CDescendant *m_HashDescendants;
+ #ifdef __HASH_3
+ CDescendant *m_Hash2Descendants;
+ #endif
+
+ CNode *m_Nodes;
+
+ UInt32 m_FreeNode;
+ UInt32 m_FreeNodeMax;
+
+ #ifdef __AUTO_REMOVE
+ UInt32 m_NumUsedNodes;
+ UInt32 m_NumNodes;
+ #else
+ bool m_SpecialRemoveMode;
+ #endif
+
+ bool m_SpecialMode;
+ UInt32 m_NumNotChangedCycles;
+ UInt32 *m_TmpBacks;
+
+ CMyComPtr<IMatchFinderCallback> m_Callback;
+
+ virtual void BeforeMoveBlock();
+ virtual void AfterMoveBlock();
+
+ // IMatchFinderSetCallback
+ STDMETHOD(SetCallback)(IMatchFinderCallback *callback);
+
+ void ChangeLastMatch(UInt32 hashValue);
+
+ #ifdef __AUTO_REMOVE
+ void TestRemoveDescendant(CDescendant &descendant, UInt32 limitPos);
+ void TestRemoveNodes();
+ void RemoveNode(UInt32 index);
+ void TestRemoveAndNormalizeDescendant(CDescendant &descendant,
+ UInt32 limitPos, UInt32 subValue);
+ void TestRemoveNodesAndNormalize();
+ #else
+ void NormalizeDescendant(CDescendant &descendant, UInt32 subValue);
+ void Normalize();
+ void RemoveMatch();
+ #endif
+private:
+ void AddInternalNode(CNodePointer aNode, CIndex *aNodePointerPointer,
+ Byte aByte, Byte aByteXOR, UInt32 aNumSameBits, UInt32 aPos)
+ {
+ while((aByteXOR & kSubNodesMask) == 0)
+ {
+ aByteXOR >>= kNumSubBits;
+ aByte >>= kNumSubBits;
+ aNumSameBits -= kNumSubBits;
+ }
+ // Insert New Node
+ CNodePointer aNewNode = &m_Nodes[m_FreeNode];
+ UInt32 aNodeIndex = *aNodePointerPointer;
+ *aNodePointerPointer = m_FreeNode;
+ m_FreeNode = aNewNode->NextFreeNode;
+ #ifdef __AUTO_REMOVE
+ m_NumUsedNodes++;
+ #endif
+ if (m_FreeNode > m_FreeNodeMax)
+ {
+ m_FreeNodeMax = m_FreeNode;
+ m_Nodes[m_FreeNode].NextFreeNode = m_FreeNode + 1;
+ }
+
+ UInt32 aBitsNew = aByte & kSubNodesMask;
+ UInt32 aBitsOld = (aByte ^ aByteXOR) & kSubNodesMask;
+ for (UInt32 i = 0; i < kNumSubNodes; i++)
+ aNewNode->Descendants[i].NodePointer = kDescendantEmptyValue;
+ aNewNode->Descendants[aBitsNew].MatchPointer = aPos + kMatchStartValue;
+ aNewNode->Descendants[aBitsOld].NodePointer = aNodeIndex;
+ aNewNode->NumSameBits = CSameBitsType(aNode->NumSameBits - aNumSameBits);
+ aNewNode->LastMatch = aPos;
+
+ aNode->NumSameBits = CSameBitsType(aNumSameBits - kNumSubBits);
+ }
+
+ void AddLeafNode(CNodePointer aNode, Byte aByte, Byte aByteXOR,
+ UInt32 aNumSameBits, UInt32 aPos, UInt32 aDescendantIndex)
+ {
+ for(;(aByteXOR & kSubNodesMask) == 0; aNumSameBits += kNumSubBits)
+ {
+ aByte >>= kNumSubBits;
+ aByteXOR >>= kNumSubBits;
+ }
+ UInt32 aNewNodeIndex = m_FreeNode;
+ CNodePointer aNewNode = &m_Nodes[m_FreeNode];
+ m_FreeNode = aNewNode->NextFreeNode;
+ #ifdef __AUTO_REMOVE
+ m_NumUsedNodes++;
+ #endif
+ if (m_FreeNode > m_FreeNodeMax)
+ {
+ m_FreeNodeMax = m_FreeNode;
+ m_Nodes[m_FreeNode].NextFreeNode = m_FreeNode + 1;
+ }
+
+ UInt32 aBitsNew = (aByte & kSubNodesMask);
+ UInt32 aBitsOld = (aByte ^ aByteXOR) & kSubNodesMask;
+ for (UInt32 i = 0; i < kNumSubNodes; i++)
+ aNewNode->Descendants[i].NodePointer = kDescendantEmptyValue;
+ aNewNode->Descendants[aBitsNew].MatchPointer = aPos + kMatchStartValue;
+ aNewNode->Descendants[aBitsOld].MatchPointer =
+ aNode->Descendants[aDescendantIndex].MatchPointer;
+ aNewNode->NumSameBits = CSameBitsType(aNumSameBits);
+ aNewNode->LastMatch = aPos;
+ aNode->Descendants[aDescendantIndex].NodePointer = aNewNodeIndex;
+ }
+};
+
+}
+
+// #endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/Patricia/PatMain.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/Patricia/PatMain.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/Patricia/PatMain.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/Patricia/PatMain.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,989 @@
+// PatMain.h
+
+#include "../../../../Common/Defs.h"
+#include "../../../../Common/Alloc.h"
+
+namespace PAT_NAMESPACE {
+
+STDMETHODIMP CPatricia::SetCallback(IMatchFinderCallback *callback)
+{
+ m_Callback = callback;
+ return S_OK;
+}
+
+void CPatricia::BeforeMoveBlock()
+{
+ if (m_Callback)
+ m_Callback->BeforeChangingBufferPos();
+ CLZInWindow::BeforeMoveBlock();
+}
+
+void CPatricia::AfterMoveBlock()
+{
+ if (m_Callback)
+ m_Callback->AfterChangingBufferPos();
+ CLZInWindow::AfterMoveBlock();
+}
+
+const UInt32 kMatchStartValue2 = 2;
+const UInt32 kDescendantEmptyValue2 = kMatchStartValue2 - 1;
+const UInt32 kDescendantsNotInitilized2 = kDescendantEmptyValue2 - 1;
+
+#ifdef __HASH_3
+
+static const UInt32 kNumHashBytes = 3;
+static const UInt32 kHashSize = 1 << (8 * kNumHashBytes);
+
+static const UInt32 kNumHash2Bytes = 2;
+static const UInt32 kHash2Size = 1 << (8 * kNumHash2Bytes);
+static const UInt32 kPrevHashSize = kNumHash2Bytes;
+
+#else
+
+static const UInt32 kNumHashBytes = 2;
+static const UInt32 kHashSize = 1 << (8 * kNumHashBytes);
+static const UInt32 kPrevHashSize = 0;
+
+#endif
+
+
+CPatricia::CPatricia():
+ m_HashDescendants(0),
+ #ifdef __HASH_3
+ m_Hash2Descendants(0),
+ #endif
+ m_Nodes(0),
+ m_TmpBacks(0)
+{
+}
+
+CPatricia::~CPatricia()
+{
+ FreeMemory();
+}
+
+void CPatricia::FreeMemory()
+{
+ MyFree(m_TmpBacks);
+ m_TmpBacks = 0;
+
+ ::BigFree(m_Nodes);
+ m_Nodes = 0;
+
+ ::BigFree(m_HashDescendants);
+ m_HashDescendants = 0;
+
+ #ifdef __HASH_3
+
+ ::BigFree(m_Hash2Descendants);
+ m_Hash2Descendants = 0;
+
+ CLZInWindow::Free();
+
+ #endif
+}
+
+STDMETHODIMP CPatricia::Create(UInt32 historySize, UInt32 keepAddBufferBefore,
+ UInt32 matchMaxLen, UInt32 keepAddBufferAfter)
+{
+ FreeMemory();
+ int kNumBitsInNumSameBits = sizeof(CSameBitsType) * 8;
+ if (kNumBitsInNumSameBits < 32 && ((matchMaxLen * MY_BYTE_SIZE) > ((UInt32)1 << kNumBitsInNumSameBits)))
+ return E_INVALIDARG;
+
+ const UInt32 kAlignMask = (1 << 16) - 1;
+ UInt32 windowReservSize = historySize;
+ windowReservSize += kAlignMask;
+ windowReservSize &= ~(kAlignMask);
+
+ const UInt32 kMinReservSize = (1 << 19);
+ if (windowReservSize < kMinReservSize)
+ windowReservSize = kMinReservSize;
+ windowReservSize += 256;
+
+ if (!CLZInWindow::Create(historySize + keepAddBufferBefore,
+ matchMaxLen + keepAddBufferAfter, windowReservSize))
+ return E_OUTOFMEMORY;
+
+ _sizeHistory = historySize;
+ _matchMaxLen = matchMaxLen;
+ m_HashDescendants = (CDescendant *)BigAlloc(kHashSize * sizeof(CDescendant));
+ if (m_HashDescendants == 0)
+ {
+ FreeMemory();
+ return E_OUTOFMEMORY;
+ }
+
+ #ifdef __HASH_3
+ m_Hash2Descendants = (CDescendant *)BigAlloc(kHash2Size * sizeof(CDescendant));
+ if (m_Hash2Descendants == 0)
+ {
+ FreeMemory();
+ return E_OUTOFMEMORY;
+ }
+ #endif
+
+ #ifdef __AUTO_REMOVE
+
+ #ifdef __HASH_3
+ m_NumNodes = historySize + _sizeHistory * 4 / 8 + (1 << 19);
+ #else
+ m_NumNodes = historySize + _sizeHistory * 4 / 8 + (1 << 10);
+ #endif
+
+ #else
+
+ UInt32 m_NumNodes = historySize;
+
+ #endif
+
+ const UInt32 kMaxNumNodes = UInt32(1) << (sizeof(CIndex) * 8 - 1);
+ if (m_NumNodes + 32 > kMaxNumNodes)
+ return E_INVALIDARG;
+
+ // m_Nodes = (CNode *)::BigAlloc((m_NumNodes + 2) * sizeof(CNode));
+ m_Nodes = (CNode *)::BigAlloc((m_NumNodes + 12) * sizeof(CNode));
+ if (m_Nodes == 0)
+ {
+ FreeMemory();
+ return E_OUTOFMEMORY;
+ }
+
+ m_TmpBacks = (UInt32 *)MyAlloc((_matchMaxLen + 1) * sizeof(UInt32));
+ if (m_TmpBacks == 0)
+ {
+ FreeMemory();
+ return E_OUTOFMEMORY;
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CPatricia::Init(ISequentialInStream *aStream)
+{
+ RINOK(CLZInWindow::Init(aStream));
+
+ // memset(m_HashDescendants, 0xFF, kHashSize * sizeof(m_HashDescendants[0]));
+
+ #ifdef __HASH_3
+ for (UInt32 i = 0; i < kHash2Size; i++)
+ m_Hash2Descendants[i].MatchPointer = kDescendantsNotInitilized2;
+ #else
+ for (UInt32 i = 0; i < kHashSize; i++)
+ m_HashDescendants[i].MakeEmpty();
+ #endif
+
+ m_Nodes[0].NextFreeNode = 1;
+ m_FreeNode = 0;
+ m_FreeNodeMax = 0;
+ #ifdef __AUTO_REMOVE
+ m_NumUsedNodes = 0;
+ #else
+ m_SpecialRemoveMode = false;
+ #endif
+ m_SpecialMode = false;
+ return S_OK;
+}
+
+STDMETHODIMP_(void) CPatricia::ReleaseStream()
+{
+ // CLZInWindow::ReleaseStream();
+}
+
+// pos = _pos + kNumHashBytes
+// fullCurrentLimit = currentLimit + kNumHashBytes
+// fullMatchLen = matchLen + kNumHashBytes
+
+void CPatricia::ChangeLastMatch(UInt32 hashValue)
+{
+ UInt32 pos = _pos + kNumHashBytes - 1;
+ UInt32 descendantIndex;
+ const Byte *currentBytePointer = _buffer + pos;
+ UInt32 numLoadedBits = 0;
+ Byte curByte = 0; // = 0 to disable warning of GCC
+ CNodePointer node = &m_Nodes[m_HashDescendants[hashValue].NodePointer];
+
+ while(true)
+ {
+ UInt32 numSameBits = node->NumSameBits;
+ if(numSameBits > 0)
+ {
+ if (numLoadedBits < numSameBits)
+ {
+ numSameBits -= numLoadedBits;
+ currentBytePointer += (numSameBits / MY_BYTE_SIZE);
+ numSameBits %= MY_BYTE_SIZE;
+ curByte = *currentBytePointer++;
+ numLoadedBits = MY_BYTE_SIZE;
+ }
+ curByte >>= numSameBits;
+ numLoadedBits -= numSameBits;
+ }
+ if(numLoadedBits == 0)
+ {
+ curByte = *currentBytePointer++;
+ numLoadedBits = MY_BYTE_SIZE;
+ }
+ descendantIndex = (curByte & kSubNodesMask);
+ node->LastMatch = pos;
+ numLoadedBits -= kNumSubBits;
+ curByte >>= kNumSubBits;
+ if(node->Descendants[descendantIndex].IsNode())
+ node = &m_Nodes[node->Descendants[descendantIndex].NodePointer];
+ else
+ break;
+ }
+ node->Descendants[descendantIndex].MatchPointer = pos + kMatchStartValue;
+}
+
+UInt32 CPatricia::GetLongestMatch(UInt32 *distances)
+{
+ UInt32 fullCurrentLimit;
+ if (_pos + _matchMaxLen <= _streamPos)
+ fullCurrentLimit = _matchMaxLen;
+ else
+ {
+ fullCurrentLimit = _streamPos - _pos;
+ if(fullCurrentLimit < kNumHashBytes)
+ return 0;
+ }
+ UInt32 pos = _pos + kNumHashBytes;
+
+ #ifdef __HASH_3
+ UInt32 hash2Value = ((UInt32(_buffer[_pos])) << 8) | _buffer[_pos + 1];
+ UInt32 hashValue = (hash2Value << 8) | _buffer[_pos + 2];
+ CDescendant &hash2Descendant = m_Hash2Descendants[hash2Value];
+ CDescendant &hashDescendant = m_HashDescendants[hashValue];
+ if(hash2Descendant.MatchPointer <= kDescendantEmptyValue2)
+ {
+ if(hash2Descendant.MatchPointer == kDescendantsNotInitilized2)
+ {
+ UInt32 base = hashValue & 0xFFFF00;
+ for (UInt32 i = 0; i < 0x100; i++)
+ m_HashDescendants[base + i].MakeEmpty();
+ }
+ hash2Descendant.MatchPointer = pos + kMatchStartValue2;
+ hashDescendant.MatchPointer = pos + kMatchStartValue;
+ return 0;
+ }
+
+ distances[kNumHash2Bytes] = pos - (hash2Descendant.MatchPointer - kMatchStartValue2) - 1;
+ hash2Descendant.MatchPointer = pos + kMatchStartValue2;
+ #ifdef __AUTO_REMOVE
+ if (distances[kNumHash2Bytes] >= _sizeHistory)
+ {
+ if (hashDescendant.IsNode())
+ RemoveNode(hashDescendant.NodePointer);
+ hashDescendant.MatchPointer = pos + kMatchStartValue;
+ return 0;
+ }
+ #endif
+ if (fullCurrentLimit == kNumHash2Bytes)
+ return kNumHash2Bytes;
+
+ #else
+ UInt32 hashValue = UInt32(GetIndexByte(1)) | (UInt32(GetIndexByte(0)) << 8);
+ CDescendant &hashDescendant = m_HashDescendants[hashValue];
+ #endif
+
+
+ if(m_SpecialMode)
+ {
+ if(hashDescendant.IsMatch())
+ m_NumNotChangedCycles = 0;
+ if(m_NumNotChangedCycles >= _sizeHistory - 1)
+ {
+ ChangeLastMatch(hashValue);
+ m_NumNotChangedCycles = 0;
+ }
+ if(GetIndexByte(fullCurrentLimit - 1) == GetIndexByte(fullCurrentLimit - 2))
+ {
+ if(hashDescendant.IsMatch())
+ hashDescendant.MatchPointer = pos + kMatchStartValue;
+ else
+ m_NumNotChangedCycles++;
+ for(UInt32 i = kNumHashBytes; i <= fullCurrentLimit; i++)
+ distances[i] = 0;
+ return fullCurrentLimit;
+ }
+ else if(m_NumNotChangedCycles > 0)
+ ChangeLastMatch(hashValue);
+ m_SpecialMode = false;
+ }
+
+ if(hashDescendant.IsEmpty())
+ {
+ hashDescendant.MatchPointer = pos + kMatchStartValue;
+ return kPrevHashSize;
+ }
+
+ UInt32 currentLimit = fullCurrentLimit - kNumHashBytes;
+
+ if(hashDescendant.IsMatch())
+ {
+ CMatchPointer matchPointer = hashDescendant.MatchPointer;
+ UInt32 backReal = pos - (matchPointer - kMatchStartValue);
+ UInt32 back = backReal - 1;
+ #ifdef __AUTO_REMOVE
+ if (back >= _sizeHistory)
+ {
+ hashDescendant.MatchPointer = pos + kMatchStartValue;
+ return kPrevHashSize;
+ }
+ #endif
+
+ UInt32 matchLen;
+ distances += kNumHashBytes;
+ Byte *buffer = _buffer + pos;
+ for(matchLen = 0; true; matchLen++)
+ {
+ *distances++ = back;
+ if (matchLen == currentLimit)
+ {
+ hashDescendant.MatchPointer = pos + kMatchStartValue;
+ return kNumHashBytes + matchLen;
+ }
+ if (buffer[matchLen] != buffer[(size_t)matchLen - backReal])
+ break;
+ }
+
+ // UInt32 matchLen = GetMatchLen(kNumHashBytes, back, currentLimit);
+
+ UInt32 fullMatchLen = matchLen + kNumHashBytes;
+ hashDescendant.NodePointer = m_FreeNode;
+ CNodePointer node = &m_Nodes[m_FreeNode];
+ m_FreeNode = node->NextFreeNode;
+ #ifdef __AUTO_REMOVE
+ m_NumUsedNodes++;
+ #endif
+ if (m_FreeNode > m_FreeNodeMax)
+ {
+ m_FreeNodeMax = m_FreeNode;
+ m_Nodes[m_FreeNode].NextFreeNode = m_FreeNode + 1;
+ }
+
+ for (UInt32 i = 0; i < kNumSubNodes; i++)
+ node->Descendants[i].NodePointer = kDescendantEmptyValue;
+ node->LastMatch = pos;
+
+ Byte byteNew = GetIndexByte(fullMatchLen);
+ Byte byteOld = GetIndexByte(fullMatchLen - backReal);
+ Byte bitsNew, bitsOld;
+ UInt32 numSameBits = matchLen * MY_BYTE_SIZE;
+ while (true)
+ {
+ bitsNew = (byteNew & kSubNodesMask);
+ bitsOld = (byteOld & kSubNodesMask);
+ if(bitsNew != bitsOld)
+ break;
+ byteNew >>= kNumSubBits;
+ byteOld >>= kNumSubBits;
+ numSameBits += kNumSubBits;
+ }
+ node->NumSameBits = CSameBitsType(numSameBits);
+ node->Descendants[bitsNew].MatchPointer = pos + kMatchStartValue;
+ node->Descendants[bitsOld].MatchPointer = matchPointer;
+ return fullMatchLen;
+ }
+ const Byte *baseCurrentBytePointer = _buffer + pos;
+ const Byte *currentBytePointer = baseCurrentBytePointer;
+ UInt32 numLoadedBits = 0;
+ Byte curByte = 0;
+ CIndex *nodePointerPointer = &hashDescendant.NodePointer;
+ CNodePointer node = &m_Nodes[*nodePointerPointer];
+ distances += kNumHashBytes;
+ const Byte *bytePointerLimit = baseCurrentBytePointer + currentLimit;
+ const Byte *currentAddingOffset = _buffer;
+
+ #ifdef __AUTO_REMOVE
+ UInt32 lowPos;
+ if (pos > _sizeHistory)
+ lowPos = pos - _sizeHistory;
+ else
+ lowPos = 0;
+ #endif
+
+ while(true)
+ {
+ #ifdef __AUTO_REMOVE
+ if (node->LastMatch < lowPos)
+ {
+ RemoveNode(*nodePointerPointer);
+ *nodePointerPointer = pos + kMatchStartValue;
+ if (currentBytePointer == baseCurrentBytePointer)
+ return kPrevHashSize;
+ return kNumHashBytes + (UInt32)(currentBytePointer - baseCurrentBytePointer - 1);
+ }
+ #endif
+ if(numLoadedBits == 0)
+ {
+ *distances++ = pos - node->LastMatch - 1;
+ if(currentBytePointer >= bytePointerLimit)
+ {
+ for (UInt32 i = 0; i < kNumSubNodes; i++)
+ node->Descendants[i].MatchPointer = pos + kMatchStartValue;
+ node->LastMatch = pos;
+ node->NumSameBits = 0;
+ return fullCurrentLimit;
+ }
+ curByte = (*currentBytePointer++);
+ currentAddingOffset++;
+ numLoadedBits = MY_BYTE_SIZE;
+ }
+ UInt32 numSameBits = node->NumSameBits;
+ if(numSameBits > 0)
+ {
+ Byte byteXOR = ((*(currentAddingOffset + node->LastMatch -1)) >>
+ (MY_BYTE_SIZE - numLoadedBits)) ^ curByte;
+ while(numLoadedBits <= numSameBits)
+ {
+ if(byteXOR != 0)
+ {
+ AddInternalNode(node, nodePointerPointer, curByte, byteXOR,
+ numSameBits, pos);
+ return kNumHashBytes + (UInt32)(currentBytePointer - baseCurrentBytePointer - 1);
+ }
+ *distances++ = pos - node->LastMatch - 1;
+ numSameBits -= numLoadedBits;
+ if(currentBytePointer >= bytePointerLimit)
+ {
+ for (UInt32 i = 0; i < kNumSubNodes; i++)
+ node->Descendants[i].MatchPointer = pos + kMatchStartValue;
+ node->LastMatch = pos;
+ node->NumSameBits = CSameBitsType(node->NumSameBits - numSameBits);
+ return fullCurrentLimit;
+ }
+ numLoadedBits = MY_BYTE_SIZE;
+ curByte = (*currentBytePointer++);
+ byteXOR = curByte ^ (*(currentAddingOffset + node->LastMatch));
+ currentAddingOffset++;
+ }
+ if((byteXOR & ((1 << numSameBits) - 1)) != 0)
+ {
+ AddInternalNode(node, nodePointerPointer, curByte, byteXOR,
+ numSameBits, pos);
+ return kNumHashBytes + (UInt32)(currentBytePointer - baseCurrentBytePointer - 1);
+ }
+ curByte >>= numSameBits;
+ numLoadedBits -= numSameBits;
+ }
+ UInt32 descendantIndex = (curByte & kSubNodesMask);
+ numLoadedBits -= kNumSubBits;
+ nodePointerPointer = &node->Descendants[descendantIndex].NodePointer;
+ UInt32 nextNodeIndex = *nodePointerPointer;
+ node->LastMatch = pos;
+ if (nextNodeIndex < kDescendantEmptyValue)
+ {
+ curByte >>= kNumSubBits;
+ node = &m_Nodes[nextNodeIndex];
+ }
+ else if (nextNodeIndex == kDescendantEmptyValue)
+ {
+ node->Descendants[descendantIndex].MatchPointer = pos + kMatchStartValue;
+ return kNumHashBytes + (UInt32)(currentBytePointer - baseCurrentBytePointer - 1);
+ }
+ else
+ break;
+ }
+
+ UInt32 descendantIndex = (curByte & kSubNodesMask);
+ curByte >>= kNumSubBits;
+ CMatchPointer matchPointer = node->Descendants[descendantIndex].MatchPointer;
+ CMatchPointer realMatchPointer;
+ realMatchPointer = matchPointer - kMatchStartValue;
+
+ #ifdef __AUTO_REMOVE
+ if (realMatchPointer < lowPos)
+ {
+ node->Descendants[descendantIndex].MatchPointer = pos + kMatchStartValue;
+ return kNumHashBytes + (UInt32)(currentBytePointer - baseCurrentBytePointer - 1);
+ }
+ #endif
+
+ Byte byteXOR;
+ UInt32 numSameBits = 0;
+ if(numLoadedBits != 0)
+ {
+ Byte matchByte = *(currentAddingOffset + realMatchPointer -1);
+ matchByte >>= (MY_BYTE_SIZE - numLoadedBits);
+ byteXOR = matchByte ^ curByte;
+ if(byteXOR != 0)
+ {
+ AddLeafNode(node, curByte, byteXOR, numSameBits, pos, descendantIndex);
+ return kNumHashBytes + (UInt32)(currentBytePointer - baseCurrentBytePointer - 1);
+ }
+ numSameBits += numLoadedBits;
+ }
+
+ const Byte *matchBytePointer = _buffer + realMatchPointer +
+ (currentBytePointer - baseCurrentBytePointer);
+ for(; currentBytePointer < bytePointerLimit; numSameBits += MY_BYTE_SIZE)
+ {
+ curByte = (*currentBytePointer++);
+ *distances++ = pos - realMatchPointer - 1;
+ byteXOR = curByte ^ (*matchBytePointer++);
+ if(byteXOR != 0)
+ {
+ AddLeafNode(node, curByte, byteXOR, numSameBits, pos, descendantIndex);
+ return kNumHashBytes + (UInt32)(currentBytePointer - baseCurrentBytePointer - 1);
+ }
+ }
+ *distances = pos - realMatchPointer - 1;
+ node->Descendants[descendantIndex].MatchPointer = pos + kMatchStartValue;
+
+ if(*distances == 0)
+ {
+ m_SpecialMode = true;
+ m_NumNotChangedCycles = 0;
+ }
+ return fullCurrentLimit;
+}
+
+STDMETHODIMP_(void) CPatricia::DummyLongestMatch()
+{
+ GetLongestMatch(m_TmpBacks);
+}
+
+
+// ------------------------------------
+// Remove Match
+
+typedef Byte CRemoveDataWord;
+
+static const int kSizeRemoveDataWordInBits = MY_BYTE_SIZE * sizeof(CRemoveDataWord);
+
+#ifndef __AUTO_REMOVE
+
+void CPatricia::RemoveMatch()
+{
+ if(m_SpecialRemoveMode)
+ {
+ if(GetIndexByte(_matchMaxLen - 1 - _sizeHistory) ==
+ GetIndexByte(_matchMaxLen - _sizeHistory))
+ return;
+ m_SpecialRemoveMode = false;
+ }
+ UInt32 pos = _pos + kNumHashBytes - _sizeHistory;
+
+ #ifdef __HASH_3
+ const Byte *pp = _buffer + _pos - _sizeHistory;
+ UInt32 hash2Value = ((UInt32(pp[0])) << 8) | pp[1];
+ UInt32 hashValue = (hash2Value << 8) | pp[2];
+ CDescendant &hashDescendant = m_HashDescendants[hashValue];
+ CDescendant &hash2Descendant = m_Hash2Descendants[hash2Value];
+ if (hash2Descendant >= kMatchStartValue2)
+ if(hash2Descendant.MatchPointer == pos + kMatchStartValue2)
+ hash2Descendant.MatchPointer = kDescendantEmptyValue2;
+ #else
+ UInt32 hashValue = UInt32(GetIndexByte(1 - _sizeHistory)) |
+ (UInt32(GetIndexByte(0 - _sizeHistory)) << 8);
+ CDescendant &hashDescendant = m_HashDescendants[hashValue];
+ #endif
+
+ if(hashDescendant.IsEmpty())
+ return;
+ if(hashDescendant.IsMatch())
+ {
+ if(hashDescendant.MatchPointer == pos + kMatchStartValue)
+ hashDescendant.MakeEmpty();
+ return;
+ }
+
+ UInt32 descendantIndex;
+ const CRemoveDataWord *currentPointer = (const CRemoveDataWord *)(_buffer + pos);
+ UInt32 numLoadedBits = 0;
+ CRemoveDataWord curWord = 0; // = 0 to disable GCC warning
+
+ CIndex *nodePointerPointer = &hashDescendant.NodePointer;
+
+ CNodePointer node = &m_Nodes[hashDescendant.NodePointer];
+
+ while(true)
+ {
+ if(numLoadedBits == 0)
+ {
+ curWord = *currentPointer++;
+ numLoadedBits = kSizeRemoveDataWordInBits;
+ }
+ UInt32 numSameBits = node->NumSameBits;
+ if(numSameBits > 0)
+ {
+ if (numLoadedBits <= numSameBits)
+ {
+ numSameBits -= numLoadedBits;
+ currentPointer += (numSameBits / kSizeRemoveDataWordInBits);
+ numSameBits %= kSizeRemoveDataWordInBits;
+ curWord = *currentPointer++;
+ numLoadedBits = kSizeRemoveDataWordInBits;
+ }
+ curWord >>= numSameBits;
+ numLoadedBits -= numSameBits;
+ }
+ descendantIndex = (curWord & kSubNodesMask);
+ numLoadedBits -= kNumSubBits;
+ curWord >>= kNumSubBits;
+ UInt32 nextNodeIndex = node->Descendants[descendantIndex].NodePointer;
+ if (nextNodeIndex < kDescendantEmptyValue)
+ {
+ nodePointerPointer = &node->Descendants[descendantIndex].NodePointer;
+ node = &m_Nodes[nextNodeIndex];
+ }
+ else
+ break;
+ }
+ if (node->Descendants[descendantIndex].MatchPointer != pos + kMatchStartValue)
+ {
+ const Byte *currentBytePointer = _buffer + _pos - _sizeHistory;
+ const Byte *currentBytePointerLimit = currentBytePointer + _matchMaxLen;
+ for(;currentBytePointer < currentBytePointerLimit; currentBytePointer++)
+ if(*currentBytePointer != *(currentBytePointer+1))
+ return;
+ m_SpecialRemoveMode = true;
+ return;
+ }
+
+ UInt32 numNodes = 0, numMatches = 0;
+
+ UInt32 i;
+ for (i = 0; i < kNumSubNodes; i++)
+ {
+ UInt32 nodeIndex = node->Descendants[i].NodePointer;
+ if (nodeIndex < kDescendantEmptyValue)
+ numNodes++;
+ else if (nodeIndex > kDescendantEmptyValue)
+ numMatches++;
+ }
+ numMatches -= 1;
+ if (numNodes + numMatches > 1)
+ {
+ node->Descendants[descendantIndex].MakeEmpty();
+ return;
+ }
+ if(numNodes == 1)
+ {
+ UInt32 i;
+ for (i = 0; i < kNumSubNodes; i++)
+ if (node->Descendants[i].IsNode())
+ break;
+ UInt32 nextNodeIndex = node->Descendants[i].NodePointer;
+ CNodePointer nextNode = &m_Nodes[nextNodeIndex];
+ nextNode->NumSameBits += node->NumSameBits + kNumSubBits;
+ *node = *nextNode;
+
+ nextNode->NextFreeNode = m_FreeNode;
+ m_FreeNode = nextNodeIndex;
+ return;
+ }
+ UInt32 matchPointer = 0; // = 0 to disable GCC warning
+ for (i = 0; i < kNumSubNodes; i++)
+ if (node->Descendants[i].IsMatch() && i != descendantIndex)
+ {
+ matchPointer = node->Descendants[i].MatchPointer;
+ break;
+ }
+ node->NextFreeNode = m_FreeNode;
+ m_FreeNode = *nodePointerPointer;
+ *nodePointerPointer = matchPointer;
+}
+#endif
+
+
+// Commented code is more correct, but it gives warning
+// on GCC: (1 << 32)
+// So we use kMatchStartValue twice:
+// kMatchStartValue = UInt32(1) << (kNumBitsInIndex - 1);
+// must be defined in Pat.h
+/*
+const UInt32 kNormalizeStartPos = (UInt32(1) << (kNumBitsInIndex)) -
+ kMatchStartValue - kNumHashBytes - 1;
+*/
+const UInt32 kNormalizeStartPos = kMatchStartValue - kNumHashBytes - 1;
+
+STDMETHODIMP CPatricia::MovePos()
+{
+ #ifndef __AUTO_REMOVE
+ if(_pos >= _sizeHistory)
+ RemoveMatch();
+ #endif
+ RINOK(CLZInWindow::MovePos());
+ #ifdef __AUTO_REMOVE
+ if (m_NumUsedNodes >= m_NumNodes)
+ TestRemoveNodes();
+ #endif
+ if (_pos >= kNormalizeStartPos)
+ {
+ #ifdef __AUTO_REMOVE
+ TestRemoveNodesAndNormalize();
+ #else
+ Normalize();
+ #endif
+ }
+ return S_OK;
+}
+
+#ifndef __AUTO_REMOVE
+
+void CPatricia::NormalizeDescendant(CDescendant &descendant, UInt32 subValue)
+{
+ if (descendant.IsEmpty())
+ return;
+ if (descendant.IsMatch())
+ descendant.MatchPointer = descendant.MatchPointer - subValue;
+ else
+ {
+ CNode &node = m_Nodes[descendant.NodePointer];
+ node.LastMatch = node.LastMatch - subValue;
+ for (UInt32 i = 0; i < kNumSubNodes; i++)
+ NormalizeDescendant(node.Descendants[i], subValue);
+ }
+}
+
+void CPatricia::Normalize()
+{
+ UInt32 subValue = _pos - _sizeHistory;
+ CLZInWindow::ReduceOffsets(subValue);
+
+ #ifdef __HASH_3
+
+ for(UInt32 hash = 0; hash < kHash2Size; hash++)
+ {
+ CDescendant &descendant = m_Hash2Descendants[hash];
+ if (descendant.MatchPointer != kDescendantsNotInitilized2)
+ {
+ UInt32 base = hash << 8;
+ for (UInt32 i = 0; i < 0x100; i++)
+ NormalizeDescendant(m_HashDescendants[base + i], subValue);
+ }
+ if (descendant.MatchPointer < kMatchStartValue2)
+ continue;
+ descendant.MatchPointer = descendant.MatchPointer - subValue;
+ }
+
+ #else
+
+ for(UInt32 hash = 0; hash < kHashSize; hash++)
+ NormalizeDescendant(m_HashDescendants[hash], subValue);
+
+ #endif
+
+}
+
+#else
+
+void CPatricia::TestRemoveDescendant(CDescendant &descendant, UInt32 limitPos)
+{
+ CNode &node = m_Nodes[descendant.NodePointer];
+ UInt32 numChilds = 0;
+ UInt32 childIndex = 0; // = 0 to disable GCC warning
+ for (UInt32 i = 0; i < kNumSubNodes; i++)
+ {
+ CDescendant &descendant2 = node.Descendants[i];
+ if (descendant2.IsEmpty())
+ continue;
+ if (descendant2.IsMatch())
+ {
+ if (descendant2.MatchPointer < limitPos)
+ descendant2.MakeEmpty();
+ else
+ {
+ numChilds++;
+ childIndex = i;
+ }
+ }
+ else
+ {
+ TestRemoveDescendant(descendant2, limitPos);
+ if (!descendant2.IsEmpty())
+ {
+ numChilds++;
+ childIndex = i;
+ }
+ }
+ }
+ if (numChilds > 1)
+ return;
+
+ CIndex nodePointerTemp = descendant.NodePointer;
+ if (numChilds == 1)
+ {
+ const CDescendant &descendant2 = node.Descendants[childIndex];
+ if (descendant2.IsNode())
+ m_Nodes[descendant2.NodePointer].NumSameBits += node.NumSameBits + kNumSubBits;
+ descendant = descendant2;
+ }
+ else
+ descendant.MakeEmpty();
+ node.NextFreeNode = m_FreeNode;
+ m_FreeNode = nodePointerTemp;
+ m_NumUsedNodes--;
+}
+
+void CPatricia::RemoveNode(UInt32 index)
+{
+ CNode &node = m_Nodes[index];
+ for (UInt32 i = 0; i < kNumSubNodes; i++)
+ {
+ CDescendant &descendant2 = node.Descendants[i];
+ if (descendant2.IsNode())
+ RemoveNode(descendant2.NodePointer);
+ }
+ node.NextFreeNode = m_FreeNode;
+ m_FreeNode = index;
+ m_NumUsedNodes--;
+}
+
+void CPatricia::TestRemoveNodes()
+{
+ UInt32 limitPos = kMatchStartValue + _pos - _sizeHistory + kNumHashBytes;
+
+ #ifdef __HASH_3
+
+ UInt32 limitPos2 = kMatchStartValue2 + _pos - _sizeHistory + kNumHashBytes;
+ for(UInt32 hash = 0; hash < kHash2Size; hash++)
+ {
+ CDescendant &descendant = m_Hash2Descendants[hash];
+ if (descendant.MatchPointer != kDescendantsNotInitilized2)
+ {
+ UInt32 base = hash << 8;
+ for (UInt32 i = 0; i < 0x100; i++)
+ {
+ CDescendant &descendant = m_HashDescendants[base + i];
+ if (descendant.IsEmpty())
+ continue;
+ if (descendant.IsMatch())
+ {
+ if (descendant.MatchPointer < limitPos)
+ descendant.MakeEmpty();
+ }
+ else
+ TestRemoveDescendant(descendant, limitPos);
+ }
+ }
+ if (descendant.MatchPointer < kMatchStartValue2)
+ continue;
+ if (descendant.MatchPointer < limitPos2)
+ descendant.MatchPointer = kDescendantEmptyValue2;
+ }
+
+ #else
+
+ for(UInt32 hash = 0; hash < kHashSize; hash++)
+ {
+ CDescendant &descendant = m_HashDescendants[hash];
+ if (descendant.IsEmpty())
+ continue;
+ if (descendant.IsMatch())
+ {
+ if (descendant.MatchPointer < limitPos)
+ descendant.MakeEmpty();
+ }
+ else
+ TestRemoveDescendant(descendant, limitPos);
+ }
+
+ #endif
+}
+
+void CPatricia::TestRemoveAndNormalizeDescendant(CDescendant &descendant,
+ UInt32 limitPos, UInt32 subValue)
+{
+ if (descendant.IsEmpty())
+ return;
+ if (descendant.IsMatch())
+ {
+ if (descendant.MatchPointer < limitPos)
+ descendant.MakeEmpty();
+ else
+ descendant.MatchPointer = descendant.MatchPointer - subValue;
+ return;
+ }
+ CNode &node = m_Nodes[descendant.NodePointer];
+ UInt32 numChilds = 0;
+ UInt32 childIndex = 0; // = 0 to disable GCC warning
+ for (UInt32 i = 0; i < kNumSubNodes; i++)
+ {
+ CDescendant &descendant2 = node.Descendants[i];
+ TestRemoveAndNormalizeDescendant(descendant2, limitPos, subValue);
+ if (!descendant2.IsEmpty())
+ {
+ numChilds++;
+ childIndex = i;
+ }
+ }
+ if (numChilds > 1)
+ {
+ node.LastMatch = node.LastMatch - subValue;
+ return;
+ }
+
+ CIndex nodePointerTemp = descendant.NodePointer;
+ if (numChilds == 1)
+ {
+ const CDescendant &descendant2 = node.Descendants[childIndex];
+ if (descendant2.IsNode())
+ m_Nodes[descendant2.NodePointer].NumSameBits += node.NumSameBits + kNumSubBits;
+ descendant = descendant2;
+ }
+ else
+ descendant.MakeEmpty();
+ node.NextFreeNode = m_FreeNode;
+ m_FreeNode = nodePointerTemp;
+ m_NumUsedNodes--;
+}
+
+void CPatricia::TestRemoveNodesAndNormalize()
+{
+ UInt32 subValue = _pos - _sizeHistory;
+ UInt32 limitPos = kMatchStartValue + _pos - _sizeHistory + kNumHashBytes;
+ CLZInWindow::ReduceOffsets(subValue);
+
+ #ifdef __HASH_3
+
+ UInt32 limitPos2 = kMatchStartValue2 + _pos - _sizeHistory + kNumHashBytes;
+ for(UInt32 hash = 0; hash < kHash2Size; hash++)
+ {
+ CDescendant &descendant = m_Hash2Descendants[hash];
+ if (descendant.MatchPointer != kDescendantsNotInitilized2)
+ {
+ UInt32 base = hash << 8;
+ for (UInt32 i = 0; i < 0x100; i++)
+ TestRemoveAndNormalizeDescendant(m_HashDescendants[base + i], limitPos, subValue);
+ }
+ if (descendant.MatchPointer < kMatchStartValue2)
+ continue;
+ if (descendant.MatchPointer < limitPos2)
+ descendant.MatchPointer = kDescendantEmptyValue2;
+ else
+ descendant.MatchPointer = descendant.MatchPointer - subValue;
+ }
+
+ #else
+
+ for(UInt32 hash = 0; hash < kHashSize; hash++)
+ TestRemoveAndNormalizeDescendant(m_HashDescendants[hash], limitPos, subValue);
+
+ #endif
+}
+
+#endif
+
+STDMETHODIMP_(Byte) CPatricia::GetIndexByte(Int32 index)
+{
+ return CLZInWindow::GetIndexByte(index);
+}
+
+STDMETHODIMP_(UInt32) CPatricia::GetMatchLen(Int32 index, UInt32 back, UInt32 limit)
+{
+ return CLZInWindow::GetMatchLen(index, back, limit);
+}
+
+STDMETHODIMP_(UInt32) CPatricia::GetNumAvailableBytes()
+{
+ return CLZInWindow::GetNumAvailableBytes();
+}
+
+STDMETHODIMP_(const Byte *) CPatricia::GetPointerToCurrentPos()
+{
+ return CLZInWindow::GetPointerToCurrentPos();
+}
+
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/StdAfx.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/StdAfx.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZ/StdAfx.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZ/StdAfx.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,6 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA/LZMADecoder.cpp squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA/LZMADecoder.cpp
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA/LZMADecoder.cpp 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA/LZMADecoder.cpp 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,342 @@
+// LZMADecoder.cpp
+
+#include "StdAfx.h"
+
+#include "LZMADecoder.h"
+#include "../../../Common/Defs.h"
+
+namespace NCompress {
+namespace NLZMA {
+
+const int kLenIdFinished = -1;
+const int kLenIdNeedInit = -2;
+
+void CDecoder::Init()
+{
+ {
+ for(int i = 0; i < kNumStates; i++)
+ {
+ for (UInt32 j = 0; j <= _posStateMask; j++)
+ {
+ _isMatch[i][j].Init();
+ _isRep0Long[i][j].Init();
+ }
+ _isRep[i].Init();
+ _isRepG0[i].Init();
+ _isRepG1[i].Init();
+ _isRepG2[i].Init();
+ }
+ }
+ {
+ for (UInt32 i = 0; i < kNumLenToPosStates; i++)
+ _posSlotDecoder[i].Init();
+ }
+ {
+ for(UInt32 i = 0; i < kNumFullDistances - kEndPosModelIndex; i++)
+ _posDecoders[i].Init();
+ }
+ _posAlignDecoder.Init();
+ _lenDecoder.Init(_posStateMask + 1);
+ _repMatchLenDecoder.Init(_posStateMask + 1);
+ _literalDecoder.Init();
+
+ _state.Init();
+ _reps[0] = _reps[1] = _reps[2] = _reps[3] = 0;
+}
+
+HRESULT CDecoder::CodeSpec(UInt32 curSize)
+{
+ if (_outSizeDefined)
+ {
+ const UInt64 rem = _outSize - _outWindowStream.GetProcessedSize();
+ if (curSize > rem)
+ curSize = (UInt32)rem;
+ }
+
+ if (_remainLen == kLenIdFinished)
+ return S_OK;
+ if (_remainLen == kLenIdNeedInit)
+ {
+ _rangeDecoder.Init();
+ Init();
+ _remainLen = 0;
+ }
+ if (curSize == 0)
+ return S_OK;
+
+ UInt32 rep0 = _reps[0];
+ UInt32 rep1 = _reps[1];
+ UInt32 rep2 = _reps[2];
+ UInt32 rep3 = _reps[3];
+ CState state = _state;
+ Byte previousByte;
+
+ while(_remainLen > 0 && curSize > 0)
+ {
+ previousByte = _outWindowStream.GetByte(rep0);
+ _outWindowStream.PutByte(previousByte);
+ _remainLen--;
+ curSize--;
+ }
+ UInt64 nowPos64 = _outWindowStream.GetProcessedSize();
+ if (nowPos64 == 0)
+ previousByte = 0;
+ else
+ previousByte = _outWindowStream.GetByte(0);
+
+ while(curSize > 0)
+ {
+ {
+ #ifdef _NO_EXCEPTIONS
+ if (_rangeDecoder.Stream.ErrorCode != S_OK)
+ return _rangeDecoder.Stream.ErrorCode;
+ #endif
+ if (_rangeDecoder.Stream.WasFinished())
+ return S_FALSE;
+ UInt32 posState = UInt32(nowPos64) & _posStateMask;
+ if (_isMatch[state.Index][posState].Decode(&_rangeDecoder) == 0)
+ {
+ if(!state.IsCharState())
+ previousByte = _literalDecoder.DecodeWithMatchByte(&_rangeDecoder,
+ (UInt32)nowPos64, previousByte, _outWindowStream.GetByte(rep0));
+ else
+ previousByte = _literalDecoder.DecodeNormal(&_rangeDecoder,
+ (UInt32)nowPos64, previousByte);
+ _outWindowStream.PutByte(previousByte);
+ state.UpdateChar();
+ curSize--;
+ nowPos64++;
+ }
+ else
+ {
+ UInt32 len;
+ if(_isRep[state.Index].Decode(&_rangeDecoder) == 1)
+ {
+ len = 0;
+ if(_isRepG0[state.Index].Decode(&_rangeDecoder) == 0)
+ {
+ if(_isRep0Long[state.Index][posState].Decode(&_rangeDecoder) == 0)
+ {
+ state.UpdateShortRep();
+ len = 1;
+ }
+ }
+ else
+ {
+ UInt32 distance;
+ if(_isRepG1[state.Index].Decode(&_rangeDecoder) == 0)
+ distance = rep1;
+ else
+ {
+ if (_isRepG2[state.Index].Decode(&_rangeDecoder) == 0)
+ distance = rep2;
+ else
+ {
+ distance = rep3;
+ rep3 = rep2;
+ }
+ rep2 = rep1;
+ }
+ rep1 = rep0;
+ rep0 = distance;
+ }
+ if (len == 0)
+ {
+ len = _repMatchLenDecoder.Decode(&_rangeDecoder, posState) + kMatchMinLen;
+ state.UpdateRep();
+ }
+ }
+ else
+ {
+ rep3 = rep2;
+ rep2 = rep1;
+ rep1 = rep0;
+ len = kMatchMinLen + _lenDecoder.Decode(&_rangeDecoder, posState);
+ state.UpdateMatch();
+ UInt32 posSlot = _posSlotDecoder[GetLenToPosState(len)].Decode(&_rangeDecoder);
+ if (posSlot >= kStartPosModelIndex)
+ {
+ UInt32 numDirectBits = (posSlot >> 1) - 1;
+ rep0 = ((2 | (posSlot & 1)) << numDirectBits);
+
+ if (posSlot < kEndPosModelIndex)
+ rep0 += NRangeCoder::ReverseBitTreeDecode(_posDecoders +
+ rep0 - posSlot - 1, &_rangeDecoder, numDirectBits);
+ else
+ {
+ rep0 += (_rangeDecoder.DecodeDirectBits(
+ numDirectBits - kNumAlignBits) << kNumAlignBits);
+ rep0 += _posAlignDecoder.ReverseDecode(&_rangeDecoder);
+ if (rep0 == 0xFFFFFFFF)
+ {
+ _remainLen = kLenIdFinished;
+ return S_OK;
+ }
+ }
+ }
+ else
+ rep0 = posSlot;
+ }
+ UInt32 locLen = len;
+ if (len > curSize)
+ locLen = (UInt32)curSize;
+ if (!_outWindowStream.CopyBlock(rep0, locLen))
+ return S_FALSE;
+ previousByte = _outWindowStream.GetByte(0);
+ curSize -= locLen;
+ nowPos64 += locLen;
+ len -= locLen;
+ if (len != 0)
+ {
+ _remainLen = (Int32)len;
+ break;
+ }
+
+ #ifdef _NO_EXCEPTIONS
+ if (_outWindowStream.ErrorCode != S_OK)
+ return _outWindowStream.ErrorCode;
+ #endif
+ }
+ }
+ }
+ if (_rangeDecoder.Stream.WasFinished())
+ return S_FALSE;
+ _reps[0] = rep0;
+ _reps[1] = rep1;
+ _reps[2] = rep2;
+ _reps[3] = rep3;
+ _state = state;
+
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UInt64 *, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ SetInStream(inStream);
+ _outWindowStream.SetStream(outStream);
+ SetOutStreamSize(outSize);
+ CDecoderFlusher flusher(this);
+
+ while (true)
+ {
+ UInt32 curSize = 1 << 18;
+ RINOK(CodeSpec(curSize));
+ if (_remainLen == kLenIdFinished)
+ break;
+ if (progress != NULL)
+ {
+ UInt64 inSize = _rangeDecoder.GetProcessedSize();
+ UInt64 nowPos64 = _outWindowStream.GetProcessedSize();
+ RINOK(progress->SetRatioInfo(&inSize, &nowPos64));
+ }
+ if (_outSizeDefined)
+ if (_outWindowStream.GetProcessedSize() >= _outSize)
+ break;
+ }
+ flusher.NeedFlush = false;
+ return Flush();
+}
+
+
+#ifdef _NO_EXCEPTIONS
+
+#define LZMA_TRY_BEGIN
+#define LZMA_TRY_END
+
+#else
+
+#define LZMA_TRY_BEGIN try {
+#define LZMA_TRY_END } \
+ catch(const CInBufferException &e) { return e.ErrorCode; } \
+ catch(const CLZOutWindowException &e) { return e.ErrorCode; } \
+ catch(...) { return S_FALSE; }
+
+#endif
+
+
+STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ LZMA_TRY_BEGIN
+ return CodeReal(inStream, outStream, inSize, outSize, progress);
+ LZMA_TRY_END
+}
+
+STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *properties, UInt32 size)
+{
+ if (size < 5)
+ return E_INVALIDARG;
+ int lc = properties[0] % 9;
+ Byte remainder = (Byte)(properties[0] / 9);
+ int lp = remainder % 5;
+ int pb = remainder / 5;
+ UInt32 dictionarySize = 0;
+ for (int i = 0; i < 4; i++)
+ dictionarySize += ((UInt32)(properties[1 + i])) << (i * 8);
+ return SetDecoderPropertiesRaw(lc, lp, pb, dictionarySize);
+}
+
+STDMETHODIMP CDecoder::SetDecoderPropertiesRaw(int lc, int lp, int pb, UInt32 dictionarySize)
+{
+ if (pb > NLength::kNumPosStatesBitsMax)
+ return E_INVALIDARG;
+ _posStateMask = (1 << pb) - 1;
+ if (!_outWindowStream.Create(dictionarySize))
+ return E_OUTOFMEMORY;
+ if (!_literalDecoder.Create(lp, lc))
+ return E_OUTOFMEMORY;
+ if (!_rangeDecoder.Create(1 << 20))
+ return E_OUTOFMEMORY;
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value)
+{
+ *value = _rangeDecoder.GetProcessedSize();
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream)
+{
+ _rangeDecoder.SetStream(inStream);
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::ReleaseInStream()
+{
+ _rangeDecoder.ReleaseStream();
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize)
+{
+ if ((_outSizeDefined = (outSize != NULL)))
+ _outSize = *outSize;
+ _remainLen = kLenIdNeedInit;
+ _outWindowStream.Init();
+ return S_OK;
+}
+
+#ifdef _ST_MODE
+
+STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ LZMA_TRY_BEGIN
+ if (processedSize)
+ *processedSize = 0;
+ const UInt64 startPos = _outWindowStream.GetProcessedSize();
+ _outWindowStream.SetMemStream((Byte *)data);
+ RINOK(CodeSpec(size));
+ if (processedSize)
+ *processedSize = (UInt32)(_outWindowStream.GetProcessedSize() - startPos);
+ return Flush();
+ LZMA_TRY_END
+}
+
+#endif
+
+}}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA/LZMADecoder.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA/LZMADecoder.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA/LZMADecoder.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA/LZMADecoder.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,249 @@
+// LZMA/Decoder.h
+
+#ifndef __LZMA_DECODER_H
+#define __LZMA_DECODER_H
+
+#include "../../../Common/MyCom.h"
+#include "../../../Common/Alloc.h"
+#include "../../ICoder.h"
+#include "../LZ/LZOutWindow.h"
+#include "../RangeCoder/RangeCoderBitTree.h"
+
+#include "LZMA.h"
+
+namespace NCompress {
+namespace NLZMA {
+
+typedef NRangeCoder::CBitDecoder<kNumMoveBits> CMyBitDecoder;
+
+class CLiteralDecoder2
+{
+ CMyBitDecoder _decoders[0x300];
+public:
+ void Init()
+ {
+ for (int i = 0; i < 0x300; i++)
+ _decoders[i].Init();
+ }
+ Byte DecodeNormal(NRangeCoder::CDecoder *rangeDecoder)
+ {
+ UInt32 symbol = 1;
+ RC_INIT_VAR
+ do
+ {
+ // symbol = (symbol << 1) | _decoders[0][symbol].Decode(rangeDecoder);
+ RC_GETBIT(kNumMoveBits, _decoders[symbol].Prob, symbol)
+ }
+ while (symbol < 0x100);
+ RC_FLUSH_VAR
+ return (Byte)symbol;
+ }
+ Byte DecodeWithMatchByte(NRangeCoder::CDecoder *rangeDecoder, Byte matchByte)
+ {
+ UInt32 symbol = 1;
+ RC_INIT_VAR
+ do
+ {
+ UInt32 matchBit = (matchByte >> 7) & 1;
+ matchByte <<= 1;
+ // UInt32 bit = _decoders[1 + matchBit][symbol].Decode(rangeDecoder);
+ // symbol = (symbol << 1) | bit;
+ UInt32 bit;
+ RC_GETBIT2(kNumMoveBits, _decoders[0x100 + (matchBit << 8) + symbol].Prob, symbol,
+ bit = 0, bit = 1)
+ if (matchBit != bit)
+ {
+ while (symbol < 0x100)
+ {
+ // symbol = (symbol << 1) | _decoders[0][symbol].Decode(rangeDecoder);
+ RC_GETBIT(kNumMoveBits, _decoders[symbol].Prob, symbol)
+ }
+ break;
+ }
+ }
+ while (symbol < 0x100);
+ RC_FLUSH_VAR
+ return (Byte)symbol;
+ }
+};
+
+class CLiteralDecoder
+{
+ CLiteralDecoder2 *_coders;
+ int _numPrevBits;
+ int _numPosBits;
+ UInt32 _posMask;
+public:
+ CLiteralDecoder(): _coders(0) {}
+ ~CLiteralDecoder() { Free(); }
+ void Free()
+ {
+ MyFree(_coders);
+ _coders = 0;
+ }
+ bool Create(int numPosBits, int numPrevBits)
+ {
+ if (_coders == 0 || (numPosBits + numPrevBits) !=
+ (_numPrevBits + _numPosBits) )
+ {
+ Free();
+ UInt32 numStates = 1 << (numPosBits + numPrevBits);
+ _coders = (CLiteralDecoder2 *)MyAlloc(numStates * sizeof(CLiteralDecoder2));
+ }
+ _numPosBits = numPosBits;
+ _posMask = (1 << numPosBits) - 1;
+ _numPrevBits = numPrevBits;
+ return (_coders != 0);
+ }
+ void Init()
+ {
+ UInt32 numStates = 1 << (_numPrevBits + _numPosBits);
+ for (UInt32 i = 0; i < numStates; i++)
+ _coders[i].Init();
+ }
+ UInt32 GetState(UInt32 pos, Byte prevByte) const
+ { return ((pos & _posMask) << _numPrevBits) + (prevByte >> (8 - _numPrevBits)); }
+ Byte DecodeNormal(NRangeCoder::CDecoder *rangeDecoder, UInt32 pos, Byte prevByte)
+ { return _coders[GetState(pos, prevByte)].DecodeNormal(rangeDecoder); }
+ Byte DecodeWithMatchByte(NRangeCoder::CDecoder *rangeDecoder, UInt32 pos, Byte prevByte, Byte matchByte)
+ { return _coders[GetState(pos, prevByte)].DecodeWithMatchByte(rangeDecoder, matchByte); }
+};
+
+namespace NLength {
+
+class CDecoder
+{
+ CMyBitDecoder _choice;
+ CMyBitDecoder _choice2;
+ NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumLowBits> _lowCoder[kNumPosStatesMax];
+ NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumMidBits> _midCoder[kNumPosStatesMax];
+ NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumHighBits> _highCoder;
+public:
+ void Init(UInt32 numPosStates)
+ {
+ _choice.Init();
+ _choice2.Init();
+ for (UInt32 posState = 0; posState < numPosStates; posState++)
+ {
+ _lowCoder[posState].Init();
+ _midCoder[posState].Init();
+ }
+ _highCoder.Init();
+ }
+ UInt32 Decode(NRangeCoder::CDecoder *rangeDecoder, UInt32 posState)
+ {
+ if(_choice.Decode(rangeDecoder) == 0)
+ return _lowCoder[posState].Decode(rangeDecoder);
+ if(_choice2.Decode(rangeDecoder) == 0)
+ return kNumLowSymbols + _midCoder[posState].Decode(rangeDecoder);
+ return kNumLowSymbols + kNumMidSymbols + _highCoder.Decode(rangeDecoder);
+ }
+};
+
+}
+
+class CDecoder:
+ public ICompressCoder,
+ public ICompressSetDecoderProperties2,
+ #ifdef _ST_MODE
+ public ICompressSetInStream,
+ public ICompressSetOutStreamSize,
+ public ISequentialInStream,
+ #endif
+ public CMyUnknownImp
+{
+ CLZOutWindow _outWindowStream;
+ NRangeCoder::CDecoder _rangeDecoder;
+
+ CMyBitDecoder _isMatch[kNumStates][NLength::kNumPosStatesMax];
+ CMyBitDecoder _isRep[kNumStates];
+ CMyBitDecoder _isRepG0[kNumStates];
+ CMyBitDecoder _isRepG1[kNumStates];
+ CMyBitDecoder _isRepG2[kNumStates];
+ CMyBitDecoder _isRep0Long[kNumStates][NLength::kNumPosStatesMax];
+
+ NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumPosSlotBits> _posSlotDecoder[kNumLenToPosStates];
+
+ CMyBitDecoder _posDecoders[kNumFullDistances - kEndPosModelIndex];
+ NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumAlignBits> _posAlignDecoder;
+
+ NLength::CDecoder _lenDecoder;
+ NLength::CDecoder _repMatchLenDecoder;
+
+ CLiteralDecoder _literalDecoder;
+
+ UInt32 _posStateMask;
+
+ ///////////////////
+ // State
+ UInt32 _reps[4];
+ CState _state;
+ Int32 _remainLen; // -1 means end of stream. // -2 means need Init
+ UInt64 _outSize;
+ bool _outSizeDefined;
+
+ void Init();
+ HRESULT CodeSpec(UInt32 size);
+public:
+
+ #ifdef _ST_MODE
+ MY_UNKNOWN_IMP4(
+ ICompressSetDecoderProperties2,
+ ICompressSetInStream,
+ ICompressSetOutStreamSize,
+ ISequentialInStream)
+ #else
+ MY_UNKNOWN_IMP1(
+ ICompressSetDecoderProperties2)
+ #endif
+
+ void ReleaseStreams()
+ {
+ _outWindowStream.ReleaseStream();
+ ReleaseInStream();
+ }
+
+ class CDecoderFlusher
+ {
+ CDecoder *_decoder;
+ public:
+ bool NeedFlush;
+ CDecoderFlusher(CDecoder *decoder): _decoder(decoder), NeedFlush(true) {}
+ ~CDecoderFlusher()
+ {
+ if (NeedFlush)
+ _decoder->Flush();
+ _decoder->ReleaseStreams();
+ }
+ };
+
+ HRESULT Flush() { return _outWindowStream.Flush(); }
+
+ STDMETHOD(CodeReal)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress);
+
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress);
+
+ STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
+ STDMETHOD(SetDecoderPropertiesRaw)(int lc, int lp, int pb, UInt32 dictionarySize);
+
+ STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
+
+ STDMETHOD(SetInStream)(ISequentialInStream *inStream);
+ STDMETHOD(ReleaseInStream)();
+ STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);
+
+ #ifdef _ST_MODE
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+ #endif
+
+ CDecoder(): _outSizeDefined(false) {}
+ virtual ~CDecoder() {}
+};
+
+}}
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA/LZMAEncoder.cpp squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA/LZMAEncoder.cpp
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA/LZMAEncoder.cpp 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA/LZMAEncoder.cpp 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,1504 @@
+// LZMA/Encoder.cpp
+
+#include "StdAfx.h"
+
+#include "../../../Common/Defs.h"
+#include "../../Common/StreamUtils.h"
+
+#include "LZMAEncoder.h"
+
+// for minimal compressing code size define these:
+// #define COMPRESS_MF_BT
+// #define COMPRESS_MF_BT4
+
+#if !defined(COMPRESS_MF_BT) && !defined(COMPRESS_MF_PAT) && !defined(COMPRESS_MF_HC)
+#define COMPRESS_MF_BT
+#define COMPRESS_MF_PAT
+#define COMPRESS_MF_HC
+#endif
+
+#ifdef COMPRESS_MF_BT
+#if !defined(COMPRESS_MF_BT2) && !defined(COMPRESS_MF_BT3) && !defined(COMPRESS_MF_BT4) && !defined(COMPRESS_MF_BT4B)
+#define COMPRESS_MF_BT2
+#define COMPRESS_MF_BT3
+#define COMPRESS_MF_BT4
+#define COMPRESS_MF_BT4B
+#endif
+#ifdef COMPRESS_MF_BT2
+#include "../LZ/BinTree/BinTree2.h"
+#endif
+#ifdef COMPRESS_MF_BT3
+#include "../LZ/BinTree/BinTree3.h"
+#endif
+#ifdef COMPRESS_MF_BT4
+#include "../LZ/BinTree/BinTree4.h"
+#endif
+#ifdef COMPRESS_MF_BT4B
+#include "../LZ/BinTree/BinTree4b.h"
+#endif
+#endif
+
+#ifdef COMPRESS_MF_PAT
+#include "../LZ/Patricia/Pat2.h"
+#include "../LZ/Patricia/Pat2H.h"
+#include "../LZ/Patricia/Pat3H.h"
+#include "../LZ/Patricia/Pat4H.h"
+#include "../LZ/Patricia/Pat2R.h"
+#endif
+
+#ifdef COMPRESS_MF_HC
+#include "../LZ/HashChain/HC3.h"
+#include "../LZ/HashChain/HC4.h"
+#endif
+
+#ifdef COMPRESS_MF_MT
+#include "../LZ/MT/MT.h"
+#endif
+
+namespace NCompress {
+namespace NLZMA {
+
+const int kDefaultDictionaryLogSize = 20;
+const UInt32 kNumFastBytesDefault = 0x20;
+
+enum
+{
+ kBT2,
+ kBT3,
+ kBT4,
+ kBT4B,
+ kPat2,
+ kPat2H,
+ kPat3H,
+ kPat4H,
+ kPat2R,
+ kHC3,
+ kHC4
+};
+
+static const wchar_t *kMatchFinderIDs[] =
+{
+ L"BT2",
+ L"BT3",
+ L"BT4",
+ L"BT4B",
+ L"PAT2",
+ L"PAT2H",
+ L"PAT3H",
+ L"PAT4H",
+ L"PAT2R",
+ L"HC3",
+ L"HC4"
+};
+
+Byte g_FastPos[1024];
+
+class CFastPosInit
+{
+public:
+ CFastPosInit() { Init(); }
+ void Init()
+ {
+ const Byte kFastSlots = 20;
+ int c = 2;
+ g_FastPos[0] = 0;
+ g_FastPos[1] = 1;
+
+ for (Byte slotFast = 2; slotFast < kFastSlots; slotFast++)
+ {
+ UInt32 k = (1 << ((slotFast >> 1) - 1));
+ for (UInt32 j = 0; j < k; j++, c++)
+ g_FastPos[c] = slotFast;
+ }
+ }
+} g_FastPosInit;
+
+
+void CLiteralEncoder2::Encode(NRangeCoder::CEncoder *rangeEncoder, Byte symbol)
+{
+ UInt32 context = 1;
+ int i = 8;
+ do
+ {
+ i--;
+ UInt32 bit = (symbol >> i) & 1;
+ _encoders[context].Encode(rangeEncoder, bit);
+ context = (context << 1) | bit;
+ }
+ while(i != 0);
+}
+
+void CLiteralEncoder2::EncodeMatched(NRangeCoder::CEncoder *rangeEncoder,
+ Byte matchByte, Byte symbol)
+{
+ UInt32 context = 1;
+ int i = 8;
+ do
+ {
+ i--;
+ UInt32 bit = (symbol >> i) & 1;
+ UInt32 matchBit = (matchByte >> i) & 1;
+ _encoders[0x100 + (matchBit << 8) + context].Encode(rangeEncoder, bit);
+ context = (context << 1) | bit;
+ if (matchBit != bit)
+ {
+ while(i != 0)
+ {
+ i--;
+ UInt32 bit = (symbol >> i) & 1;
+ _encoders[context].Encode(rangeEncoder, bit);
+ context = (context << 1) | bit;
+ }
+ break;
+ }
+ }
+ while(i != 0);
+}
+
+UInt32 CLiteralEncoder2::GetPrice(bool matchMode, Byte matchByte, Byte symbol) const
+{
+ UInt32 price = 0;
+ UInt32 context = 1;
+ int i = 8;
+ if (matchMode)
+ {
+ do
+ {
+ i--;
+ UInt32 matchBit = (matchByte >> i) & 1;
+ UInt32 bit = (symbol >> i) & 1;
+ price += _encoders[0x100 + (matchBit << 8) + context].GetPrice(bit);
+ context = (context << 1) | bit;
+ if (matchBit != bit)
+ break;
+ }
+ while (i != 0);
+ }
+ while(i != 0)
+ {
+ i--;
+ UInt32 bit = (symbol >> i) & 1;
+ price += _encoders[context].GetPrice(bit);
+ context = (context << 1) | bit;
+ }
+ return price;
+};
+
+
+namespace NLength {
+
+void CEncoder::Init(UInt32 numPosStates)
+{
+ _choice.Init();
+ _choice2.Init();
+ for (UInt32 posState = 0; posState < numPosStates; posState++)
+ {
+ _lowCoder[posState].Init();
+ _midCoder[posState].Init();
+ }
+ _highCoder.Init();
+}
+
+void CEncoder::Encode(NRangeCoder::CEncoder *rangeEncoder, UInt32 symbol, UInt32 posState)
+{
+ if(symbol < kNumLowSymbols)
+ {
+ _choice.Encode(rangeEncoder, 0);
+ _lowCoder[posState].Encode(rangeEncoder, symbol);
+ }
+ else
+ {
+ _choice.Encode(rangeEncoder, 1);
+ if(symbol < kNumLowSymbols + kNumMidSymbols)
+ {
+ _choice2.Encode(rangeEncoder, 0);
+ _midCoder[posState].Encode(rangeEncoder, symbol - kNumLowSymbols);
+ }
+ else
+ {
+ _choice2.Encode(rangeEncoder, 1);
+ _highCoder.Encode(rangeEncoder, symbol - kNumLowSymbols - kNumMidSymbols);
+ }
+ }
+}
+
+UInt32 CEncoder::GetPrice(UInt32 symbol, UInt32 posState) const
+{
+ if(symbol < kNumLowSymbols)
+ return _choice.GetPrice0() + _lowCoder[posState].GetPrice(symbol);
+ UInt32 price = _choice.GetPrice1();
+ if(symbol < kNumLowSymbols + kNumMidSymbols)
+ {
+ price += _choice2.GetPrice0();
+ price += _midCoder[posState].GetPrice(symbol - kNumLowSymbols);
+ }
+ else
+ {
+ price += _choice2.GetPrice1();
+ price += _highCoder.GetPrice(symbol - kNumLowSymbols - kNumMidSymbols);
+ }
+ return price;
+}
+
+}
+CEncoder::CEncoder():
+ _numFastBytes(kNumFastBytesDefault),
+ _distTableSize(kDefaultDictionaryLogSize * 2),
+ _posStateBits(2),
+ _posStateMask(4 - 1),
+ _numLiteralPosStateBits(0),
+ _numLiteralContextBits(3),
+ _dictionarySize(1 << kDefaultDictionaryLogSize),
+ _dictionarySizePrev(UInt32(-1)),
+ _numFastBytesPrev(UInt32(-1)),
+ _matchFinderIndex(kBT4),
+ #ifdef COMPRESS_MF_MT
+ _multiThread(false),
+ #endif
+ _writeEndMark(false)
+{
+ _maxMode = false;
+ _fastMode = false;
+}
+
+HRESULT CEncoder::Create()
+{
+ if (!_rangeEncoder.Create(1 << 20))
+ return E_OUTOFMEMORY;
+ if (!_matchFinder)
+ {
+ switch(_matchFinderIndex)
+ {
+ #ifdef COMPRESS_MF_BT
+ #ifdef COMPRESS_MF_BT2
+ case kBT2:
+ _matchFinder = new NBT2::CMatchFinderBinTree;
+ break;
+ #endif
+ #ifdef COMPRESS_MF_BT3
+ case kBT3:
+ _matchFinder = new NBT3::CMatchFinderBinTree;
+ break;
+ #endif
+ #ifdef COMPRESS_MF_BT4
+ case kBT4:
+ _matchFinder = new NBT4::CMatchFinderBinTree;
+ break;
+ #endif
+ #ifdef COMPRESS_MF_BT4B
+ case kBT4B:
+ _matchFinder = new NBT4B::CMatchFinderBinTree;
+ break;
+ #endif
+ #endif
+
+ #ifdef COMPRESS_MF_PAT
+ case kPat2:
+ _matchFinder = new NPat2::CPatricia;
+ break;
+ case kPat2H:
+ _matchFinder = new NPat2H::CPatricia;
+ break;
+ case kPat3H:
+ _matchFinder = new NPat3H::CPatricia;
+ break;
+ case kPat4H:
+ _matchFinder = new NPat4H::CPatricia;
+ break;
+ case kPat2R:
+ _matchFinder = new NPat2R::CPatricia;
+ break;
+ #endif
+
+ #ifdef COMPRESS_MF_HC
+ case kHC3:
+ _matchFinder = new NHC3::CMatchFinderHC;
+ break;
+ case kHC4:
+ _matchFinder = new NHC4::CMatchFinderHC;
+ break;
+ #endif
+ }
+ if (_matchFinder == 0)
+ return E_OUTOFMEMORY;
+
+ #ifdef COMPRESS_MF_MT
+ if (_multiThread && !(_fastMode && (_matchFinderIndex == kHC3 || _matchFinderIndex == kHC4)))
+ {
+ CMatchFinderMT *mfSpec = new CMatchFinderMT;
+ if (mfSpec == 0)
+ return E_OUTOFMEMORY;
+ CMyComPtr<IMatchFinder> mf = mfSpec;
+ RINOK(mfSpec->SetMatchFinder(_matchFinder));
+ _matchFinder.Release();
+ _matchFinder = mf;
+ }
+ #endif
+ }
+
+ if (!_literalEncoder.Create(_numLiteralPosStateBits, _numLiteralContextBits))
+ return E_OUTOFMEMORY;
+
+ if (_dictionarySize == _dictionarySizePrev && _numFastBytesPrev == _numFastBytes)
+ return S_OK;
+ RINOK(_matchFinder->Create(_dictionarySize, kNumOpts, _numFastBytes,
+ kMatchMaxLen * 2 + 1 - _numFastBytes));
+ _dictionarySizePrev = _dictionarySize;
+ _numFastBytesPrev = _numFastBytes;
+ return S_OK;
+}
+
+static bool AreStringsEqual(const wchar_t *base, const wchar_t *testString)
+{
+ while (true)
+ {
+ wchar_t c = *testString;
+ if (c >= 'a' && c <= 'z')
+ c -= 0x20;
+ if (*base != c)
+ return false;
+ if (c == 0)
+ return true;
+ base++;
+ testString++;
+ }
+}
+
+static int FindMatchFinder(const wchar_t *s)
+{
+ for (int m = 0; m < (int)(sizeof(kMatchFinderIDs) / sizeof(kMatchFinderIDs[0])); m++)
+ if (AreStringsEqual(kMatchFinderIDs[m], s))
+ return m;
+ return -1;
+}
+
+STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs,
+ const PROPVARIANT *properties, UInt32 numProperties)
+{
+ for (UInt32 i = 0; i < numProperties; i++)
+ {
+ const PROPVARIANT &prop = properties[i];
+ switch(propIDs[i])
+ {
+ case NCoderPropID::kNumFastBytes:
+ {
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ UInt32 numFastBytes = prop.ulVal;
+ if(numFastBytes < 5 || numFastBytes > kMatchMaxLen)
+ return E_INVALIDARG;
+ _numFastBytes = numFastBytes;
+ break;
+ }
+ case NCoderPropID::kAlgorithm:
+ {
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ UInt32 maximize = prop.ulVal;
+ _fastMode = (maximize == 0);
+ _maxMode = (maximize >= 2);
+ break;
+ }
+ case NCoderPropID::kMatchFinder:
+ {
+ if (prop.vt != VT_BSTR)
+ return E_INVALIDARG;
+ int matchFinderIndexPrev = _matchFinderIndex;
+ int m = FindMatchFinder(prop.bstrVal);
+ if (m < 0)
+ return E_INVALIDARG;
+ _matchFinderIndex = m;
+ if (_matchFinder && matchFinderIndexPrev != _matchFinderIndex)
+ {
+ _dictionarySizePrev = UInt32(-1);
+ _matchFinder.Release();
+ }
+ break;
+ }
+ #ifdef COMPRESS_MF_MT
+ case NCoderPropID::kMultiThread:
+ {
+ if (prop.vt != VT_BOOL)
+ return E_INVALIDARG;
+ bool newMultiThread = (prop.boolVal == VARIANT_TRUE);
+ if (newMultiThread != _multiThread)
+ {
+ _dictionarySizePrev = UInt32(-1);
+ _matchFinder.Release();
+ }
+ _multiThread = newMultiThread;
+ break;
+ }
+ #endif
+ case NCoderPropID::kDictionarySize:
+ {
+ const int kDicLogSizeMaxCompress = 28;
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ UInt32 dictionarySize = prop.ulVal;
+ if (dictionarySize < UInt32(1 << kDicLogSizeMin) ||
+ dictionarySize > UInt32(1 << kDicLogSizeMaxCompress))
+ return E_INVALIDARG;
+ _dictionarySize = dictionarySize;
+ UInt32 dicLogSize;
+ for(dicLogSize = 0; dicLogSize < (UInt32)kDicLogSizeMaxCompress; dicLogSize++)
+ if (dictionarySize <= (UInt32(1) << dicLogSize))
+ break;
+ _distTableSize = dicLogSize * 2;
+ break;
+ }
+ case NCoderPropID::kPosStateBits:
+ {
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ UInt32 value = prop.ulVal;
+ if (value > (UInt32)NLength::kNumPosStatesBitsEncodingMax)
+ return E_INVALIDARG;
+ _posStateBits = value;
+ _posStateMask = (1 << _posStateBits) - 1;
+ break;
+ }
+ case NCoderPropID::kLitPosBits:
+ {
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ UInt32 value = prop.ulVal;
+ if (value > (UInt32)kNumLitPosStatesBitsEncodingMax)
+ return E_INVALIDARG;
+ _numLiteralPosStateBits = value;
+ break;
+ }
+ case NCoderPropID::kLitContextBits:
+ {
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ UInt32 value = prop.ulVal;
+ if (value > (UInt32)kNumLitContextBitsMax)
+ return E_INVALIDARG;
+ _numLiteralContextBits = value;
+ break;
+ }
+ case NCoderPropID::kEndMarker:
+ {
+ if (prop.vt != VT_BOOL)
+ return E_INVALIDARG;
+ SetWriteEndMarkerMode(prop.boolVal == VARIANT_TRUE);
+ break;
+ }
+ default:
+ return E_INVALIDARG;
+ }
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
+{
+ const UInt32 kPropSize = 5;
+ Byte properties[kPropSize];
+ properties[0] = (_posStateBits * 5 + _numLiteralPosStateBits) * 9 + _numLiteralContextBits;
+ for (int i = 0; i < 4; i++)
+ properties[1 + i] = Byte(_dictionarySize >> (8 * i));
+ return WriteStream(outStream, properties, kPropSize, NULL);
+}
+
+STDMETHODIMP CEncoder::SetOutStream(ISequentialOutStream *outStream)
+{
+ _rangeEncoder.SetStream(outStream);
+ return S_OK;
+}
+
+STDMETHODIMP CEncoder::ReleaseOutStream()
+{
+ _rangeEncoder.ReleaseStream();
+ return S_OK;
+}
+
+HRESULT CEncoder::Init()
+{
+ CBaseState::Init();
+
+ // RINOK(_matchFinder->Init(inStream));
+ _rangeEncoder.Init();
+
+ for(int i = 0; i < kNumStates; i++)
+ {
+ for (UInt32 j = 0; j <= _posStateMask; j++)
+ {
+ _isMatch[i][j].Init();
+ _isRep0Long[i][j].Init();
+ }
+ _isRep[i].Init();
+ _isRepG0[i].Init();
+ _isRepG1[i].Init();
+ _isRepG2[i].Init();
+ }
+
+ _literalEncoder.Init();
+
+ // _repMatchLenEncoder.Init();
+
+ {
+ for(UInt32 i = 0; i < kNumLenToPosStates; i++)
+ _posSlotEncoder[i].Init();
+ }
+ {
+ for(UInt32 i = 0; i < kNumFullDistances - kEndPosModelIndex; i++)
+ _posEncoders[i].Init();
+ }
+
+ _lenEncoder.Init(1 << _posStateBits);
+ _repMatchLenEncoder.Init(1 << _posStateBits);
+
+ _posAlignEncoder.Init();
+
+ _longestMatchWasFound = false;
+ _optimumEndIndex = 0;
+ _optimumCurrentIndex = 0;
+ _additionalOffset = 0;
+
+ return S_OK;
+}
+
+HRESULT CEncoder::MovePos(UInt32 num)
+{
+ for (;num != 0; num--)
+ {
+ _matchFinder->DummyLongestMatch();
+ RINOK(_matchFinder->MovePos());
+ _additionalOffset++;
+ }
+ return S_OK;
+}
+
+UInt32 CEncoder::Backward(UInt32 &backRes, UInt32 cur)
+{
+ _optimumEndIndex = cur;
+ UInt32 posMem = _optimum[cur].PosPrev;
+ UInt32 backMem = _optimum[cur].BackPrev;
+ do
+ {
+ if (_optimum[cur].Prev1IsChar)
+ {
+ _optimum[posMem].MakeAsChar();
+ _optimum[posMem].PosPrev = posMem - 1;
+ if (_optimum[cur].Prev2)
+ {
+ _optimum[posMem - 1].Prev1IsChar = false;
+ _optimum[posMem - 1].PosPrev = _optimum[cur].PosPrev2;
+ _optimum[posMem - 1].BackPrev = _optimum[cur].BackPrev2;
+ }
+ }
+ UInt32 posPrev = posMem;
+ UInt32 backCur = backMem;
+
+ backMem = _optimum[posPrev].BackPrev;
+ posMem = _optimum[posPrev].PosPrev;
+
+ _optimum[posPrev].BackPrev = backCur;
+ _optimum[posPrev].PosPrev = cur;
+ cur = posPrev;
+ }
+ while(cur != 0);
+ backRes = _optimum[0].BackPrev;
+ _optimumCurrentIndex = _optimum[0].PosPrev;
+ return _optimumCurrentIndex;
+}
+
+/*
+inline UInt32 GetMatchLen(const Byte *data, UInt32 back, UInt32 limit)
+{
+ back++;
+ for(UInt32 i = 0; i < limit && data[i] == data[i - back]; i++);
+ return i;
+}
+*/
+
+
+/*
+Out:
+ (lenRes == 1) && (backRes == 0xFFFFFFFF) means Literal
+*/
+
+HRESULT CEncoder::GetOptimum(UInt32 position, UInt32 &backRes, UInt32 &lenRes)
+{
+ if(_optimumEndIndex != _optimumCurrentIndex)
+ {
+ const COptimal &optimum = _optimum[_optimumCurrentIndex];
+ lenRes = optimum.PosPrev - _optimumCurrentIndex;
+ backRes = optimum.BackPrev;
+ _optimumCurrentIndex = optimum.PosPrev;
+ return S_OK;
+ }
+ _optimumCurrentIndex = 0;
+ _optimumEndIndex = 0; // test it;
+
+ UInt32 lenMain;
+ if (!_longestMatchWasFound)
+ {
+ RINOK(ReadMatchDistances(lenMain));
+ }
+ else
+ {
+ lenMain = _longestMatchLength;
+ _longestMatchWasFound = false;
+ }
+
+
+ UInt32 reps[kNumRepDistances];
+ UInt32 repLens[kNumRepDistances];
+ UInt32 repMaxIndex = 0;
+ UInt32 i;
+ for(i = 0; i < kNumRepDistances; i++)
+ {
+ reps[i] = _repDistances[i];
+ repLens[i] = _matchFinder->GetMatchLen(0 - 1, reps[i], kMatchMaxLen);
+ if (i == 0 || repLens[i] > repLens[repMaxIndex])
+ repMaxIndex = i;
+ }
+ if(repLens[repMaxIndex] >= _numFastBytes)
+ {
+ backRes = repMaxIndex;
+ lenRes = repLens[repMaxIndex];
+ return MovePos(lenRes - 1);
+ }
+
+ if(lenMain >= _numFastBytes)
+ {
+ backRes = _matchDistances[_numFastBytes] + kNumRepDistances;
+ lenRes = lenMain;
+ return MovePos(lenMain - 1);
+ }
+ Byte currentByte = _matchFinder->GetIndexByte(0 - 1);
+
+ _optimum[0].State = _state;
+
+ Byte matchByte;
+
+ matchByte = _matchFinder->GetIndexByte(0 - _repDistances[0] - 1 - 1);
+
+ UInt32 posState = (position & _posStateMask);
+
+ _optimum[1].Price = _isMatch[_state.Index][posState].GetPrice0() +
+ _literalEncoder.GetPrice(position, _previousByte, !_state.IsCharState(), matchByte, currentByte);
+ _optimum[1].MakeAsChar();
+
+ _optimum[1].PosPrev = 0;
+
+ for (i = 0; i < kNumRepDistances; i++)
+ _optimum[0].Backs[i] = reps[i];
+
+ UInt32 matchPrice = _isMatch[_state.Index][posState].GetPrice1();
+ UInt32 repMatchPrice = matchPrice + _isRep[_state.Index].GetPrice1();
+
+ if(matchByte == currentByte)
+ {
+ UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(_state, posState);
+ if(shortRepPrice < _optimum[1].Price)
+ {
+ _optimum[1].Price = shortRepPrice;
+ _optimum[1].MakeAsShortRep();
+ }
+ }
+ if(lenMain < 2)
+ {
+ backRes = _optimum[1].BackPrev;
+ lenRes = 1;
+ return S_OK;
+ }
+
+
+ UInt32 normalMatchPrice = matchPrice +
+ _isRep[_state.Index].GetPrice0();
+
+ if (lenMain <= repLens[repMaxIndex])
+ lenMain = 0;
+
+ UInt32 len;
+ for(len = 2; len <= lenMain; len++)
+ {
+ _optimum[len].PosPrev = 0;
+ _optimum[len].BackPrev = _matchDistances[len] + kNumRepDistances;
+ _optimum[len].Price = normalMatchPrice +
+ GetPosLenPrice(_matchDistances[len], len, posState);
+ _optimum[len].Prev1IsChar = false;
+ }
+
+ if (lenMain < repLens[repMaxIndex])
+ lenMain = repLens[repMaxIndex];
+
+ for (; len <= lenMain; len++)
+ _optimum[len].Price = kIfinityPrice;
+
+ for(i = 0; i < kNumRepDistances; i++)
+ {
+ UInt32 repLen = repLens[i];
+ for(UInt32 lenTest = 2; lenTest <= repLen; lenTest++)
+ {
+ UInt32 curAndLenPrice = repMatchPrice + GetRepPrice(i, lenTest, _state, posState);
+ COptimal &optimum = _optimum[lenTest];
+ if (curAndLenPrice < optimum.Price)
+ {
+ optimum.Price = curAndLenPrice;
+ optimum.PosPrev = 0;
+ optimum.BackPrev = i;
+ optimum.Prev1IsChar = false;
+ }
+ }
+ }
+
+ UInt32 cur = 0;
+ UInt32 lenEnd = lenMain;
+
+ while(true)
+ {
+ cur++;
+ if(cur == lenEnd)
+ {
+ lenRes = Backward(backRes, cur);
+ return S_OK;
+ }
+ position++;
+ COptimal &curOptimum = _optimum[cur];
+ UInt32 posPrev = curOptimum.PosPrev;
+ CState state;
+ if (curOptimum.Prev1IsChar)
+ {
+ posPrev--;
+ if (curOptimum.Prev2)
+ {
+ state = _optimum[curOptimum.PosPrev2].State;
+ if (curOptimum.BackPrev2 < kNumRepDistances)
+ state.UpdateRep();
+ else
+ state.UpdateMatch();
+ }
+ else
+ state = _optimum[posPrev].State;
+ state.UpdateChar();
+ }
+ else
+ state = _optimum[posPrev].State;
+ if (posPrev == cur - 1)
+ {
+ if (curOptimum.IsShortRep())
+ state.UpdateShortRep();
+ else
+ state.UpdateChar();
+ /*
+ if (curOptimum.Prev1IsChar)
+ for(int i = 0; i < kNumRepDistances; i++)
+ reps[i] = _optimum[posPrev].Backs[i];
+ */
+ }
+ else
+ {
+ UInt32 pos;
+ if (curOptimum.Prev1IsChar && curOptimum.Prev2)
+ {
+ posPrev = curOptimum.PosPrev2;
+ pos = curOptimum.BackPrev2;
+ state.UpdateRep();
+ }
+ else
+ {
+ pos = curOptimum.BackPrev;
+ if (pos < kNumRepDistances)
+ state.UpdateRep();
+ else
+ state.UpdateMatch();
+ }
+ const COptimal &prevOptimum = _optimum[posPrev];
+ if (pos < kNumRepDistances)
+ {
+ reps[0] = prevOptimum.Backs[pos];
+ UInt32 i;
+ for(i = 1; i <= pos; i++)
+ reps[i] = prevOptimum.Backs[i - 1];
+ for(; i < kNumRepDistances; i++)
+ reps[i] = prevOptimum.Backs[i];
+ }
+ else
+ {
+ reps[0] = (pos - kNumRepDistances);
+ for(UInt32 i = 1; i < kNumRepDistances; i++)
+ reps[i] = prevOptimum.Backs[i - 1];
+ }
+ }
+ curOptimum.State = state;
+ for(UInt32 i = 0; i < kNumRepDistances; i++)
+ curOptimum.Backs[i] = reps[i];
+ UInt32 newLen;
+ RINOK(ReadMatchDistances(newLen));
+ if(newLen >= _numFastBytes)
+ {
+ _longestMatchLength = newLen;
+ _longestMatchWasFound = true;
+ lenRes = Backward(backRes, cur);
+ return S_OK;
+ }
+ UInt32 curPrice = curOptimum.Price;
+ // Byte currentByte = _matchFinder->GetIndexByte(0 - 1);
+ // Byte matchByte = _matchFinder->GetIndexByte(0 - reps[0] - 1 - 1);
+ const Byte *data = _matchFinder->GetPointerToCurrentPos() - 1;
+ Byte currentByte = *data;
+ Byte matchByte = data[(size_t)0 - reps[0] - 1];
+
+ UInt32 posState = (position & _posStateMask);
+
+ UInt32 curAnd1Price = curPrice +
+ _isMatch[state.Index][posState].GetPrice0() +
+ _literalEncoder.GetPrice(position, data[(size_t)0 - 1], !state.IsCharState(), matchByte, currentByte);
+
+ COptimal &nextOptimum = _optimum[cur + 1];
+
+ bool nextIsChar = false;
+ if (curAnd1Price < nextOptimum.Price)
+ {
+ nextOptimum.Price = curAnd1Price;
+ nextOptimum.PosPrev = cur;
+ nextOptimum.MakeAsChar();
+ nextIsChar = true;
+ }
+
+ UInt32 matchPrice = curPrice + _isMatch[state.Index][posState].GetPrice1();
+ UInt32 repMatchPrice = matchPrice + _isRep[state.Index].GetPrice1();
+
+ if(matchByte == currentByte &&
+ !(nextOptimum.PosPrev < cur && nextOptimum.BackPrev == 0))
+ {
+ UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(state, posState);
+ if(shortRepPrice <= nextOptimum.Price)
+ {
+ nextOptimum.Price = shortRepPrice;
+ nextOptimum.PosPrev = cur;
+ nextOptimum.MakeAsShortRep();
+ // nextIsChar = false;
+ }
+ }
+ /*
+ if(newLen == 2 && _matchDistances[2] >= kDistLimit2) // test it maybe set 2000 ?
+ continue;
+ */
+
+ UInt32 numAvailableBytesFull = _matchFinder->GetNumAvailableBytes() + 1;
+ numAvailableBytesFull = MyMin(kNumOpts - 1 - cur, numAvailableBytesFull);
+ UInt32 numAvailableBytes = numAvailableBytesFull;
+
+ if (numAvailableBytes < 2)
+ continue;
+ if (numAvailableBytes > _numFastBytes)
+ numAvailableBytes = _numFastBytes;
+ if (numAvailableBytes >= 3 && !nextIsChar)
+ {
+ // try Literal + rep0
+ UInt32 backOffset = reps[0] + 1;
+ UInt32 temp;
+ for (temp = 1; temp < numAvailableBytes; temp++)
+ if (data[temp] != data[(size_t)temp - backOffset])
+ break;
+ UInt32 lenTest2 = temp - 1;
+ if (lenTest2 >= 2)
+ {
+ CState state2 = state;
+ state2.UpdateChar();
+ UInt32 posStateNext = (position + 1) & _posStateMask;
+ UInt32 nextRepMatchPrice = curAnd1Price +
+ _isMatch[state2.Index][posStateNext].GetPrice1() +
+ _isRep[state2.Index].GetPrice1();
+ // for (; lenTest2 >= 2; lenTest2--)
+ {
+ while(lenEnd < cur + 1 + lenTest2)
+ _optimum[++lenEnd].Price = kIfinityPrice;
+ UInt32 curAndLenPrice = nextRepMatchPrice + GetRepPrice(
+ 0, lenTest2, state2, posStateNext);
+ COptimal &optimum = _optimum[cur + 1 + lenTest2];
+ if (curAndLenPrice < optimum.Price)
+ {
+ optimum.Price = curAndLenPrice;
+ optimum.PosPrev = cur + 1;
+ optimum.BackPrev = 0;
+ optimum.Prev1IsChar = true;
+ optimum.Prev2 = false;
+ }
+ }
+ }
+ }
+ for(UInt32 repIndex = 0; repIndex < kNumRepDistances; repIndex++)
+ {
+ // UInt32 repLen = _matchFinder->GetMatchLen(0 - 1, reps[repIndex], newLen); // test it;
+ UInt32 backOffset = reps[repIndex] + 1;
+ if (data[0] != data[(size_t)0 - backOffset] ||
+ data[1] != data[(size_t)1 - backOffset])
+ continue;
+ UInt32 lenTest;
+ for (lenTest = 2; lenTest < numAvailableBytes; lenTest++)
+ if (data[lenTest] != data[(size_t)lenTest - backOffset])
+ break;
+ UInt32 lenTestTemp = lenTest;
+ do
+ {
+ while(lenEnd < cur + lenTest)
+ _optimum[++lenEnd].Price = kIfinityPrice;
+ UInt32 curAndLenPrice = repMatchPrice + GetRepPrice(repIndex, lenTest, state, posState);
+ COptimal &optimum = _optimum[cur + lenTest];
+ if (curAndLenPrice < optimum.Price)
+ {
+ optimum.Price = curAndLenPrice;
+ optimum.PosPrev = cur;
+ optimum.BackPrev = repIndex;
+ optimum.Prev1IsChar = false;
+ }
+ }
+ while(--lenTest >= 2);
+ lenTest = lenTestTemp;
+
+ if (_maxMode)
+ {
+ UInt32 lenTest2 = lenTest + 1;
+ UInt32 limit = MyMin(numAvailableBytesFull, lenTest2 + _numFastBytes);
+ for (; lenTest2 < limit; lenTest2++)
+ if (data[lenTest2] != data[(size_t)lenTest2 - backOffset])
+ break;
+ lenTest2 -= lenTest + 1;
+ if (lenTest2 >= 2)
+ {
+ CState state2 = state;
+ state2.UpdateRep();
+ UInt32 posStateNext = (position + lenTest) & _posStateMask;
+ UInt32 curAndLenCharPrice =
+ repMatchPrice + GetRepPrice(repIndex, lenTest, state, posState) +
+ _isMatch[state2.Index][posStateNext].GetPrice0() +
+ _literalEncoder.GetPrice(position + lenTest, data[(size_t)lenTest - 1],
+ true, data[(size_t)lenTest - backOffset], data[lenTest]);
+ state2.UpdateChar();
+ posStateNext = (position + lenTest + 1) & _posStateMask;
+ UInt32 nextMatchPrice = curAndLenCharPrice + _isMatch[state2.Index][posStateNext].GetPrice1();
+ UInt32 nextRepMatchPrice = nextMatchPrice + _isRep[state2.Index].GetPrice1();
+
+ // for(; lenTest2 >= 2; lenTest2--)
+ {
+ UInt32 offset = lenTest + 1 + lenTest2;
+ while(lenEnd < cur + offset)
+ _optimum[++lenEnd].Price = kIfinityPrice;
+ UInt32 curAndLenPrice = nextRepMatchPrice + GetRepPrice(
+ 0, lenTest2, state2, posStateNext);
+ COptimal &optimum = _optimum[cur + offset];
+ if (curAndLenPrice < optimum.Price)
+ {
+ optimum.Price = curAndLenPrice;
+ optimum.PosPrev = cur + lenTest + 1;
+ optimum.BackPrev = 0;
+ optimum.Prev1IsChar = true;
+ optimum.Prev2 = true;
+ optimum.PosPrev2 = cur;
+ optimum.BackPrev2 = repIndex;
+ }
+ }
+ }
+ }
+ }
+
+ // for(UInt32 lenTest = 2; lenTest <= newLen; lenTest++)
+ if (newLen > numAvailableBytes)
+ newLen = numAvailableBytes;
+ if (newLen >= 2)
+ {
+ if (newLen == 2 && _matchDistances[2] >= 0x80)
+ continue;
+ UInt32 normalMatchPrice = matchPrice +
+ _isRep[state.Index].GetPrice0();
+ while(lenEnd < cur + newLen)
+ _optimum[++lenEnd].Price = kIfinityPrice;
+
+ for(UInt32 lenTest = newLen; lenTest >= 2; lenTest--)
+ {
+ UInt32 curBack = _matchDistances[lenTest];
+ UInt32 curAndLenPrice = normalMatchPrice + GetPosLenPrice(curBack, lenTest, posState);
+ COptimal &optimum = _optimum[cur + lenTest];
+ if (curAndLenPrice < optimum.Price)
+ {
+ optimum.Price = curAndLenPrice;
+ optimum.PosPrev = cur;
+ optimum.BackPrev = curBack + kNumRepDistances;
+ optimum.Prev1IsChar = false;
+ }
+
+ if (_maxMode && (lenTest == newLen || curBack != _matchDistances[lenTest + 1]))
+ {
+ // Try Match + Literal + Rep0
+ UInt32 backOffset = curBack + 1;
+ UInt32 lenTest2 = lenTest + 1;
+ UInt32 limit = MyMin(numAvailableBytesFull, lenTest2 + _numFastBytes);
+ for (; lenTest2 < limit; lenTest2++)
+ if (data[lenTest2] != data[(size_t)lenTest2 - backOffset])
+ break;
+ lenTest2 -= lenTest + 1;
+ if (lenTest2 >= 2)
+ {
+ CState state2 = state;
+ state2.UpdateMatch();
+ UInt32 posStateNext = (position + lenTest) & _posStateMask;
+ UInt32 curAndLenCharPrice = curAndLenPrice +
+ _isMatch[state2.Index][posStateNext].GetPrice0() +
+ _literalEncoder.GetPrice(position + lenTest, data[(size_t)lenTest - 1],
+ true, data[(size_t)lenTest - backOffset], data[lenTest]);
+ state2.UpdateChar();
+ posStateNext = (position + lenTest + 1) & _posStateMask;
+ UInt32 nextMatchPrice = curAndLenCharPrice + _isMatch[state2.Index][posStateNext].GetPrice1();
+ UInt32 nextRepMatchPrice = nextMatchPrice + _isRep[state2.Index].GetPrice1();
+
+ // for(; lenTest2 >= 2; lenTest2--)
+ {
+ UInt32 offset = lenTest + 1 + lenTest2;
+ while(lenEnd < cur + offset)
+ _optimum[++lenEnd].Price = kIfinityPrice;
+ UInt32 curAndLenPrice = nextRepMatchPrice + GetRepPrice(
+ 0, lenTest2, state2, posStateNext);
+ COptimal &optimum = _optimum[cur + offset];
+ if (curAndLenPrice < optimum.Price)
+ {
+ optimum.Price = curAndLenPrice;
+ optimum.PosPrev = cur + lenTest + 1;
+ optimum.BackPrev = 0;
+ optimum.Prev1IsChar = true;
+ optimum.Prev2 = true;
+ optimum.PosPrev2 = cur;
+ optimum.BackPrev2 = curBack + kNumRepDistances;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+static inline bool ChangePair(UInt32 smallDist, UInt32 bigDist)
+{
+ const int kDif = 7;
+ return (smallDist < (UInt32(1) << (32-kDif)) && bigDist >= (smallDist << kDif));
+}
+
+
+HRESULT CEncoder::ReadMatchDistances(UInt32 &lenRes)
+{
+ lenRes = _matchFinder->GetLongestMatch(_matchDistances);
+ if (lenRes == _numFastBytes)
+ lenRes += _matchFinder->GetMatchLen(lenRes, _matchDistances[lenRes],
+ kMatchMaxLen - lenRes);
+ _additionalOffset++;
+ return _matchFinder->MovePos();
+}
+
+HRESULT CEncoder::GetOptimumFast(UInt32 position, UInt32 &backRes, UInt32 &lenRes)
+{
+ UInt32 lenMain;
+ if (!_longestMatchWasFound)
+ {
+ RINOK(ReadMatchDistances(lenMain));
+ }
+ else
+ {
+ lenMain = _longestMatchLength;
+ _longestMatchWasFound = false;
+ }
+ UInt32 repLens[kNumRepDistances];
+ UInt32 repMaxIndex = 0;
+ for(UInt32 i = 0; i < kNumRepDistances; i++)
+ {
+ repLens[i] = _matchFinder->GetMatchLen(0 - 1, _repDistances[i], kMatchMaxLen);
+ if (i == 0 || repLens[i] > repLens[repMaxIndex])
+ repMaxIndex = i;
+ }
+ if(repLens[repMaxIndex] >= _numFastBytes)
+ {
+ backRes = repMaxIndex;
+ lenRes = repLens[repMaxIndex];
+ return MovePos(lenRes - 1);
+ }
+ if(lenMain >= _numFastBytes)
+ {
+ backRes = _matchDistances[_numFastBytes] + kNumRepDistances;
+ lenRes = lenMain;
+ return MovePos(lenMain - 1);
+ }
+ while (lenMain > 2)
+ {
+ if (!ChangePair(_matchDistances[lenMain - 1], _matchDistances[lenMain]))
+ break;
+ lenMain--;
+ }
+ if (lenMain == 2 && _matchDistances[2] >= 0x80)
+ lenMain = 1;
+
+ UInt32 backMain = _matchDistances[lenMain];
+ if (repLens[repMaxIndex] >= 2)
+ {
+ if (repLens[repMaxIndex] + 1 >= lenMain ||
+ (repLens[repMaxIndex] + 2 >= lenMain && (backMain > (1<<12))))
+ {
+ backRes = repMaxIndex;
+ lenRes = repLens[repMaxIndex];
+ return MovePos(lenRes - 1);
+ }
+ }
+
+
+ if (lenMain >= 2)
+ {
+ RINOK(ReadMatchDistances(_longestMatchLength));
+ if (_longestMatchLength >= 2 &&
+ (
+ (_longestMatchLength >= lenMain && _matchDistances[lenMain] < backMain) ||
+ ((_longestMatchLength == lenMain + 1) &&
+ !ChangePair(backMain, _matchDistances[_longestMatchLength])) ||
+ (_longestMatchLength > lenMain + 1) ||
+ ((_longestMatchLength + 1 >= lenMain) && lenMain >= 3 &&
+ ChangePair(_matchDistances[lenMain - 1], backMain))
+ )
+ )
+ {
+ _longestMatchWasFound = true;
+ backRes = UInt32(-1);
+ lenRes = 1;
+ return S_OK;
+ }
+ for(UInt32 i = 0; i < kNumRepDistances; i++)
+ {
+ UInt32 repLen = _matchFinder->GetMatchLen(0 - 1, _repDistances[i], kMatchMaxLen);
+ if (repLen >= 2 && repLen + 1 >= lenMain)
+ {
+ _longestMatchWasFound = true;
+ backRes = UInt32(-1);
+ lenRes = 1;
+ return S_OK;
+ }
+ }
+ backRes = backMain + kNumRepDistances;
+ lenRes = lenMain;
+ return MovePos(lenMain - 2);
+ }
+ backRes = UInt32(-1);
+ lenRes = 1;
+ return S_OK;
+}
+
+STDMETHODIMP CEncoder::InitMatchFinder(IMatchFinder *matchFinder)
+{
+ _matchFinder = matchFinder;
+ return S_OK;
+}
+
+HRESULT CEncoder::Flush(UInt32 nowPos)
+{
+ ReleaseMFStream();
+ WriteEndMarker(nowPos & _posStateMask);
+ _rangeEncoder.FlushData();
+ return _rangeEncoder.FlushStream();
+}
+
+void CEncoder::WriteEndMarker(UInt32 posState)
+{
+ // This function for writing End Mark for stream version of LZMA.
+ // In current version this feature is not used.
+ if (!_writeEndMark)
+ return;
+
+ _isMatch[_state.Index][posState].Encode(&_rangeEncoder, 1);
+ _isRep[_state.Index].Encode(&_rangeEncoder, 0);
+ _state.UpdateMatch();
+ UInt32 len = kMatchMinLen; // kMatchMaxLen;
+ _lenEncoder.Encode(&_rangeEncoder, len - kMatchMinLen, posState);
+ UInt32 posSlot = (1 << kNumPosSlotBits) - 1;
+ UInt32 lenToPosState = GetLenToPosState(len);
+ _posSlotEncoder[lenToPosState].Encode(&_rangeEncoder, posSlot);
+ UInt32 footerBits = 30;
+ UInt32 posReduced = (UInt32(1) << footerBits) - 1;
+ _rangeEncoder.EncodeDirectBits(posReduced >> kNumAlignBits, footerBits - kNumAlignBits);
+ _posAlignEncoder.ReverseEncode(&_rangeEncoder, posReduced & kAlignMask);
+}
+
+HRESULT CEncoder::CodeReal(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ _needReleaseMFStream = false;
+ CCoderReleaser coderReleaser(this);
+ RINOK(SetStreams(inStream, outStream, inSize, outSize));
+ while(true)
+ {
+ UInt64 processedInSize;
+ UInt64 processedOutSize;
+ Int32 finished;
+ RINOK(CodeOneBlock(&processedInSize, &processedOutSize, &finished));
+ if (finished != 0)
+ return S_OK;
+ if (progress != 0)
+ {
+ RINOK(progress->SetRatioInfo(&processedInSize, &processedOutSize));
+ }
+ }
+}
+
+HRESULT CEncoder::SetStreams(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UInt64 *inSize, const UInt64 *outSize)
+{
+ _inStream = inStream;
+ _finished = false;
+ RINOK(Create());
+ RINOK(SetOutStream(outStream));
+ RINOK(Init());
+
+ // CCoderReleaser releaser(this);
+
+ /*
+ if (_matchFinder->GetNumAvailableBytes() == 0)
+ return Flush();
+ */
+
+ if (!_fastMode)
+ {
+ FillPosSlotPrices();
+ FillDistancesPrices();
+ FillAlignPrices();
+ }
+
+ _lenEncoder.SetTableSize(_numFastBytes + 1 - kMatchMinLen);
+ _lenEncoder.UpdateTables(1 << _posStateBits);
+ _repMatchLenEncoder.SetTableSize(_numFastBytes + 1 - kMatchMinLen);
+ _repMatchLenEncoder.UpdateTables(1 << _posStateBits);
+
+ lastPosSlotFillingPos = 0;
+ nowPos64 = 0;
+ return S_OK;
+}
+
+HRESULT CEncoder::CodeOneBlock(UInt64 *inSize, UInt64 *outSize, Int32 *finished)
+{
+ if (_inStream != 0)
+ {
+ RINOK(_matchFinder->Init(_inStream));
+ _needReleaseMFStream = true;
+ _inStream = 0;
+ }
+
+
+ *finished = 1;
+ if (_finished)
+ return S_OK;
+ _finished = true;
+
+
+ UInt64 progressPosValuePrev = nowPos64;
+ if (nowPos64 == 0)
+ {
+ if (_matchFinder->GetNumAvailableBytes() == 0)
+ return Flush(UInt32(nowPos64));
+ UInt32 len; // it's not used
+ RINOK(ReadMatchDistances(len));
+ UInt32 posState = UInt32(nowPos64) & _posStateMask;
+ _isMatch[_state.Index][posState].Encode(&_rangeEncoder, 0);
+ _state.UpdateChar();
+ Byte curByte = _matchFinder->GetIndexByte(0 - _additionalOffset);
+ _literalEncoder.GetSubCoder(UInt32(nowPos64), _previousByte)->Encode(&_rangeEncoder, curByte);
+ _previousByte = curByte;
+ _additionalOffset--;
+ nowPos64++;
+ }
+ if (_matchFinder->GetNumAvailableBytes() == 0)
+ return Flush(UInt32(nowPos64));
+ while(true)
+ {
+ #ifdef _NO_EXCEPTIONS
+ if (_rangeEncoder.Stream.ErrorCode != S_OK)
+ return _rangeEncoder.Stream.ErrorCode;
+ #endif
+ UInt32 pos;
+ UInt32 posState = UInt32(nowPos64) & _posStateMask;
+
+ UInt32 len;
+ HRESULT result;
+ if (_fastMode)
+ result = GetOptimumFast(UInt32(nowPos64), pos, len);
+ else
+ result = GetOptimum(UInt32(nowPos64), pos, len);
+ RINOK(result);
+
+ if(len == 1 && pos == 0xFFFFFFFF)
+ {
+ _isMatch[_state.Index][posState].Encode(&_rangeEncoder, 0);
+ Byte curByte = _matchFinder->GetIndexByte(0 - _additionalOffset);
+ CLiteralEncoder2 *subCoder = _literalEncoder.GetSubCoder(UInt32(nowPos64), _previousByte);
+ if(!_state.IsCharState())
+ {
+ Byte matchByte = _matchFinder->GetIndexByte(0 - _repDistances[0] - 1 - _additionalOffset);
+ subCoder->EncodeMatched(&_rangeEncoder, matchByte, curByte);
+ }
+ else
+ subCoder->Encode(&_rangeEncoder, curByte);
+ _state.UpdateChar();
+ _previousByte = curByte;
+ }
+ else
+ {
+ _isMatch[_state.Index][posState].Encode(&_rangeEncoder, 1);
+ if(pos < kNumRepDistances)
+ {
+ _isRep[_state.Index].Encode(&_rangeEncoder, 1);
+ if(pos == 0)
+ {
+ _isRepG0[_state.Index].Encode(&_rangeEncoder, 0);
+ if(len == 1)
+ _isRep0Long[_state.Index][posState].Encode(&_rangeEncoder, 0);
+ else
+ _isRep0Long[_state.Index][posState].Encode(&_rangeEncoder, 1);
+ }
+ else
+ {
+ _isRepG0[_state.Index].Encode(&_rangeEncoder, 1);
+ if (pos == 1)
+ _isRepG1[_state.Index].Encode(&_rangeEncoder, 0);
+ else
+ {
+ _isRepG1[_state.Index].Encode(&_rangeEncoder, 1);
+ _isRepG2[_state.Index].Encode(&_rangeEncoder, pos - 2);
+ }
+ }
+ if (len == 1)
+ _state.UpdateShortRep();
+ else
+ {
+ _repMatchLenEncoder.Encode(&_rangeEncoder, len - kMatchMinLen, posState);
+ _state.UpdateRep();
+ }
+
+
+ UInt32 distance = _repDistances[pos];
+ if (pos != 0)
+ {
+ for(UInt32 i = pos; i >= 1; i--)
+ _repDistances[i] = _repDistances[i - 1];
+ _repDistances[0] = distance;
+ }
+ }
+ else
+ {
+ _isRep[_state.Index].Encode(&_rangeEncoder, 0);
+ _state.UpdateMatch();
+ _lenEncoder.Encode(&_rangeEncoder, len - kMatchMinLen, posState);
+ pos -= kNumRepDistances;
+ UInt32 posSlot = GetPosSlot(pos);
+ UInt32 lenToPosState = GetLenToPosState(len);
+ _posSlotEncoder[lenToPosState].Encode(&_rangeEncoder, posSlot);
+
+ if (posSlot >= kStartPosModelIndex)
+ {
+ UInt32 footerBits = ((posSlot >> 1) - 1);
+ UInt32 base = ((2 | (posSlot & 1)) << footerBits);
+ UInt32 posReduced = pos - base;
+
+ if (posSlot < kEndPosModelIndex)
+ NRangeCoder::ReverseBitTreeEncode(_posEncoders + base - posSlot - 1,
+ &_rangeEncoder, footerBits, posReduced);
+ else
+ {
+ _rangeEncoder.EncodeDirectBits(posReduced >> kNumAlignBits, footerBits - kNumAlignBits);
+ _posAlignEncoder.ReverseEncode(&_rangeEncoder, posReduced & kAlignMask);
+ if (!_fastMode)
+ if (--_alignPriceCount == 0)
+ FillAlignPrices();
+ }
+ }
+ UInt32 distance = pos;
+ for(UInt32 i = kNumRepDistances - 1; i >= 1; i--)
+ _repDistances[i] = _repDistances[i - 1];
+ _repDistances[0] = distance;
+ }
+ _previousByte = _matchFinder->GetIndexByte(len - 1 - _additionalOffset);
+ }
+ _additionalOffset -= len;
+ nowPos64 += len;
+ if (!_fastMode)
+ if (nowPos64 - lastPosSlotFillingPos >= (1 << 9))
+ {
+ FillPosSlotPrices();
+ FillDistancesPrices();
+ lastPosSlotFillingPos = nowPos64;
+ }
+ if (_additionalOffset == 0)
+ {
+ *inSize = nowPos64;
+ *outSize = _rangeEncoder.GetProcessedSize();
+ if (_matchFinder->GetNumAvailableBytes() == 0)
+ return Flush(UInt32(nowPos64));
+ if (nowPos64 - progressPosValuePrev >= (1 << 12))
+ {
+ _finished = false;
+ *finished = 0;
+ return S_OK;
+ }
+ }
+ }
+}
+
+STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ #ifndef _NO_EXCEPTIONS
+ try
+ {
+ #endif
+ return CodeReal(inStream, outStream, inSize, outSize, progress);
+ #ifndef _NO_EXCEPTIONS
+ }
+ catch(const COutBufferException &e) { return e.ErrorCode; }
+ catch(...) { return E_FAIL; }
+ #endif
+}
+
+void CEncoder::FillPosSlotPrices()
+{
+ for (UInt32 lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++)
+ {
+ UInt32 posSlot;
+ for (posSlot = 0; posSlot < kEndPosModelIndex && posSlot < _distTableSize; posSlot++)
+ _posSlotPrices[lenToPosState][posSlot] = _posSlotEncoder[lenToPosState].GetPrice(posSlot);
+ for (; posSlot < _distTableSize; posSlot++)
+ _posSlotPrices[lenToPosState][posSlot] = _posSlotEncoder[lenToPosState].GetPrice(posSlot) +
+ ((((posSlot >> 1) - 1) - kNumAlignBits) << NRangeCoder::kNumBitPriceShiftBits);
+ }
+}
+
+void CEncoder::FillDistancesPrices()
+{
+ for (UInt32 lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++)
+ {
+ UInt32 i;
+ for (i = 0; i < kStartPosModelIndex; i++)
+ _distancesPrices[lenToPosState][i] = _posSlotPrices[lenToPosState][i];
+ for (; i < kNumFullDistances; i++)
+ {
+ UInt32 posSlot = GetPosSlot(i);
+ UInt32 footerBits = ((posSlot >> 1) - 1);
+ UInt32 base = ((2 | (posSlot & 1)) << footerBits);
+
+ _distancesPrices[lenToPosState][i] = _posSlotPrices[lenToPosState][posSlot] +
+ NRangeCoder::ReverseBitTreeGetPrice(_posEncoders +
+ base - posSlot - 1, footerBits, i - base);
+
+ }
+ }
+}
+
+void CEncoder::FillAlignPrices()
+{
+ for (UInt32 i = 0; i < kAlignTableSize; i++)
+ _alignPrices[i] = _posAlignEncoder.ReverseGetPrice(i);
+ _alignPriceCount = kAlignTableSize;
+}
+
+}}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA/LZMAEncoder.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA/LZMAEncoder.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA/LZMAEncoder.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA/LZMAEncoder.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,416 @@
+// LZMA/Encoder.h
+
+#ifndef __LZMA_ENCODER_H
+#define __LZMA_ENCODER_H
+
+#include "../../../Common/MyCom.h"
+#include "../../../Common/Alloc.h"
+#include "../../ICoder.h"
+#include "../LZ/IMatchFinder.h"
+#include "../RangeCoder/RangeCoderBitTree.h"
+
+#include "LZMA.h"
+
+namespace NCompress {
+namespace NLZMA {
+
+typedef NRangeCoder::CBitEncoder<kNumMoveBits> CMyBitEncoder;
+
+class CBaseState
+{
+protected:
+ CState _state;
+ Byte _previousByte;
+ UInt32 _repDistances[kNumRepDistances];
+ void Init()
+ {
+ _state.Init();
+ _previousByte = 0;
+ for(UInt32 i = 0 ; i < kNumRepDistances; i++)
+ _repDistances[i] = 0;
+ }
+};
+
+struct COptimal
+{
+ CState State;
+
+ bool Prev1IsChar;
+ bool Prev2;
+
+ UInt32 PosPrev2;
+ UInt32 BackPrev2;
+
+ UInt32 Price;
+ UInt32 PosPrev; // posNext;
+ UInt32 BackPrev;
+ UInt32 Backs[kNumRepDistances];
+ void MakeAsChar() { BackPrev = UInt32(-1); Prev1IsChar = false; }
+ void MakeAsShortRep() { BackPrev = 0; ; Prev1IsChar = false; }
+ bool IsShortRep() { return (BackPrev == 0); }
+};
+
+
+extern Byte g_FastPos[1024];
+inline UInt32 GetPosSlot(UInt32 pos)
+{
+ if (pos < (1 << 10))
+ return g_FastPos[pos];
+ if (pos < (1 << 19))
+ return g_FastPos[pos >> 9] + 18;
+ return g_FastPos[pos >> 18] + 36;
+}
+
+inline UInt32 GetPosSlot2(UInt32 pos)
+{
+ if (pos < (1 << 16))
+ return g_FastPos[pos >> 6] + 12;
+ if (pos < (1 << 25))
+ return g_FastPos[pos >> 15] + 30;
+ return g_FastPos[pos >> 24] + 48;
+}
+
+const UInt32 kIfinityPrice = 0xFFFFFFF;
+
+const UInt32 kNumOpts = 1 << 12;
+
+
+class CLiteralEncoder2
+{
+ CMyBitEncoder _encoders[0x300];
+public:
+ void Init()
+ {
+ for (int i = 0; i < 0x300; i++)
+ _encoders[i].Init();
+ }
+ void Encode(NRangeCoder::CEncoder *rangeEncoder, Byte symbol);
+ void EncodeMatched(NRangeCoder::CEncoder *rangeEncoder, Byte matchByte, Byte symbol);
+ UInt32 GetPrice(bool matchMode, Byte matchByte, Byte symbol) const;
+};
+
+class CLiteralEncoder
+{
+ CLiteralEncoder2 *_coders;
+ int _numPrevBits;
+ int _numPosBits;
+ UInt32 _posMask;
+public:
+ CLiteralEncoder(): _coders(0) {}
+ ~CLiteralEncoder() { Free(); }
+ void Free()
+ {
+ MyFree(_coders);
+ _coders = 0;
+ }
+ bool Create(int numPosBits, int numPrevBits)
+ {
+ if (_coders == 0 || (numPosBits + numPrevBits) !=
+ (_numPrevBits + _numPosBits) )
+ {
+ Free();
+ UInt32 numStates = 1 << (numPosBits + numPrevBits);
+ _coders = (CLiteralEncoder2 *)MyAlloc(numStates * sizeof(CLiteralEncoder2));
+ }
+ _numPosBits = numPosBits;
+ _posMask = (1 << numPosBits) - 1;
+ _numPrevBits = numPrevBits;
+ return (_coders != 0);
+ }
+ void Init()
+ {
+ UInt32 numStates = 1 << (_numPrevBits + _numPosBits);
+ for (UInt32 i = 0; i < numStates; i++)
+ _coders[i].Init();
+ }
+ UInt32 GetState(UInt32 pos, Byte prevByte) const
+ { return ((pos & _posMask) << _numPrevBits) + (prevByte >> (8 - _numPrevBits)); }
+ CLiteralEncoder2 *GetSubCoder(UInt32 pos, Byte prevByte)
+ { return &_coders[GetState(pos, prevByte)]; }
+ /*
+ void Encode(NRangeCoder::CEncoder *rangeEncoder, UInt32 pos, Byte prevByte,
+ Byte symbol)
+ { _coders[GetState(pos, prevByte)].Encode(rangeEncoder, symbol); }
+ void EncodeMatched(NRangeCoder::CEncoder *rangeEncoder, UInt32 pos, Byte prevByte,
+ Byte matchByte, Byte symbol)
+ { _coders[GetState(pos, prevByte)].Encode(rangeEncoder,
+ matchByte, symbol); }
+ */
+ UInt32 GetPrice(UInt32 pos, Byte prevByte, bool matchMode, Byte matchByte, Byte symbol) const
+ { return _coders[GetState(pos, prevByte)].GetPrice(matchMode, matchByte, symbol); }
+};
+
+namespace NLength {
+
+class CEncoder
+{
+ CMyBitEncoder _choice;
+ CMyBitEncoder _choice2;
+ NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumLowBits> _lowCoder[kNumPosStatesEncodingMax];
+ NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumMidBits> _midCoder[kNumPosStatesEncodingMax];
+ NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumHighBits> _highCoder;
+public:
+ void Init(UInt32 numPosStates);
+ void Encode(NRangeCoder::CEncoder *rangeEncoder, UInt32 symbol, UInt32 posState);
+ UInt32 GetPrice(UInt32 symbol, UInt32 posState) const;
+};
+
+const UInt32 kNumSpecSymbols = kNumLowSymbols + kNumMidSymbols;
+
+class CPriceTableEncoder: public CEncoder
+{
+ UInt32 _prices[kNumSymbolsTotal][kNumPosStatesEncodingMax];
+ UInt32 _tableSize;
+ UInt32 _counters[kNumPosStatesEncodingMax];
+public:
+ void SetTableSize(UInt32 tableSize) { _tableSize = tableSize; }
+ UInt32 GetPrice(UInt32 symbol, UInt32 posState) const
+ { return _prices[symbol][posState]; }
+ void UpdateTable(UInt32 posState)
+ {
+ for (UInt32 len = 0; len < _tableSize; len++)
+ _prices[len][posState] = CEncoder::GetPrice(len, posState);
+ _counters[posState] = _tableSize;
+ }
+ void UpdateTables(UInt32 numPosStates)
+ {
+ for (UInt32 posState = 0; posState < numPosStates; posState++)
+ UpdateTable(posState);
+ }
+ void Encode(NRangeCoder::CEncoder *rangeEncoder, UInt32 symbol, UInt32 posState)
+ {
+ CEncoder::Encode(rangeEncoder, symbol, posState);
+ if (--_counters[posState] == 0)
+ UpdateTable(posState);
+ }
+};
+
+}
+
+class CEncoder :
+ public ICompressCoder,
+ public ICompressSetOutStream,
+ public ICompressSetCoderProperties,
+ public ICompressWriteCoderProperties,
+ public CBaseState,
+ public CMyUnknownImp
+{
+ COptimal _optimum[kNumOpts];
+ CMyComPtr<IMatchFinder> _matchFinder; // test it
+ NRangeCoder::CEncoder _rangeEncoder;
+
+ CMyBitEncoder _isMatch[kNumStates][NLength::kNumPosStatesEncodingMax];
+ CMyBitEncoder _isRep[kNumStates];
+ CMyBitEncoder _isRepG0[kNumStates];
+ CMyBitEncoder _isRepG1[kNumStates];
+ CMyBitEncoder _isRepG2[kNumStates];
+ CMyBitEncoder _isRep0Long[kNumStates][NLength::kNumPosStatesEncodingMax];
+
+ NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumPosSlotBits> _posSlotEncoder[kNumLenToPosStates];
+
+ CMyBitEncoder _posEncoders[kNumFullDistances - kEndPosModelIndex];
+ NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumAlignBits> _posAlignEncoder;
+
+ NLength::CPriceTableEncoder _lenEncoder;
+ NLength::CPriceTableEncoder _repMatchLenEncoder;
+
+ CLiteralEncoder _literalEncoder;
+
+ UInt32 _matchDistances[kMatchMaxLen + 1];
+
+ bool _fastMode;
+ bool _maxMode;
+ UInt32 _numFastBytes;
+ UInt32 _longestMatchLength;
+
+ UInt32 _additionalOffset;
+
+ UInt32 _optimumEndIndex;
+ UInt32 _optimumCurrentIndex;
+
+ bool _longestMatchWasFound;
+
+ UInt32 _posSlotPrices[kNumLenToPosStates][kDistTableSizeMax];
+
+ UInt32 _distancesPrices[kNumLenToPosStates][kNumFullDistances];
+
+ UInt32 _alignPrices[kAlignTableSize];
+ UInt32 _alignPriceCount;
+
+ UInt32 _distTableSize;
+
+ UInt32 _posStateBits;
+ UInt32 _posStateMask;
+ UInt32 _numLiteralPosStateBits;
+ UInt32 _numLiteralContextBits;
+
+ UInt32 _dictionarySize;
+
+ UInt32 _dictionarySizePrev;
+ UInt32 _numFastBytesPrev;
+
+ UInt64 lastPosSlotFillingPos;
+ UInt64 nowPos64;
+ bool _finished;
+ ISequentialInStream *_inStream;
+
+ int _matchFinderIndex;
+ #ifdef COMPRESS_MF_MT
+ bool _multiThread;
+ #endif
+
+ bool _writeEndMark;
+
+ bool _needReleaseMFStream;
+
+ HRESULT ReadMatchDistances(UInt32 &len);
+
+ HRESULT MovePos(UInt32 num);
+ UInt32 GetRepLen1Price(CState state, UInt32 posState) const
+ {
+ return _isRepG0[state.Index].GetPrice0() +
+ _isRep0Long[state.Index][posState].GetPrice0();
+ }
+ UInt32 GetRepPrice(UInt32 repIndex, UInt32 len, CState state, UInt32 posState) const
+ {
+ UInt32 price = _repMatchLenEncoder.GetPrice(len - kMatchMinLen, posState);
+ if(repIndex == 0)
+ {
+ price += _isRepG0[state.Index].GetPrice0();
+ price += _isRep0Long[state.Index][posState].GetPrice1();
+ }
+ else
+ {
+ price += _isRepG0[state.Index].GetPrice1();
+ if (repIndex == 1)
+ price += _isRepG1[state.Index].GetPrice0();
+ else
+ {
+ price += _isRepG1[state.Index].GetPrice1();
+ price += _isRepG2[state.Index].GetPrice(repIndex - 2);
+ }
+ }
+ return price;
+ }
+ /*
+ UInt32 GetPosLen2Price(UInt32 pos, UInt32 posState) const
+ {
+ if (pos >= kNumFullDistances)
+ return kIfinityPrice;
+ return _distancesPrices[0][pos] + _lenEncoder.GetPrice(0, posState);
+ }
+ UInt32 GetPosLen3Price(UInt32 pos, UInt32 len, UInt32 posState) const
+ {
+ UInt32 price;
+ UInt32 lenToPosState = GetLenToPosState(len);
+ if (pos < kNumFullDistances)
+ price = _distancesPrices[lenToPosState][pos];
+ else
+ price = _posSlotPrices[lenToPosState][GetPosSlot2(pos)] +
+ _alignPrices[pos & kAlignMask];
+ return price + _lenEncoder.GetPrice(len - kMatchMinLen, posState);
+ }
+ */
+ UInt32 GetPosLenPrice(UInt32 pos, UInt32 len, UInt32 posState) const
+ {
+ if (len == 2 && pos >= 0x80)
+ return kIfinityPrice;
+ UInt32 price;
+ UInt32 lenToPosState = GetLenToPosState(len);
+ if (pos < kNumFullDistances)
+ price = _distancesPrices[lenToPosState][pos];
+ else
+ price = _posSlotPrices[lenToPosState][GetPosSlot2(pos)] +
+ _alignPrices[pos & kAlignMask];
+ return price + _lenEncoder.GetPrice(len - kMatchMinLen, posState);
+ }
+
+ UInt32 Backward(UInt32 &backRes, UInt32 cur);
+ HRESULT GetOptimum(UInt32 position, UInt32 &backRes, UInt32 &lenRes);
+ HRESULT GetOptimumFast(UInt32 position, UInt32 &backRes, UInt32 &lenRes);
+
+ void FillPosSlotPrices();
+ void FillDistancesPrices();
+ void FillAlignPrices();
+
+ void ReleaseMFStream()
+ {
+ if (_matchFinder && _needReleaseMFStream)
+ {
+ _matchFinder->ReleaseStream();
+ _needReleaseMFStream = false;
+ }
+ }
+
+ void ReleaseStreams()
+ {
+ ReleaseMFStream();
+ ReleaseOutStream();
+ }
+
+ HRESULT Flush(UInt32 nowPos);
+ class CCoderReleaser
+ {
+ CEncoder *_coder;
+ public:
+ CCoderReleaser(CEncoder *coder): _coder(coder) {}
+ ~CCoderReleaser()
+ {
+ _coder->ReleaseStreams();
+ }
+ };
+ friend class CCoderReleaser;
+
+ void WriteEndMarker(UInt32 posState);
+
+public:
+ CEncoder();
+ void SetWriteEndMarkerMode(bool writeEndMarker)
+ { _writeEndMark= writeEndMarker; }
+
+ HRESULT Create();
+
+ MY_UNKNOWN_IMP3(
+ ICompressSetOutStream,
+ ICompressSetCoderProperties,
+ ICompressWriteCoderProperties
+ )
+
+ HRESULT Init();
+
+ // ICompressCoder interface
+ HRESULT SetStreams(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UInt64 *inSize, const UInt64 *outSize);
+ HRESULT CodeOneBlock(UInt64 *inSize, UInt64 *outSize, Int32 *finished);
+
+ HRESULT CodeReal(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress);
+
+ // ICompressCoder interface
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress);
+
+ // IInitMatchFinder interface
+ STDMETHOD(InitMatchFinder)(IMatchFinder *matchFinder);
+
+ // ICompressSetCoderProperties2
+ STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
+ const PROPVARIANT *properties, UInt32 numProperties);
+
+ // ICompressWriteCoderProperties
+ STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
+
+ STDMETHOD(SetOutStream)(ISequentialOutStream *outStream);
+ STDMETHOD(ReleaseOutStream)();
+
+ virtual ~CEncoder() {}
+};
+
+}}
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA/LZMA.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA/LZMA.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA/LZMA.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA/LZMA.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,82 @@
+// LZMA.h
+
+#ifndef __LZMA_H
+#define __LZMA_H
+
+namespace NCompress {
+namespace NLZMA {
+
+const UInt32 kNumRepDistances = 4;
+
+const int kNumStates = 12;
+
+const Byte kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5};
+const Byte kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10};
+const Byte kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};
+const Byte kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11};
+
+class CState
+{
+public:
+ Byte Index;
+ void Init() { Index = 0; }
+ void UpdateChar() { Index = kLiteralNextStates[Index]; }
+ void UpdateMatch() { Index = kMatchNextStates[Index]; }
+ void UpdateRep() { Index = kRepNextStates[Index]; }
+ void UpdateShortRep() { Index = kShortRepNextStates[Index]; }
+ bool IsCharState() const { return Index < 7; }
+};
+
+const int kNumPosSlotBits = 6;
+const int kDicLogSizeMin = 0;
+const int kDicLogSizeMax = 32;
+const int kDistTableSizeMax = kDicLogSizeMax * 2;
+
+const UInt32 kNumLenToPosStates = 4;
+
+inline UInt32 GetLenToPosState(UInt32 len)
+{
+ len -= 2;
+ if (len < kNumLenToPosStates)
+ return len;
+ return kNumLenToPosStates - 1;
+}
+
+namespace NLength {
+
+const int kNumPosStatesBitsMax = 4;
+const UInt32 kNumPosStatesMax = (1 << kNumPosStatesBitsMax);
+
+const int kNumPosStatesBitsEncodingMax = 4;
+const UInt32 kNumPosStatesEncodingMax = (1 << kNumPosStatesBitsEncodingMax);
+
+const int kNumLowBits = 3;
+const int kNumMidBits = 3;
+const int kNumHighBits = 8;
+const UInt32 kNumLowSymbols = 1 << kNumLowBits;
+const UInt32 kNumMidSymbols = 1 << kNumMidBits;
+const UInt32 kNumSymbolsTotal = kNumLowSymbols + kNumMidSymbols + (1 << kNumHighBits);
+
+}
+
+const UInt32 kMatchMinLen = 2;
+const UInt32 kMatchMaxLen = kMatchMinLen + NLength::kNumSymbolsTotal - 1;
+
+const int kNumAlignBits = 4;
+const UInt32 kAlignTableSize = 1 << kNumAlignBits;
+const UInt32 kAlignMask = (kAlignTableSize - 1);
+
+const UInt32 kStartPosModelIndex = 4;
+const UInt32 kEndPosModelIndex = 14;
+const UInt32 kNumPosModels = kEndPosModelIndex - kStartPosModelIndex;
+
+const UInt32 kNumFullDistances = 1 << (kEndPosModelIndex / 2);
+
+const int kNumLitPosStatesBitsEncodingMax = 4;
+const int kNumLitContextBitsMax = 8;
+
+const int kNumMoveBits = 5;
+
+}}
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA/StdAfx.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA/StdAfx.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA/StdAfx.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA/StdAfx.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/AloneLZMA.dsp squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/AloneLZMA.dsp
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/AloneLZMA.dsp 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/AloneLZMA.dsp 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,523 @@
+# Microsoft Developer Studio Project File - Name="AloneLZMA" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=AloneLZMA - Win32 DebugU
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "AloneLZMA.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "AloneLZMA.mak" CFG="AloneLZMA - Win32 DebugU"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "AloneLZMA - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "AloneLZMA - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE "AloneLZMA - Win32 ReleaseU" (based on "Win32 (x86) Console Application")
+!MESSAGE "AloneLZMA - Win32 DebugU" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "AloneLZMA - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /Yu"StdAfx.h" /FD /c
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\UTIL\lzma.exe" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "AloneLZMA - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /Yu"StdAfx.h" /FD /GZ /c
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x419 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\UTIL\lzma.exe" /pdbtype:sept
+
+!ELSEIF "$(CFG)" == "AloneLZMA - Win32 ReleaseU"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "ReleaseU"
+# PROP BASE Intermediate_Dir "ReleaseU"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "ReleaseU"
+# PROP Intermediate_Dir "ReleaseU"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_PAT" /D "COMPRESS_MF_BT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /Yu"StdAfx.h" /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\..\\" /D "NDEBUG" /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_CONSOLE" /Yu"StdAfx.h" /FD /c
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\UTIL\7za2.exe" /opt:NOWIN98
+# SUBTRACT BASE LINK32 /pdb:none
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\UTIL\lzma.exe" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "AloneLZMA - Win32 DebugU"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "DebugU"
+# PROP BASE Intermediate_Dir "DebugU"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "DebugU"
+# PROP Intermediate_Dir "DebugU"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_PAT" /D "COMPRESS_MF_BT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /Yu"StdAfx.h" /FD /GZ /c
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x419 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\UTIL\7za2.exe" /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\UTIL\lzma.exe" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "AloneLZMA - Win32 Release"
+# Name "AloneLZMA - Win32 Debug"
+# Name "AloneLZMA - Win32 ReleaseU"
+# Name "AloneLZMA - Win32 DebugU"
+# Begin Group "Spec"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\StdAfx.cpp
+# ADD CPP /Yc"StdAfx.h"
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# End Group
+# Begin Group "Compress"
+
+# PROP Default_Filter ""
+# Begin Group "LZMA"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\LZMA\LZMA.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZMA\LZMADecoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZMA\LZMADecoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZMA\LZMAEncoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZMA\LZMAEncoder.h
+# End Source File
+# End Group
+# Begin Group "RangeCoder"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\RangeCoder\RangeCoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\RangeCoder\RangeCoderBit.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\RangeCoder\RangeCoderBit.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\RangeCoder\RangeCoderBitTree.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\RangeCoder\RangeCoderOpt.h
+# End Source File
+# End Group
+# Begin Group "LZ"
+
+# PROP Default_Filter ""
+# Begin Group "Pat"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\LZ\Patricia\Pat.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\Patricia\Pat2.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\Patricia\Pat2H.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\Patricia\Pat2R.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\Patricia\Pat3H.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\Patricia\Pat4H.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\Patricia\PatMain.h
+# End Source File
+# End Group
+# Begin Group "BT"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\LZ\BinTree\BinTree.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\BinTree\BinTree2.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\BinTree\BinTree3.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\BinTree\BinTree3Z.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\BinTree\BinTree3ZMain.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\BinTree\BinTree4.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\BinTree\BinTree4b.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\BinTree\BinTreeMain.h
+# End Source File
+# End Group
+# Begin Group "HC"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\LZ\HashChain\HC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\HashChain\HC2.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\HashChain\HC3.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\HashChain\HC4.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\HashChain\HC4b.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\HashChain\HCMain.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\LZ\IMatchFinder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\LZInWindow.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\LZInWindow.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\LZOutWindow.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\LZOutWindow.h
+# End Source File
+# End Group
+# Begin Group "Branch"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\Branch\BranchX86.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\Branch\BranchX86.h
+# End Source File
+# End Group
+# Begin Group "LZMA_C"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\LZMA_C\LzmaDecode.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZMA_C\LzmaDecode.h
+# End Source File
+# End Group
+# End Group
+# Begin Group "Windows"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.h
+# End Source File
+# End Group
+# Begin Group "Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Common\Alloc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Alloc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CommandLineParser.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CommandLineParser.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CRC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Defs.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Defs.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyCom.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyWindows.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\String.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\String.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringConvert.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringConvert.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringToInt.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringToInt.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Types.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Vector.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Vector.h
+# End Source File
+# End Group
+# Begin Group "7zip Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Common\FileStreams.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FileStreams.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\InBuffer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\InBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OutBuffer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OutBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\..\ICoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\LzmaAlone.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\LzmaBench.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\LzmaBench.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\LzmaRam.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\LzmaRam.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\LzmaRamDecode.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=.\LzmaRamDecode.h
+# End Source File
+# End Target
+# End Project
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/AloneLZMA.dsw squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/AloneLZMA.dsw
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/AloneLZMA.dsw 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/AloneLZMA.dsw 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "AloneLZMA"=.\AloneLZMA.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/LzmaAlone.cpp squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/LzmaAlone.cpp
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/LzmaAlone.cpp 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/LzmaAlone.cpp 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,509 @@
+// LzmaAlone.cpp
+
+#include "StdAfx.h"
+
+#include "../../../Common/MyWindows.h"
+#include "../../../Common/MyInitGuid.h"
+
+#include <stdio.h>
+
+#if defined(_WIN32) || defined(OS2) || defined(MSDOS)
+#include <fcntl.h>
+#include <io.h>
+#define MY_SET_BINARY_MODE(file) setmode(fileno(file),O_BINARY)
+#else
+#define MY_SET_BINARY_MODE(file)
+#endif
+
+#include "../../../Common/CommandLineParser.h"
+#include "../../../Common/StringConvert.h"
+#include "../../../Common/StringToInt.h"
+
+#include "../../Common/FileStreams.h"
+#include "../../Common/StreamUtils.h"
+
+#include "../LZMA/LZMADecoder.h"
+#include "../LZMA/LZMAEncoder.h"
+
+#include "LzmaBench.h"
+#include "LzmaRam.h"
+
+extern "C"
+{
+#include "LzmaRamDecode.h"
+}
+
+using namespace NCommandLineParser;
+
+#ifdef _WIN32
+bool g_IsNT = false;
+static inline bool IsItWindowsNT()
+{
+ OSVERSIONINFO versionInfo;
+ versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
+ if (!::GetVersionEx(&versionInfo))
+ return false;
+ return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
+}
+#endif
+
+static const char *kCantAllocate = "Can not allocate memory";
+static const char *kReadError = "Read error";
+static const char *kWriteError = "Write error";
+
+namespace NKey {
+enum Enum
+{
+ kHelp1 = 0,
+ kHelp2,
+ kMode,
+ kDictionary,
+ kFastBytes,
+ kLitContext,
+ kLitPos,
+ kPosBits,
+ kMatchFinder,
+ kEOS,
+ kStdIn,
+ kStdOut,
+ kFilter86
+};
+}
+
+static const CSwitchForm kSwitchForms[] =
+{
+ { L"?", NSwitchType::kSimple, false },
+ { L"H", NSwitchType::kSimple, false },
+ { L"A", NSwitchType::kUnLimitedPostString, false, 1 },
+ { L"D", NSwitchType::kUnLimitedPostString, false, 1 },
+ { L"FB", NSwitchType::kUnLimitedPostString, false, 1 },
+ { L"LC", NSwitchType::kUnLimitedPostString, false, 1 },
+ { L"LP", NSwitchType::kUnLimitedPostString, false, 1 },
+ { L"PB", NSwitchType::kUnLimitedPostString, false, 1 },
+ { L"MF", NSwitchType::kUnLimitedPostString, false, 1 },
+ { L"EOS", NSwitchType::kSimple, false },
+ { L"SI", NSwitchType::kSimple, false },
+ { L"SO", NSwitchType::kSimple, false },
+ { L"F86", NSwitchType::kSimple, false }
+};
+
+static const int kNumSwitches = sizeof(kSwitchForms) / sizeof(kSwitchForms[0]);
+
+static void PrintHelp()
+{
+ fprintf(stderr, "\nUsage: LZMA <e|d> inputFile outputFile [<switches>...]\n"
+ " e: encode file\n"
+ " d: decode file\n"
+ " b: Benchmark\n"
+ "<Switches>\n"
+ " -a{N}: set compression mode - [0, 2], default: 2 (max)\n"
+ " -d{N}: set dictionary - [0,28], default: 23 (8MB)\n"
+ " -fb{N}: set number of fast bytes - [5, 273], default: 128\n"
+ " -lc{N}: set number of literal context bits - [0, 8], default: 3\n"
+ " -lp{N}: set number of literal pos bits - [0, 4], default: 0\n"
+ " -pb{N}: set number of pos bits - [0, 4], default: 2\n"
+ " -mf{MF_ID}: set Match Finder: [bt2, bt3, bt4, bt4b, pat2r, pat2,\n"
+ " pat2h, pat3h, pat4h, hc3, hc4], default: bt4\n"
+ " -eos: write End Of Stream marker\n"
+ " -si: read data from stdin\n"
+ " -so: write data to stdout\n"
+ );
+}
+
+static void PrintHelpAndExit(const char *s)
+{
+ fprintf(stderr, "\nError: %s\n\n", s);
+ PrintHelp();
+ throw -1;
+}
+
+static void IncorrectCommand()
+{
+ PrintHelpAndExit("Incorrect command");
+}
+
+static void WriteArgumentsToStringList(int numArguments, const char *arguments[],
+ UStringVector &strings)
+{
+ for(int i = 1; i < numArguments; i++)
+ strings.Add(MultiByteToUnicodeString(arguments[i]));
+}
+
+static bool GetNumber(const wchar_t *s, UInt32 &value)
+{
+ value = 0;
+ if (MyStringLen(s) == 0)
+ return false;
+ const wchar_t *end;
+ UInt64 res = ConvertStringToUInt64(s, &end);
+ if (*end != L'\0')
+ return false;
+ if (res > 0xFFFFFFFF)
+ return false;
+ value = UInt32(res);
+ return true;
+}
+
+int main2(int n, const char *args[])
+{
+ #ifdef _WIN32
+ g_IsNT = IsItWindowsNT();
+ #endif
+
+ fprintf(stderr, "\nLZMA 4.32 Copyright (c) 1999-2005 Igor Pavlov 2005-12-09\n");
+
+ if (n == 1)
+ {
+ PrintHelp();
+ return 0;
+ }
+
+ if (sizeof(Byte) != 1 || sizeof(UInt32) < 4 || sizeof(UInt64) < 4)
+ {
+ fprintf(stderr, "Unsupported base types. Edit Common/Types.h and recompile");
+ return 1;
+ }
+
+ UStringVector commandStrings;
+ WriteArgumentsToStringList(n, args, commandStrings);
+ CParser parser(kNumSwitches);
+ try
+ {
+ parser.ParseStrings(kSwitchForms, commandStrings);
+ }
+ catch(...)
+ {
+ IncorrectCommand();
+ }
+
+ if(parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs)
+ {
+ PrintHelp();
+ return 0;
+ }
+ const UStringVector &nonSwitchStrings = parser.NonSwitchStrings;
+
+ int paramIndex = 0;
+ if (paramIndex >= nonSwitchStrings.Size())
+ IncorrectCommand();
+ const UString &command = nonSwitchStrings[paramIndex++];
+
+ bool dictionaryIsDefined = false;
+ UInt32 dictionary = 1 << 21;
+ if(parser[NKey::kDictionary].ThereIs)
+ {
+ UInt32 dicLog;
+ if (!GetNumber(parser[NKey::kDictionary].PostStrings[0], dicLog))
+ IncorrectCommand();
+ dictionary = 1 << dicLog;
+ dictionaryIsDefined = true;
+ }
+ UString mf = L"BT4";
+ if (parser[NKey::kMatchFinder].ThereIs)
+ mf = parser[NKey::kMatchFinder].PostStrings[0];
+
+ if (command.CompareNoCase(L"b") == 0)
+ {
+ const UInt32 kNumDefaultItereations = 10;
+ UInt32 numIterations = kNumDefaultItereations;
+ {
+ if (paramIndex < nonSwitchStrings.Size())
+ if (!GetNumber(nonSwitchStrings[paramIndex++], numIterations))
+ numIterations = kNumDefaultItereations;
+ }
+ return LzmaBenchmark(stderr, numIterations, dictionary,
+ mf.CompareNoCase(L"BT4") == 0);
+ }
+
+ bool encodeMode = false;
+ if (command.CompareNoCase(L"e") == 0)
+ encodeMode = true;
+ else if (command.CompareNoCase(L"d") == 0)
+ encodeMode = false;
+ else
+ IncorrectCommand();
+
+ bool stdInMode = parser[NKey::kStdIn].ThereIs;
+ bool stdOutMode = parser[NKey::kStdOut].ThereIs;
+
+ CMyComPtr<ISequentialInStream> inStream;
+ CInFileStream *inStreamSpec = 0;
+ if (stdInMode)
+ {
+ inStream = new CStdInFileStream;
+ MY_SET_BINARY_MODE(stdin);
+ }
+ else
+ {
+ if (paramIndex >= nonSwitchStrings.Size())
+ IncorrectCommand();
+ const UString &inputName = nonSwitchStrings[paramIndex++];
+ inStreamSpec = new CInFileStream;
+ inStream = inStreamSpec;
+ if (!inStreamSpec->Open(GetSystemString(inputName)))
+ {
+ fprintf(stderr, "\nError: can not open input file %s\n",
+ (const char *)GetOemString(inputName));
+ return 1;
+ }
+ }
+
+ CMyComPtr<ISequentialOutStream> outStream;
+ if (stdOutMode)
+ {
+ outStream = new CStdOutFileStream;
+ MY_SET_BINARY_MODE(stdout);
+ }
+ else
+ {
+ if (paramIndex >= nonSwitchStrings.Size())
+ IncorrectCommand();
+ const UString &outputName = nonSwitchStrings[paramIndex++];
+ COutFileStream *outStreamSpec = new COutFileStream;
+ outStream = outStreamSpec;
+ if (!outStreamSpec->Create(GetSystemString(outputName), true))
+ {
+ fprintf(stderr, "\nError: can not open output file %s\n",
+ (const char *)GetOemString(outputName));
+ return 1;
+ }
+ }
+
+ if (parser[NKey::kFilter86].ThereIs)
+ {
+ // -f86 switch is for x86 filtered mode: BCJ + LZMA.
+ if (parser[NKey::kEOS].ThereIs || stdInMode)
+ throw "Can not use stdin in this mode";
+ UInt64 fileSize;
+ inStreamSpec->File.GetLength(fileSize);
+ if (fileSize > 0xF0000000)
+ throw "File is too big";
+ UInt32 inSize = (UInt32)fileSize;
+ Byte *inBuffer = 0;
+ if (inSize != 0)
+ {
+ inBuffer = (Byte *)MyAlloc((size_t)inSize);
+ if (inBuffer == 0)
+ throw kCantAllocate;
+ }
+
+ UInt32 processedSize;
+ if (ReadStream(inStream, inBuffer, (UInt32)inSize, &processedSize) != S_OK)
+ throw "Can not read";
+ if ((UInt32)inSize != processedSize)
+ throw "Read size error";
+
+ Byte *outBuffer = 0;
+ size_t outSizeProcessed;
+ if (encodeMode)
+ {
+ // we allocate 105% of original size for output buffer
+ size_t outSize = (size_t)fileSize / 20 * 21 + (1 << 16);
+ if (outSize != 0)
+ {
+ outBuffer = (Byte *)MyAlloc((size_t)outSize);
+ if (outBuffer == 0)
+ throw kCantAllocate;
+ }
+ if (!dictionaryIsDefined)
+ dictionary = 1 << 23;
+ int res = LzmaRamEncode(inBuffer, inSize, outBuffer, outSize, &outSizeProcessed,
+ dictionary, SZ_FILTER_AUTO);
+ if (res != 0)
+ {
+ fprintf(stderr, "\nEncoder error = %d\n", (int)res);
+ return 1;
+ }
+ }
+ else
+ {
+ size_t outSize;
+ if (LzmaRamGetUncompressedSize(inBuffer, inSize, &outSize) != 0)
+ throw "data error";
+ if (outSize != 0)
+ {
+ outBuffer = (Byte *)MyAlloc(outSize);
+ if (outBuffer == 0)
+ throw kCantAllocate;
+ }
+ int res = LzmaRamDecompress(inBuffer, inSize, outBuffer, outSize, &outSizeProcessed, malloc, free);
+ if (res != 0)
+ throw "LzmaDecoder error";
+ }
+ if (WriteStream(outStream, outBuffer, (UInt32)outSizeProcessed, &processedSize) != S_OK)
+ throw kWriteError;
+ MyFree(outBuffer);
+ MyFree(inBuffer);
+ return 0;
+ }
+
+
+ UInt64 fileSize;
+ if (encodeMode)
+ {
+ NCompress::NLZMA::CEncoder *encoderSpec =
+ new NCompress::NLZMA::CEncoder;
+ CMyComPtr<ICompressCoder> encoder = encoderSpec;
+
+ if (!dictionaryIsDefined)
+ dictionary = 1 << 23;
+
+ UInt32 posStateBits = 2;
+ UInt32 litContextBits = 3; // for normal files
+ // UInt32 litContextBits = 0; // for 32-bit data
+ UInt32 litPosBits = 0;
+ // UInt32 litPosBits = 2; // for 32-bit data
+ UInt32 algorithm = 2;
+ UInt32 numFastBytes = 128;
+
+ bool eos = parser[NKey::kEOS].ThereIs || stdInMode;
+
+ if(parser[NKey::kMode].ThereIs)
+ if (!GetNumber(parser[NKey::kMode].PostStrings[0], algorithm))
+ IncorrectCommand();
+
+ if(parser[NKey::kFastBytes].ThereIs)
+ if (!GetNumber(parser[NKey::kFastBytes].PostStrings[0], numFastBytes))
+ IncorrectCommand();
+ if(parser[NKey::kLitContext].ThereIs)
+ if (!GetNumber(parser[NKey::kLitContext].PostStrings[0], litContextBits))
+ IncorrectCommand();
+ if(parser[NKey::kLitPos].ThereIs)
+ if (!GetNumber(parser[NKey::kLitPos].PostStrings[0], litPosBits))
+ IncorrectCommand();
+ if(parser[NKey::kPosBits].ThereIs)
+ if (!GetNumber(parser[NKey::kPosBits].PostStrings[0], posStateBits))
+ IncorrectCommand();
+
+ PROPID propIDs[] =
+ {
+ NCoderPropID::kDictionarySize,
+ NCoderPropID::kPosStateBits,
+ NCoderPropID::kLitContextBits,
+ NCoderPropID::kLitPosBits,
+ NCoderPropID::kAlgorithm,
+ NCoderPropID::kNumFastBytes,
+ NCoderPropID::kMatchFinder,
+ NCoderPropID::kEndMarker
+ };
+ const int kNumProps = sizeof(propIDs) / sizeof(propIDs[0]);
+ /*
+ NWindows::NCOM::CPropVariant properties[kNumProps];
+ properties[0] = UInt32(dictionary);
+ properties[1] = UInt32(posStateBits);
+ properties[2] = UInt32(litContextBits);
+
+ properties[3] = UInt32(litPosBits);
+ properties[4] = UInt32(algorithm);
+ properties[5] = UInt32(numFastBytes);
+ properties[6] = mf;
+ properties[7] = eos;
+ */
+ PROPVARIANT properties[kNumProps];
+ for (int p = 0; p < 6; p++)
+ properties[p].vt = VT_UI4;
+ properties[0].ulVal = UInt32(dictionary);
+ properties[1].ulVal = UInt32(posStateBits);
+ properties[2].ulVal = UInt32(litContextBits);
+ properties[3].ulVal = UInt32(litPosBits);
+ properties[4].ulVal = UInt32(algorithm);
+ properties[5].ulVal = UInt32(numFastBytes);
+
+ properties[6].vt = VT_BSTR;
+ properties[6].bstrVal = (BSTR)(const wchar_t *)mf;
+
+ properties[7].vt = VT_BOOL;
+ properties[7].boolVal = eos ? VARIANT_TRUE : VARIANT_FALSE;
+
+ if (encoderSpec->SetCoderProperties(propIDs, properties, kNumProps) != S_OK)
+ IncorrectCommand();
+ encoderSpec->WriteCoderProperties(outStream);
+
+ if (eos || stdInMode)
+ fileSize = (UInt64)(Int64)-1;
+ else
+ inStreamSpec->File.GetLength(fileSize);
+
+ for (int i = 0; i < 8; i++)
+ {
+ Byte b = Byte(fileSize >> (8 * i));
+ if (outStream->Write(&b, 1, 0) != S_OK)
+ {
+ fprintf(stderr, kWriteError);
+ return 1;
+ }
+ }
+ HRESULT result = encoder->Code(inStream, outStream, 0, 0, 0);
+ if (result == E_OUTOFMEMORY)
+ {
+ fprintf(stderr, "\nError: Can not allocate memory\n");
+ return 1;
+ }
+ else if (result != S_OK)
+ {
+ fprintf(stderr, "\nEncoder error = %X\n", (unsigned int)result);
+ return 1;
+ }
+ }
+ else
+ {
+ NCompress::NLZMA::CDecoder *decoderSpec =
+ new NCompress::NLZMA::CDecoder;
+ CMyComPtr<ICompressCoder> decoder = decoderSpec;
+ const UInt32 kPropertiesSize = 5;
+ Byte properties[kPropertiesSize];
+ UInt32 processedSize;
+ if (ReadStream(inStream, properties, kPropertiesSize, &processedSize) != S_OK)
+ {
+ fprintf(stderr, kReadError);
+ return 1;
+ }
+ if (processedSize != kPropertiesSize)
+ {
+ fprintf(stderr, kReadError);
+ return 1;
+ }
+ if (decoderSpec->SetDecoderProperties2(properties, kPropertiesSize) != S_OK)
+ {
+ fprintf(stderr, "SetDecoderProperties error");
+ return 1;
+ }
+ fileSize = 0;
+ for (int i = 0; i < 8; i++)
+ {
+ Byte b;
+ if (inStream->Read(&b, 1, &processedSize) != S_OK)
+ {
+ fprintf(stderr, kReadError);
+ return 1;
+ }
+ if (processedSize != 1)
+ {
+ fprintf(stderr, kReadError);
+ return 1;
+ }
+ fileSize |= ((UInt64)b) << (8 * i);
+ }
+ if (decoder->Code(inStream, outStream, 0, &fileSize, 0) != S_OK)
+ {
+ fprintf(stderr, "Decoder error");
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int main(int n, const char *args[])
+{
+ try { return main2(n, args); }
+ catch(const char *s)
+ {
+ fprintf(stderr, "\nError: %s\n", s);
+ return 1;
+ }
+ catch(...)
+ {
+ fprintf(stderr, "\nError\n");
+ return 1;
+ }
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/LzmaBench.cpp squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/LzmaBench.cpp
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/LzmaBench.cpp 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/LzmaBench.cpp 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,508 @@
+// LzmaBench.cpp
+
+#include "StdAfx.h"
+
+#include "LzmaBench.h"
+
+#ifndef _WIN32
+#include <time.h>
+#endif
+
+#include "../../../Common/CRC.h"
+#include "../LZMA/LZMADecoder.h"
+#include "../LZMA/LZMAEncoder.h"
+
+static const UInt32 kAdditionalSize =
+#ifdef _WIN32_WCE
+(1 << 20);
+#else
+(6 << 20);
+#endif
+
+static const UInt32 kCompressedAdditionalSize = (1 << 10);
+static const UInt32 kMaxLzmaPropSize = 10;
+
+class CRandomGenerator
+{
+ UInt32 A1;
+ UInt32 A2;
+public:
+ CRandomGenerator() { Init(); }
+ void Init() { A1 = 362436069; A2 = 521288629;}
+ UInt32 GetRnd()
+ {
+ return
+ ((A1 = 36969 * (A1 & 0xffff) + (A1 >> 16)) << 16) ^
+ ((A2 = 18000 * (A2 & 0xffff) + (A2 >> 16)) );
+ }
+};
+
+class CBitRandomGenerator
+{
+ CRandomGenerator RG;
+ UInt32 Value;
+ int NumBits;
+public:
+ void Init()
+ {
+ Value = 0;
+ NumBits = 0;
+ }
+ UInt32 GetRnd(int numBits)
+ {
+ if (NumBits > numBits)
+ {
+ UInt32 result = Value & ((1 << numBits) - 1);
+ Value >>= numBits;
+ NumBits -= numBits;
+ return result;
+ }
+ numBits -= NumBits;
+ UInt32 result = (Value << numBits);
+ Value = RG.GetRnd();
+ result |= Value & ((1 << numBits) - 1);
+ Value >>= numBits;
+ NumBits = 32 - numBits;
+ return result;
+ }
+};
+
+class CBenchRandomGenerator
+{
+ CBitRandomGenerator RG;
+ UInt32 Pos;
+public:
+ UInt32 BufferSize;
+ Byte *Buffer;
+ CBenchRandomGenerator(): Buffer(0) {}
+ ~CBenchRandomGenerator() { delete []Buffer; }
+ void Init() { RG.Init(); }
+ void Set(UInt32 bufferSize)
+ {
+ delete []Buffer;
+ Buffer = 0;
+ Buffer = new Byte[bufferSize];
+ Pos = 0;
+ BufferSize = bufferSize;
+ }
+ UInt32 GetRndBit() { return RG.GetRnd(1); }
+ /*
+ UInt32 GetLogRand(int maxLen)
+ {
+ UInt32 len = GetRnd() % (maxLen + 1);
+ return GetRnd() & ((1 << len) - 1);
+ }
+ */
+ UInt32 GetLogRandBits(int numBits)
+ {
+ UInt32 len = RG.GetRnd(numBits);
+ return RG.GetRnd(len);
+ }
+ UInt32 GetOffset()
+ {
+ if (GetRndBit() == 0)
+ return GetLogRandBits(4);
+ return (GetLogRandBits(4) << 10) | RG.GetRnd(10);
+ }
+ UInt32 GetLen()
+ {
+ if (GetRndBit() == 0)
+ return RG.GetRnd(2);
+ if (GetRndBit() == 0)
+ return 4 + RG.GetRnd(3);
+ return 12 + RG.GetRnd(4);
+ }
+ void Generate()
+ {
+ while(Pos < BufferSize)
+ {
+ if (GetRndBit() == 0 || Pos < 1)
+ Buffer[Pos++] = Byte(RG.GetRnd(8));
+ else
+ {
+ UInt32 offset = GetOffset();
+ while (offset >= Pos)
+ offset >>= 1;
+ offset += 1;
+ UInt32 len = 2 + GetLen();
+ for (UInt32 i = 0; i < len && Pos < BufferSize; i++, Pos++)
+ Buffer[Pos] = Buffer[Pos - offset];
+ }
+ }
+ }
+};
+
+class CBenchmarkInStream:
+ public ISequentialInStream,
+ public CMyUnknownImp
+{
+ const Byte *Data;
+ UInt32 Pos;
+ UInt32 Size;
+public:
+ MY_UNKNOWN_IMP
+ void Init(const Byte *data, UInt32 size)
+ {
+ Data = data;
+ Size = size;
+ Pos = 0;
+ }
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+};
+
+STDMETHODIMP CBenchmarkInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 remain = Size - Pos;
+ if (size > remain)
+ size = remain;
+ for (UInt32 i = 0; i < size; i++)
+ ((Byte *)data)[i] = Data[Pos + i];
+ Pos += size;
+ if(processedSize != NULL)
+ *processedSize = size;
+ return S_OK;
+}
+
+class CBenchmarkOutStream:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+ UInt32 BufferSize;
+ FILE *_f;
+public:
+ UInt32 Pos;
+ Byte *Buffer;
+ CBenchmarkOutStream(): _f(0), Buffer(0) {}
+ virtual ~CBenchmarkOutStream() { delete []Buffer; }
+ void Init(FILE *f, UInt32 bufferSize)
+ {
+ delete []Buffer;
+ Buffer = 0;
+ Buffer = new Byte[bufferSize];
+ Pos = 0;
+ BufferSize = bufferSize;
+ _f = f;
+ }
+ MY_UNKNOWN_IMP
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+};
+
+STDMETHODIMP CBenchmarkOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 i;
+ for (i = 0; i < size && Pos < BufferSize; i++)
+ Buffer[Pos++] = ((const Byte *)data)[i];
+ if(processedSize != NULL)
+ *processedSize = i;
+ if (i != size)
+ {
+ fprintf(_f, "\nERROR: Buffer is full\n");
+ return E_FAIL;
+ }
+ return S_OK;
+}
+
+class CCrcOutStream:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+public:
+ CCRC CRC;
+ MY_UNKNOWN_IMP
+ void Init() { CRC.Init(); }
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+};
+
+STDMETHODIMP CCrcOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ CRC.Update(data, size);
+ if(processedSize != NULL)
+ *processedSize = size;
+ return S_OK;
+}
+
+static UInt64 GetTimeCount()
+{
+ #ifdef _WIN32
+ LARGE_INTEGER value;
+ if (::QueryPerformanceCounter(&value))
+ return value.QuadPart;
+ return GetTickCount();
+ #else
+ return clock();
+ #endif
+}
+
+static UInt64 GetFreq()
+{
+ #ifdef _WIN32
+ LARGE_INTEGER value;
+ if (::QueryPerformanceFrequency(&value))
+ return value.QuadPart;
+ return 1000;
+ #else
+ return CLOCKS_PER_SEC;
+ #endif
+}
+
+struct CProgressInfo:
+ public ICompressProgressInfo,
+ public CMyUnknownImp
+{
+ UInt64 ApprovedStart;
+ UInt64 InSize;
+ UInt64 Time;
+ void Init()
+ {
+ InSize = 0;
+ Time = 0;
+ }
+ MY_UNKNOWN_IMP
+ STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
+};
+
+STDMETHODIMP CProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
+{
+ if (*inSize >= ApprovedStart && InSize == 0)
+ {
+ Time = ::GetTimeCount();
+ InSize = *inSize;
+ }
+ return S_OK;
+}
+
+static const int kSubBits = 8;
+
+static UInt32 GetLogSize(UInt32 size)
+{
+ for (int i = kSubBits; i < 32; i++)
+ for (UInt32 j = 0; j < (1 << kSubBits); j++)
+ if (size <= (((UInt32)1) << i) + (j << (i - kSubBits)))
+ return (i << kSubBits) + j;
+ return (32 << kSubBits);
+}
+
+static UInt64 MyMultDiv64(UInt64 value, UInt64 elapsedTime)
+{
+ UInt64 freq = GetFreq();
+ UInt64 elTime = elapsedTime;
+ while(freq > 1000000)
+ {
+ freq >>= 1;
+ elTime >>= 1;
+ }
+ if (elTime == 0)
+ elTime = 1;
+ return value * freq / elTime;
+}
+
+static UInt64 GetCompressRating(UInt32 dictionarySize, bool isBT4,
+ UInt64 elapsedTime, UInt64 size)
+{
+ UInt64 numCommandsForOne;
+ if (isBT4)
+ {
+ UInt64 t = GetLogSize(dictionarySize) - (19 << kSubBits);
+ numCommandsForOne = 2000 + ((t * t * 68) >> (2 * kSubBits));
+ }
+ else
+ {
+ UInt64 t = GetLogSize(dictionarySize) - (15 << kSubBits);
+ numCommandsForOne = 1500 + ((t * t * 41) >> (2 * kSubBits));
+ }
+ UInt64 numCommands = (UInt64)(size) * numCommandsForOne;
+ return MyMultDiv64(numCommands, elapsedTime);
+}
+
+static UInt64 GetDecompressRating(UInt64 elapsedTime,
+ UInt64 outSize, UInt64 inSize)
+{
+ UInt64 numCommands = inSize * 250 + outSize * 21;
+ return MyMultDiv64(numCommands, elapsedTime);
+}
+
+/*
+static UInt64 GetTotalRating(
+ UInt32 dictionarySize,
+ bool isBT4,
+ UInt64 elapsedTimeEn, UInt64 sizeEn,
+ UInt64 elapsedTimeDe,
+ UInt64 inSizeDe, UInt64 outSizeDe)
+{
+ return (GetCompressRating(dictionarySize, isBT4, elapsedTimeEn, sizeEn) +
+ GetDecompressRating(elapsedTimeDe, inSizeDe, outSizeDe)) / 2;
+}
+*/
+
+static void PrintRating(FILE *f, UInt64 rating)
+{
+ fprintf(f, "%5d MIPS", (unsigned int)(rating / 1000000));
+}
+
+static void PrintResults(
+ FILE *f,
+ UInt32 dictionarySize,
+ bool isBT4,
+ UInt64 elapsedTime,
+ UInt64 size,
+ bool decompressMode, UInt64 secondSize)
+{
+ UInt64 speed = MyMultDiv64(size, elapsedTime);
+ fprintf(f, "%6d KB/s ", (unsigned int)(speed / 1024));
+ UInt64 rating;
+ if (decompressMode)
+ rating = GetDecompressRating(elapsedTime, size, secondSize);
+ else
+ rating = GetCompressRating(dictionarySize, isBT4, elapsedTime, size);
+ PrintRating(f, rating);
+}
+
+static void ThrowError(FILE *f, HRESULT result, const char *s)
+{
+ fprintf(f, "\nError: ");
+ if (result == E_ABORT)
+ fprintf(f, "User break");
+ if (result == E_OUTOFMEMORY)
+ fprintf(f, "Can not allocate memory");
+ else
+ fprintf(f, s);
+ fprintf(f, "\n");
+}
+
+const wchar_t *bt2 = L"BT2";
+const wchar_t *bt4 = L"BT4";
+
+int LzmaBenchmark(FILE *f, UInt32 numIterations, UInt32 dictionarySize, bool isBT4)
+{
+ if (numIterations == 0)
+ return 0;
+ if (dictionarySize < (1 << 19) && isBT4 || dictionarySize < (1 << 15))
+ {
+ fprintf(f, "\nError: dictionary size for benchmark must be >= 19 (512 KB)\n");
+ return 1;
+ }
+ fprintf(f, "\n Compressing Decompressing\n\n");
+ NCompress::NLZMA::CEncoder *encoderSpec = new NCompress::NLZMA::CEncoder;
+ CMyComPtr<ICompressCoder> encoder = encoderSpec;
+
+ NCompress::NLZMA::CDecoder *decoderSpec = new NCompress::NLZMA::CDecoder;
+ CMyComPtr<ICompressCoder> decoder = decoderSpec;
+
+ CBenchmarkOutStream *propStreamSpec = new CBenchmarkOutStream;
+ CMyComPtr<ISequentialOutStream> propStream = propStreamSpec;
+ propStreamSpec->Init(f, kMaxLzmaPropSize);
+
+ PROPID propIDs[] =
+ {
+ NCoderPropID::kDictionarySize,
+ NCoderPropID::kMatchFinder
+ };
+ const int kNumProps = sizeof(propIDs) / sizeof(propIDs[0]);
+ PROPVARIANT properties[kNumProps];
+ properties[0].vt = VT_UI4;
+ properties[0].ulVal = UInt32(dictionarySize);
+
+ properties[1].vt = VT_BSTR;
+ properties[1].bstrVal = isBT4 ? (BSTR)bt4: (BSTR)bt2;
+
+ const UInt32 kBufferSize = dictionarySize + kAdditionalSize;
+ const UInt32 kCompressedBufferSize = (kBufferSize / 2) + kCompressedAdditionalSize;
+
+ if (encoderSpec->SetCoderProperties(propIDs, properties, kNumProps) != S_OK)
+ {
+ fprintf(f, "\nError: Incorrect command\n");
+ return 1;
+ }
+ encoderSpec->WriteCoderProperties(propStream);
+
+ CBenchRandomGenerator rg;
+ rg.Init();
+ rg.Set(kBufferSize);
+ rg.Generate();
+ CCRC crc;
+ crc.Update(rg.Buffer, rg.BufferSize);
+
+ CProgressInfo *progressInfoSpec = new CProgressInfo;
+ CMyComPtr<ICompressProgressInfo> progressInfo = progressInfoSpec;
+
+ progressInfoSpec->ApprovedStart = dictionarySize;
+
+ UInt64 totalBenchSize = 0;
+ UInt64 totalEncodeTime = 0;
+ UInt64 totalDecodeTime = 0;
+ UInt64 totalCompressedSize = 0;
+
+ for (UInt32 i = 0; i < numIterations; i++)
+ {
+ progressInfoSpec->Init();
+ CBenchmarkInStream *inStreamSpec = new CBenchmarkInStream;
+ inStreamSpec->Init(rg.Buffer, rg.BufferSize);
+ CMyComPtr<ISequentialInStream> inStream = inStreamSpec;
+ CBenchmarkOutStream *outStreamSpec = new CBenchmarkOutStream;
+ outStreamSpec->Init(f, kCompressedBufferSize);
+ CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
+ HRESULT result = encoder->Code(inStream, outStream, 0, 0, progressInfo);
+ UInt64 encodeTime = ::GetTimeCount() - progressInfoSpec->Time;
+ UInt32 compressedSize = outStreamSpec->Pos;
+ if(result != S_OK)
+ {
+ ThrowError(f, result, "Encoder Error");
+ return 1;
+ }
+ if (progressInfoSpec->InSize == 0)
+ {
+ fprintf(f, "\nError: Internal ERROR 1282\n");
+ return 1;
+ }
+
+ ///////////////////////
+ // Decompressing
+
+ CCrcOutStream *crcOutStreamSpec = new CCrcOutStream;
+ CMyComPtr<ISequentialOutStream> crcOutStream = crcOutStreamSpec;
+
+ UInt64 decodeTime;
+ for (int j = 0; j < 2; j++)
+ {
+ inStreamSpec->Init(outStreamSpec->Buffer, compressedSize);
+ crcOutStreamSpec->Init();
+
+ if (decoderSpec->SetDecoderProperties2(propStreamSpec->Buffer, propStreamSpec->Pos) != S_OK)
+ {
+ fprintf(f, "\nError: Set Decoder Properties Error\n");
+ return 1;
+ }
+ UInt64 outSize = kBufferSize;
+ UInt64 startTime = ::GetTimeCount();
+ result = decoder->Code(inStream, crcOutStream, 0, &outSize, 0);
+ decodeTime = ::GetTimeCount() - startTime;
+ if(result != S_OK)
+ {
+ ThrowError(f, result, "Decode Error");
+ return 1;
+ }
+ if (crcOutStreamSpec->CRC.GetDigest() != crc.GetDigest())
+ {
+ fprintf(f, "\nError: CRC Error\n");
+ return 1;
+ }
+ }
+ UInt64 benchSize = kBufferSize - progressInfoSpec->InSize;
+ PrintResults(f, dictionarySize, isBT4, encodeTime, benchSize, false, 0);
+ fprintf(f, " ");
+ PrintResults(f, dictionarySize, isBT4, decodeTime, kBufferSize, true, compressedSize);
+ fprintf(f, "\n");
+
+ totalBenchSize += benchSize;
+ totalEncodeTime += encodeTime;
+ totalDecodeTime += decodeTime;
+ totalCompressedSize += compressedSize;
+ }
+ fprintf(f, "---------------------------------------------------\n");
+ PrintResults(f, dictionarySize, isBT4, totalEncodeTime, totalBenchSize, false, 0);
+ fprintf(f, " ");
+ PrintResults(f, dictionarySize, isBT4, totalDecodeTime,
+ kBufferSize * numIterations, true, totalCompressedSize);
+ fprintf(f, " Average\n");
+ return 0;
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/LzmaBench.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/LzmaBench.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/LzmaBench.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/LzmaBench.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,11 @@
+// LzmaBench.h
+
+#ifndef __LzmaBench_h
+#define __LzmaBench_h
+
+#include <stdio.h>
+#include "../../../Common/Types.h"
+
+int LzmaBenchmark(FILE *f, UInt32 numIterations, UInt32 dictionarySize, bool isBT4);
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/LzmaRam.cpp squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/LzmaRam.cpp
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/LzmaRam.cpp 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/LzmaRam.cpp 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,228 @@
+// LzmaRam.cpp
+
+#include "StdAfx.h"
+#include "../../../Common/Types.h"
+#include "../LZMA/LZMADecoder.h"
+#include "../LZMA/LZMAEncoder.h"
+#include "LzmaRam.h"
+
+extern "C"
+{
+#include "../Branch/BranchX86.h"
+}
+
+class CInStreamRam:
+ public ISequentialInStream,
+ public CMyUnknownImp
+{
+ const Byte *Data;
+ size_t Size;
+ size_t Pos;
+public:
+ MY_UNKNOWN_IMP
+ void Init(const Byte *data, size_t size)
+ {
+ Data = data;
+ Size = size;
+ Pos = 0;
+ }
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+};
+
+STDMETHODIMP CInStreamRam::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 remain = Size - Pos;
+ if (size > remain)
+ size = remain;
+ for (UInt32 i = 0; i < size; i++)
+ ((Byte *)data)[i] = Data[Pos + i];
+ Pos += size;
+ if(processedSize != NULL)
+ *processedSize = size;
+ return S_OK;
+}
+
+class COutStreamRam:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+ size_t Size;
+public:
+ Byte *Data;
+ size_t Pos;
+ bool Overflow;
+ void Init(Byte *data, size_t size)
+ {
+ Data = data;
+ Size = size;
+ Pos = 0;
+ Overflow = false;
+ }
+ void SetPos(size_t pos)
+ {
+ Overflow = false;
+ Pos = pos;
+ }
+ MY_UNKNOWN_IMP
+ HRESULT WriteByte(Byte b)
+ {
+ if (Pos >= Size)
+ {
+ Overflow = true;
+ return E_FAIL;
+ }
+ Data[Pos++] = b;
+ return S_OK;
+ }
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+};
+
+STDMETHODIMP COutStreamRam::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 i;
+ for (i = 0; i < size && Pos < Size; i++)
+ Data[Pos++] = ((const Byte *)data)[i];
+ if(processedSize != NULL)
+ *processedSize = i;
+ if (i != size)
+ {
+ Overflow = true;
+ return E_FAIL;
+ }
+ return S_OK;
+}
+
+#define SZE_FAIL (1)
+#define SZE_OUTOFMEMORY (2)
+#define SZE_OUT_OVERFLOW (3)
+
+int LzmaRamEncode(
+ const Byte *inBuffer, size_t inSize,
+ Byte *outBuffer, size_t outSize, size_t *outSizeProcessed,
+ UInt32 dictionarySize, ESzFilterMode filterMode)
+{
+ #ifndef _NO_EXCEPTIONS
+ try {
+ #endif
+
+ *outSizeProcessed = 0;
+ const size_t kIdSize = 1;
+ const size_t kLzmaPropsSize = 5;
+ const size_t kMinDestSize = kIdSize + kLzmaPropsSize + 8;
+ if (outSize < kMinDestSize)
+ return SZE_OUT_OVERFLOW;
+ NCompress::NLZMA::CEncoder *encoderSpec = new NCompress::NLZMA::CEncoder;
+ CMyComPtr<ICompressCoder> encoder = encoderSpec;
+
+ PROPID propIDs[] =
+ {
+ NCoderPropID::kAlgorithm,
+ NCoderPropID::kDictionarySize,
+ NCoderPropID::kNumFastBytes,
+ };
+ const int kNumProps = sizeof(propIDs) / sizeof(propIDs[0]);
+ PROPVARIANT properties[kNumProps];
+ properties[0].vt = VT_UI4;
+ properties[1].vt = VT_UI4;
+ properties[2].vt = VT_UI4;
+ properties[0].ulVal = (UInt32)2;
+ properties[1].ulVal = (UInt32)dictionarySize;
+ properties[2].ulVal = (UInt32)64;
+
+ if (encoderSpec->SetCoderProperties(propIDs, properties, kNumProps) != S_OK)
+ return 1;
+
+ COutStreamRam *outStreamSpec = new COutStreamRam;
+ if (outStreamSpec == 0)
+ return SZE_OUTOFMEMORY;
+ CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
+ CInStreamRam *inStreamSpec = new CInStreamRam;
+ if (inStreamSpec == 0)
+ return SZE_OUTOFMEMORY;
+ CMyComPtr<ISequentialInStream> inStream = inStreamSpec;
+
+ outStreamSpec->Init(outBuffer, outSize);
+ if (outStreamSpec->WriteByte(0) != S_OK)
+ return SZE_OUT_OVERFLOW;
+
+ if (encoderSpec->WriteCoderProperties(outStream) != S_OK)
+ return SZE_OUT_OVERFLOW;
+ if (outStreamSpec->Pos != kIdSize + kLzmaPropsSize)
+ return 1;
+
+ int i;
+ for (i = 0; i < 8; i++)
+ {
+ UInt64 t = (UInt64)(inSize);
+ if (outStreamSpec->WriteByte((Byte)((t) >> (8 * i))) != S_OK)
+ return SZE_OUT_OVERFLOW;
+ }
+
+ Byte *filteredStream = 0;
+
+ bool useFilter = (filterMode != SZ_FILTER_NO);
+ if (useFilter)
+ {
+ if (inSize != 0)
+ {
+ filteredStream = (Byte *)MyAlloc(inSize);
+ if (filteredStream == 0)
+ return SZE_OUTOFMEMORY;
+ memmove(filteredStream, inBuffer, inSize);
+ }
+ UInt32 _prevMask;
+ UInt32 _prevPos;
+ x86_Convert_Init(_prevMask, _prevPos);
+ x86_Convert(filteredStream, (UInt32)inSize, 0, &_prevMask, &_prevPos, 1);
+ }
+
+ UInt32 minSize = 0;
+ int numPasses = (filterMode == SZ_FILTER_AUTO) ? 3 : 1;
+ bool bestIsFiltered = false;
+ int mainResult = 0;
+ size_t startPos = outStreamSpec->Pos;
+ for (i = 0; i < numPasses; i++)
+ {
+ if (numPasses > 1 && i == numPasses - 1 && !bestIsFiltered)
+ break;
+ outStreamSpec->SetPos(startPos);
+ bool curModeIsFiltered = false;
+ if (useFilter && i == 0)
+ curModeIsFiltered = true;
+ if (numPasses > 1 && i == numPasses - 1)
+ curModeIsFiltered = true;
+
+ inStreamSpec->Init(curModeIsFiltered ? filteredStream : inBuffer, inSize);
+
+ HRESULT lzmaResult = encoder->Code(inStream, outStream, 0, 0, 0);
+
+ mainResult = 0;
+ if (lzmaResult == E_OUTOFMEMORY)
+ {
+ mainResult = SZE_OUTOFMEMORY;
+ break;
+ }
+ if (i == 0 || outStreamSpec->Pos <= minSize)
+ {
+ minSize = outStreamSpec->Pos;
+ bestIsFiltered = curModeIsFiltered;
+ }
+ if (outStreamSpec->Overflow)
+ mainResult = SZE_OUT_OVERFLOW;
+ else if (lzmaResult != S_OK)
+ {
+ mainResult = SZE_FAIL;
+ break;
+ }
+ }
+ *outSizeProcessed = outStreamSpec->Pos;
+ if (bestIsFiltered)
+ outBuffer[0] = 1;
+ if (useFilter)
+ MyFree(filteredStream);
+ return mainResult;
+
+ #ifndef _NO_EXCEPTIONS
+ } catch(...) { return SZE_OUTOFMEMORY; }
+ #endif
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/LzmaRamDecode.c squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/LzmaRamDecode.c
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/LzmaRamDecode.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/LzmaRamDecode.c 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,79 @@
+/* LzmaRamDecode.c */
+
+#include "LzmaRamDecode.h"
+#ifdef _SZ_ONE_DIRECTORY
+#include "LzmaDecode.h"
+#include "BranchX86.h"
+#else
+#include "../LZMA_C/LzmaDecode.h"
+#include "../Branch/BranchX86.h"
+#endif
+
+#define LZMA_PROPS_SIZE 14
+#define LZMA_SIZE_OFFSET 6
+
+int LzmaRamGetUncompressedSize(
+ const unsigned char *inBuffer,
+ size_t inSize,
+ size_t *outSize)
+{
+ unsigned int i;
+ if (inSize < LZMA_PROPS_SIZE)
+ return 1;
+ *outSize = 0;
+ for(i = 0; i < sizeof(size_t); i++)
+ *outSize += ((size_t)inBuffer[LZMA_SIZE_OFFSET + i]) << (8 * i);
+ for(; i < 8; i++)
+ if (inBuffer[LZMA_SIZE_OFFSET + i] != 0)
+ return 1;
+ return 0;
+}
+
+#define SZE_DATA_ERROR (1)
+#define SZE_OUTOFMEMORY (2)
+
+int LzmaRamDecompress(
+ const unsigned char *inBuffer,
+ size_t inSize,
+ unsigned char *outBuffer,
+ size_t outSize,
+ size_t *outSizeProcessed,
+ void * (*allocFunc)(size_t size),
+ void (*freeFunc)(void *))
+{
+ CLzmaDecoderState state; /* it's about 24 bytes structure, if int is 32-bit */
+ int result;
+ SizeT outSizeProcessedLoc;
+ SizeT inProcessed;
+ int useFilter;
+
+ if (inSize < LZMA_PROPS_SIZE)
+ return 1;
+ useFilter = inBuffer[0];
+
+ *outSizeProcessed = 0;
+ if (useFilter > 1)
+ return 1;
+
+ if (LzmaDecodeProperties(&state.Properties, inBuffer + 1, LZMA_PROPERTIES_SIZE) != LZMA_RESULT_OK)
+ return 1;
+ state.Probs = (CProb *)allocFunc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
+ if (state.Probs == 0)
+ return SZE_OUTOFMEMORY;
+
+ result = LzmaDecode(&state,
+ inBuffer + LZMA_PROPS_SIZE, (SizeT)inSize - LZMA_PROPS_SIZE, &inProcessed,
+ outBuffer, (SizeT)outSize, &outSizeProcessedLoc);
+ freeFunc(state.Probs);
+ if (result != LZMA_RESULT_OK)
+ return 1;
+ *outSizeProcessed = (size_t)outSizeProcessedLoc;
+ if (useFilter == 1)
+ {
+ UInt32 _prevMask;
+ UInt32 _prevPos;
+ x86_Convert_Init(_prevMask, _prevPos);
+ x86_Convert(outBuffer, (UInt32)outSizeProcessedLoc, 0, &_prevMask, &_prevPos, 0);
+ }
+ return 0;
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/LzmaRamDecode.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/LzmaRamDecode.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/LzmaRamDecode.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/LzmaRamDecode.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,55 @@
+/* LzmaRamDecode.h */
+
+#ifndef __LzmaRamDecode_h
+#define __LzmaRamDecode_h
+
+#include <stdlib.h>
+
+/*
+LzmaRamGetUncompressedSize:
+ In:
+ inBuffer - input data
+ inSize - input data size
+ Out:
+ outSize - uncompressed size
+ Return code:
+ 0 - OK
+ 1 - Error in headers
+*/
+
+int LzmaRamGetUncompressedSize(
+ const unsigned char *inBuffer,
+ size_t inSize,
+ size_t *outSize);
+
+
+/*
+LzmaRamDecompress:
+ In:
+ inBuffer - input data
+ inSize - input data size
+ outBuffer - output data
+ outSize - output size
+ allocFunc - alloc function (can be malloc)
+ freeFunc - free function (can be free)
+ Out:
+ outSizeProcessed - processed size
+ Return code:
+ 0 - OK
+ 1 - Error in headers / data stream
+ 2 - Memory allocating error
+
+Memory requirements depend from properties of LZMA stream.
+With default lzma settings it's about 16 KB.
+*/
+
+int LzmaRamDecompress(
+ const unsigned char *inBuffer,
+ size_t inSize,
+ unsigned char *outBuffer,
+ size_t outSize,
+ size_t *outSizeProcessed,
+ void * (*allocFunc)(size_t size),
+ void (*freeFunc)(void *));
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/LzmaRam.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/LzmaRam.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/LzmaRam.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/LzmaRam.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,46 @@
+// LzmaRam.h
+
+#ifndef __LzmaRam_h
+#define __LzmaRam_h
+
+#include <stdlib.h>
+#include "../../../Common/Types.h"
+
+/*
+LzmaRamEncode: BCJ + LZMA RAM->RAM compressing.
+It uses .lzma format, but it writes one additional byte to .lzma file:
+ 0: - no filter
+ 1: - x86(BCJ) filter.
+
+To provide best compression ratio dictionarySize mustbe >= inSize
+
+LzmaRamEncode allocates Data with MyAlloc/BigAlloc functions.
+RAM Requirements:
+ RamSize = dictionarySize * 9.5 + 6MB + FilterBlockSize
+ FilterBlockSize = 0, if useFilter == false
+ FilterBlockSize = inSize, if useFilter == true
+
+ Return code:
+ 0 - OK
+ 1 - Unspecified Error
+ 2 - Memory allocating error
+ 3 - Output buffer OVERFLOW
+
+If you use SZ_FILTER_AUTO mode, then encoder will use 2 or 3 passes:
+ 2 passes when FILTER_NO provides better compression.
+ 3 passes when FILTER_YES provides better compression.
+*/
+
+enum ESzFilterMode
+{
+ SZ_FILTER_NO,
+ SZ_FILTER_YES,
+ SZ_FILTER_AUTO
+};
+
+int LzmaRamEncode(
+ const Byte *inBuffer, size_t inSize,
+ Byte *outBuffer, size_t outSize, size_t *outSizeProcessed,
+ UInt32 dictionarySize, ESzFilterMode filterMode);
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/makefile squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/makefile
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/makefile 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/makefile 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,100 @@
+PROG = lzma.exe
+CFLAGS = $(CFLAGS) -I ../../../
+LIBS = $(LIBS) oleaut32.lib user32.lib
+
+!IFNDEF O
+!IFDEF CPU
+O=$(CPU)
+!ELSE
+O=O
+!ENDIF
+!ENDIF
+
+CFLAGS = $(CFLAGS) -nologo -EHsc -c -Fo$O/ -GS-
+CFLAGS_O1 = $(CFLAGS) -O1
+CFLAGS_O2 = $(CFLAGS) -O2
+
+LFLAGS = $(LFLAGS) -nologo -OPT:NOWIN98
+
+PROGPATH = $O\$(PROG)
+
+COMPL_O1 = $(CPP) $(CFLAGS_O1) $**
+COMPL_O2 = $(CPP) $(CFLAGS_O2) $**
+COMPL = $(CPP) $(CFLAGS_O1) $**
+
+
+LZMA_OBJS = \
+ $O\LzmaAlone.obj \
+ $O\LzmaBench.obj \
+ $O\LzmaRam.obj \
+
+LZMA_OPT_OBJS = \
+ $O\LZMADecoder.obj \
+ $O\LZMAEncoder.obj \
+
+COMMON_OBJS = \
+ $O\Alloc.obj \
+ $O\CRC.obj \
+ $O\CommandLineParser.obj \
+ $O\String.obj \
+ $O\StringConvert.obj \
+ $O\StringToInt.obj \
+ $O\Vector.obj
+
+7ZIP_COMMON_OBJS = \
+ $O\InBuffer.obj \
+ $O\OutBuffer.obj \
+ $O\StreamUtils.obj \
+
+LZ_OBJS = \
+ $O\LZInWindow.obj \
+ $O\LZOutWindow.obj \
+
+
+OBJS = \
+ $(LZMA_OBJS) \
+ $(LZMA_OPT_OBJS) \
+ $(COMMON_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+ $(LZ_OBJS) \
+ $O\LzmaRamDecode.obj \
+ $O\LzmaDecode.obj \
+ $O\FileStreams.obj \
+ $O\FileIO.obj \
+ $O\RangeCoderBit.obj \
+ $O\BranchX86.obj \
+
+all: $(PROGPATH)
+
+clean:
+ -del /Q $(PROGPATH) $O\*.exe $O\*.dll $O\*.obj $O\*.lib $O\*.exp $O\*.res $O\*.pch
+
+$O:
+ if not exist "$O" mkdir "$O"
+
+$(PROGPATH): $O $(OBJS)
+ link $(LFLAGS) -out:$(PROGPATH) $(OBJS) $(LIBS)
+
+
+$(LZMA_OBJS): $(*B).cpp
+ $(COMPL)
+$(LZMA_OPT_OBJS): ../LZMA/$(*B).cpp
+ $(COMPL_O2)
+$(COMMON_OBJS): ../../../Common/$(*B).cpp
+ $(COMPL)
+$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
+ $(COMPL)
+$(LZ_OBJS): ../LZ/$(*B).cpp
+ $(COMPL)
+$O\RangeCoderBit.obj: ../RangeCoder/$(*B).cpp
+ $(COMPL)
+$O\LzmaRamDecode.obj: LzmaRamDecode.c
+ $(COMPL_O1)
+$O\LzmaDecode.obj: ../LZMA_C/LzmaDecode.c
+ $(COMPL_O2)
+$O\BranchX86.obj: ../Branch/BranchX86.c
+ $(COMPL_O2)
+$O\FileStreams.obj: ../../Common/FileStreams.cpp
+ $(COMPL)
+$O\FileIO.obj: ../../../Windows/FileIO.cpp
+ $(COMPL)
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/makefile.gcc squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/makefile.gcc
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/makefile.gcc 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/makefile.gcc 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,113 @@
+PROG = lzma
+CXX = g++ -O2 -Wall
+CXX_C = gcc -O2 -Wall
+LIB = -lm
+RM = rm -f
+CFLAGS = -c -I ../../../
+
+OBJS = \
+ LzmaAlone.o \
+ LzmaBench.o \
+ LzmaRam.o \
+ LzmaRamDecode.o \
+ LzmaDecode.o \
+ BranchX86.o \
+ LZMADecoder.o \
+ LZMAEncoder.o \
+ LZInWindow.o \
+ LZOutWindow.o \
+ RangeCoderBit.o \
+ InBuffer.o \
+ OutBuffer.o \
+ FileStreams.o \
+ StreamUtils.o \
+ Alloc.o \
+ C_FileIO.o \
+ CommandLineParser.o \
+ CRC.o \
+ String.o \
+ StringConvert.o \
+ StringToInt.o \
+ Vector.o \
+
+
+all: $(PROG)
+
+$(PROG): $(OBJS)
+ $(CXX) -o $(PROG) $(LDFLAGS) $(OBJS) $(LIB)
+
+LzmaAlone.o: LzmaAlone.cpp
+ $(CXX) $(CFLAGS) LzmaAlone.cpp
+
+LzmaBench.o: LzmaBench.cpp
+ $(CXX) $(CFLAGS) LzmaBench.cpp
+
+LzmaRam.o: LzmaRam.cpp
+ $(CXX) $(CFLAGS) LzmaRam.cpp
+
+LzmaRamDecode.o: LzmaRamDecode.c
+ $(CXX_C) $(CFLAGS) LzmaRamDecode.c
+
+LzmaDecode.o: ../LZMA_C/LzmaDecode.c
+ $(CXX_C) $(CFLAGS) ../LZMA_C/LzmaDecode.c
+
+BranchX86.o: ../Branch/BranchX86.c
+ $(CXX_C) $(CFLAGS) ../Branch/BranchX86.c
+
+LZMADecoder.o: ../LZMA/LZMADecoder.cpp
+ $(CXX) $(CFLAGS) ../LZMA/LZMADecoder.cpp
+
+LZMAEncoder.o: ../LZMA/LZMAEncoder.cpp
+ $(CXX) $(CFLAGS) ../LZMA/LZMAEncoder.cpp
+
+LZInWindow.o: ../LZ/LZInWindow.cpp
+ $(CXX) $(CFLAGS) ../LZ/LZInWindow.cpp
+
+LZOutWindow.o: ../LZ/LZOutWindow.cpp
+ $(CXX) $(CFLAGS) ../LZ/LZOutWindow.cpp
+
+RangeCoderBit.o: ../RangeCoder/RangeCoderBit.cpp
+ $(CXX) $(CFLAGS) ../RangeCoder/RangeCoderBit.cpp
+
+InBuffer.o: ../../Common/InBuffer.cpp
+ $(CXX) $(CFLAGS) ../../Common/InBuffer.cpp
+
+OutBuffer.o: ../../Common/OutBuffer.cpp
+ $(CXX) $(CFLAGS) ../../Common/OutBuffer.cpp
+
+FileStreams.o: ../../Common/FileStreams.cpp
+ $(CXX) $(CFLAGS) ../../Common/FileStreams.cpp
+
+StreamUtils.o: ../../Common/StreamUtils.cpp
+ $(CXX) $(CFLAGS) ../../Common/StreamUtils.cpp
+
+Alloc.o: ../../../Common/Alloc.cpp
+ $(CXX) $(CFLAGS) ../../../Common/Alloc.cpp
+
+C_FileIO.o: ../../../Common/C_FileIO.cpp
+ $(CXX) $(CFLAGS) ../../../Common/C_FileIO.cpp
+
+CommandLineParser.o: ../../../Common/CommandLineParser.cpp
+ $(CXX) $(CFLAGS) ../../../Common/CommandLineParser.cpp
+
+CRC.o: ../../../Common/CRC.cpp
+ $(CXX) $(CFLAGS) ../../../Common/CRC.cpp
+
+MyWindows.o: ../../../Common/MyWindows.cpp
+ $(CXX) $(CFLAGS) ../../../Common/MyWindows.cpp
+
+String.o: ../../../Common/String.cpp
+ $(CXX) $(CFLAGS) ../../../Common/String.cpp
+
+StringConvert.o: ../../../Common/StringConvert.cpp
+ $(CXX) $(CFLAGS) ../../../Common/StringConvert.cpp
+
+StringToInt.o: ../../../Common/StringToInt.cpp
+ $(CXX) $(CFLAGS) ../../../Common/StringToInt.cpp
+
+Vector.o: ../../../Common/Vector.cpp
+ $(CXX) $(CFLAGS) ../../../Common/Vector.cpp
+
+clean:
+ -$(RM) $(PROG) $(OBJS)
+
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/StdAfx.cpp squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/StdAfx.cpp
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/StdAfx.cpp 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/StdAfx.cpp 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/StdAfx.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/StdAfx.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/StdAfx.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Alone/StdAfx.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_C/LzmaDecode.c squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_C/LzmaDecode.c
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_C/LzmaDecode.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_C/LzmaDecode.c 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,588 @@
+/*
+ LzmaDecode.c
+ LZMA Decoder (optimized for Speed version)
+
+ LZMA SDK 4.22 Copyright (c) 1999-2005 Igor Pavlov (2005-06-10)
+ http://www.7-zip.org/
+
+ LZMA SDK is licensed under two licenses:
+ 1) GNU Lesser General Public License (GNU LGPL)
+ 2) Common Public License (CPL)
+ It means that you can select one of these two licenses and
+ follow rules of that license.
+
+ SPECIAL EXCEPTION:
+ Igor Pavlov, as the author of this Code, expressly permits you to
+ statically or dynamically link your Code (or bind by name) to the
+ interfaces of this file without subjecting your linked Code to the
+ terms of the CPL or GNU LGPL. Any modifications or additions
+ to this file, however, are subject to the LGPL or CPL terms.
+*/
+
+#include "LzmaDecode.h"
+
+#ifndef Byte
+#define Byte unsigned char
+#endif
+
+#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_INIT2 Code = 0; Range = 0xFFFFFFFF; \
+ { int i; for(i = 0; i < 5; i++) { RC_TEST; Code = (Code << 8) | RC_READ_BYTE; }}
+
+#ifdef _LZMA_IN_CB
+
+#define RC_TEST { if (Buffer == BufferLim) \
+ { SizeT size; int result = InCallback->Read(InCallback, &Buffer, &size); if (result != LZMA_RESULT_OK) return result; \
+ BufferLim = Buffer + size; if (size == 0) return LZMA_RESULT_DATA_ERROR; }}
+
+#define RC_INIT Buffer = BufferLim = 0; RC_INIT2
+
+#else
+
+#define RC_TEST { if (Buffer == BufferLim) return LZMA_RESULT_DATA_ERROR; }
+
+#define RC_INIT(buffer, bufferSize) Buffer = buffer; BufferLim = buffer + bufferSize; RC_INIT2
+
+#endif
+
+#define RC_NORMALIZE if (Range < kTopValue) { RC_TEST; Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; }
+
+#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound)
+#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits;
+#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits;
+
+#define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \
+ { UpdateBit0(p); mi <<= 1; A0; } else \
+ { UpdateBit1(p); mi = (mi + mi) + 1; A1; }
+
+#define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;)
+
+#define RangeDecoderBitTreeDecode(probs, numLevels, res) \
+ { int i = numLevels; res = 1; \
+ do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0); \
+ res -= (1 << numLevels); }
+
+
+#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 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)
+
+#if Literal != LZMA_BASE_SIZE
+StopCompilingDueBUG
+#endif
+
+int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size)
+{
+ unsigned char prop0;
+ if (size < LZMA_PROPERTIES_SIZE)
+ return LZMA_RESULT_DATA_ERROR;
+ prop0 = propsData[0];
+ if (prop0 >= (9 * 5 * 5))
+ return LZMA_RESULT_DATA_ERROR;
+ {
+ for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5));
+ for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9);
+ propsRes->lc = prop0;
+ /*
+ unsigned char remainder = (unsigned char)(prop0 / 9);
+ propsRes->lc = prop0 % 9;
+ propsRes->pb = remainder / 5;
+ propsRes->lp = remainder % 5;
+ */
+ }
+
+ #ifdef _LZMA_OUT_READ
+ {
+ int i;
+ propsRes->DictionarySize = 0;
+ for (i = 0; i < 4; i++)
+ propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8);
+ if (propsRes->DictionarySize == 0)
+ propsRes->DictionarySize = 1;
+ }
+ #endif
+ return LZMA_RESULT_OK;
+}
+
+#define kLzmaStreamWasFinishedId (-1)
+
+int LzmaDecode(CLzmaDecoderState *vs,
+ #ifdef _LZMA_IN_CB
+ ILzmaInCallback *InCallback,
+ #else
+ const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
+ #endif
+ unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed)
+{
+ CProb *p = vs->Probs;
+ SizeT nowPos = 0;
+ Byte previousByte = 0;
+ UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1;
+ UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1;
+ int lc = vs->Properties.lc;
+
+ #ifdef _LZMA_OUT_READ
+
+ UInt32 Range = vs->Range;
+ UInt32 Code = vs->Code;
+ #ifdef _LZMA_IN_CB
+ const Byte *Buffer = vs->Buffer;
+ const Byte *BufferLim = vs->BufferLim;
+ #else
+ const Byte *Buffer = inStream;
+ const Byte *BufferLim = inStream + inSize;
+ #endif
+ int state = vs->State;
+ UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3];
+ int len = vs->RemainLen;
+ UInt32 globalPos = vs->GlobalPos;
+ UInt32 distanceLimit = vs->DistanceLimit;
+
+ Byte *dictionary = vs->Dictionary;
+ UInt32 dictionarySize = vs->Properties.DictionarySize;
+ UInt32 dictionaryPos = vs->DictionaryPos;
+
+ Byte tempDictionary[4];
+
+ #ifndef _LZMA_IN_CB
+ *inSizeProcessed = 0;
+ #endif
+ *outSizeProcessed = 0;
+ if (len == kLzmaStreamWasFinishedId)
+ return LZMA_RESULT_OK;
+
+ if (dictionarySize == 0)
+ {
+ dictionary = tempDictionary;
+ dictionarySize = 1;
+ tempDictionary[0] = vs->TempDictionary[0];
+ }
+
+ if (len == kLzmaNeedInitId)
+ {
+ {
+ UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
+ UInt32 i;
+ for (i = 0; i < numProbs; i++)
+ p[i] = kBitModelTotal >> 1;
+ rep0 = rep1 = rep2 = rep3 = 1;
+ state = 0;
+ globalPos = 0;
+ distanceLimit = 0;
+ dictionaryPos = 0;
+ dictionary[dictionarySize - 1] = 0;
+ #ifdef _LZMA_IN_CB
+ RC_INIT;
+ #else
+ RC_INIT(inStream, inSize);
+ #endif
+ }
+ len = 0;
+ }
+ while(len != 0 && nowPos < outSize)
+ {
+ UInt32 pos = dictionaryPos - rep0;
+ if (pos >= dictionarySize)
+ pos += dictionarySize;
+ outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos];
+ if (++dictionaryPos == dictionarySize)
+ dictionaryPos = 0;
+ len--;
+ }
+ if (dictionaryPos == 0)
+ previousByte = dictionary[dictionarySize - 1];
+ else
+ previousByte = dictionary[dictionaryPos - 1];
+
+ #else /* if !_LZMA_OUT_READ */
+
+ int state = 0;
+ UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1;
+ int len = 0;
+ const Byte *Buffer;
+ const Byte *BufferLim;
+ UInt32 Range;
+ UInt32 Code;
+
+ #ifndef _LZMA_IN_CB
+ *inSizeProcessed = 0;
+ #endif
+ *outSizeProcessed = 0;
+
+ {
+ UInt32 i;
+ UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
+ for (i = 0; i < numProbs; i++)
+ p[i] = kBitModelTotal >> 1;
+ }
+
+ #ifdef _LZMA_IN_CB
+ RC_INIT;
+ #else
+ RC_INIT(inStream, inSize);
+ #endif
+
+ #endif /* _LZMA_OUT_READ */
+
+ while(nowPos < outSize)
+ {
+ CProb *prob;
+ UInt32 bound;
+ int posState = (int)(
+ (nowPos
+ #ifdef _LZMA_OUT_READ
+ + globalPos
+ #endif
+ )
+ & posStateMask);
+
+ prob = p + IsMatch + (state << kNumPosBitsMax) + posState;
+ IfBit0(prob)
+ {
+ int symbol = 1;
+ UpdateBit0(prob)
+ prob = p + Literal + (LZMA_LIT_SIZE *
+ (((
+ (nowPos
+ #ifdef _LZMA_OUT_READ
+ + globalPos
+ #endif
+ )
+ & literalPosMask) << lc) + (previousByte >> (8 - lc))));
+
+ if (state >= kNumLitStates)
+ {
+ int matchByte;
+ #ifdef _LZMA_OUT_READ
+ UInt32 pos = dictionaryPos - rep0;
+ if (pos >= dictionarySize)
+ pos += dictionarySize;
+ matchByte = dictionary[pos];
+ #else
+ matchByte = outStream[nowPos - rep0];
+ #endif
+ do
+ {
+ int bit;
+ CProb *probLit;
+ matchByte <<= 1;
+ bit = (matchByte & 0x100);
+ probLit = prob + 0x100 + bit + symbol;
+ RC_GET_BIT2(probLit, symbol, if (bit != 0) break, if (bit == 0) break)
+ }
+ while (symbol < 0x100);
+ }
+ while (symbol < 0x100)
+ {
+ CProb *probLit = prob + symbol;
+ RC_GET_BIT(probLit, symbol)
+ }
+ previousByte = (Byte)symbol;
+
+ outStream[nowPos++] = previousByte;
+ #ifdef _LZMA_OUT_READ
+ if (distanceLimit < dictionarySize)
+ distanceLimit++;
+
+ dictionary[dictionaryPos] = previousByte;
+ if (++dictionaryPos == dictionarySize)
+ dictionaryPos = 0;
+ #endif
+ if (state < 4) state = 0;
+ else if (state < 10) state -= 3;
+ else state -= 6;
+ }
+ else
+ {
+ UpdateBit1(prob);
+ prob = p + IsRep + state;
+ IfBit0(prob)
+ {
+ UpdateBit0(prob);
+ rep3 = rep2;
+ rep2 = rep1;
+ rep1 = rep0;
+ state = state < kNumLitStates ? 0 : 3;
+ prob = p + LenCoder;
+ }
+ else
+ {
+ UpdateBit1(prob);
+ prob = p + IsRepG0 + state;
+ IfBit0(prob)
+ {
+ UpdateBit0(prob);
+ prob = p + IsRep0Long + (state << kNumPosBitsMax) + posState;
+ IfBit0(prob)
+ {
+ #ifdef _LZMA_OUT_READ
+ UInt32 pos;
+ #endif
+ UpdateBit0(prob);
+
+ #ifdef _LZMA_OUT_READ
+ if (distanceLimit == 0)
+ #else
+ if (nowPos == 0)
+ #endif
+ return LZMA_RESULT_DATA_ERROR;
+
+ state = state < kNumLitStates ? 9 : 11;
+ #ifdef _LZMA_OUT_READ
+ pos = dictionaryPos - rep0;
+ if (pos >= dictionarySize)
+ pos += dictionarySize;
+ previousByte = dictionary[pos];
+ dictionary[dictionaryPos] = previousByte;
+ if (++dictionaryPos == dictionarySize)
+ dictionaryPos = 0;
+ #else
+ previousByte = outStream[nowPos - rep0];
+ #endif
+ outStream[nowPos++] = previousByte;
+ #ifdef _LZMA_OUT_READ
+ if (distanceLimit < dictionarySize)
+ distanceLimit++;
+ #endif
+
+ continue;
+ }
+ else
+ {
+ UpdateBit1(prob);
+ }
+ }
+ else
+ {
+ UInt32 distance;
+ UpdateBit1(prob);
+ prob = p + IsRepG1 + state;
+ IfBit0(prob)
+ {
+ UpdateBit0(prob);
+ distance = rep1;
+ }
+ else
+ {
+ UpdateBit1(prob);
+ prob = p + IsRepG2 + state;
+ IfBit0(prob)
+ {
+ UpdateBit0(prob);
+ distance = rep2;
+ }
+ else
+ {
+ UpdateBit1(prob);
+ distance = rep3;
+ rep3 = rep2;
+ }
+ rep2 = rep1;
+ }
+ rep1 = rep0;
+ rep0 = distance;
+ }
+ state = state < kNumLitStates ? 8 : 11;
+ prob = p + RepLenCoder;
+ }
+ {
+ int numBits, offset;
+ CProb *probLen = prob + LenChoice;
+ IfBit0(probLen)
+ {
+ UpdateBit0(probLen);
+ probLen = prob + LenLow + (posState << kLenNumLowBits);
+ offset = 0;
+ numBits = kLenNumLowBits;
+ }
+ else
+ {
+ UpdateBit1(probLen);
+ probLen = prob + LenChoice2;
+ IfBit0(probLen)
+ {
+ UpdateBit0(probLen);
+ probLen = prob + LenMid + (posState << kLenNumMidBits);
+ offset = kLenNumLowSymbols;
+ numBits = kLenNumMidBits;
+ }
+ else
+ {
+ UpdateBit1(probLen);
+ probLen = prob + LenHigh;
+ offset = kLenNumLowSymbols + kLenNumMidSymbols;
+ numBits = kLenNumHighBits;
+ }
+ }
+ RangeDecoderBitTreeDecode(probLen, numBits, len);
+ len += offset;
+ }
+
+ if (state < 4)
+ {
+ int posSlot;
+ state += kNumLitStates;
+ prob = p + PosSlot +
+ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
+ kNumPosSlotBits);
+ RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot);
+ if (posSlot >= kStartPosModelIndex)
+ {
+ int numDirectBits = ((posSlot >> 1) - 1);
+ rep0 = (2 | ((UInt32)posSlot & 1));
+ if (posSlot < kEndPosModelIndex)
+ {
+ rep0 <<= numDirectBits;
+ prob = p + SpecPos + rep0 - posSlot - 1;
+ }
+ else
+ {
+ numDirectBits -= kNumAlignBits;
+ do
+ {
+ RC_NORMALIZE
+ Range >>= 1;
+ rep0 <<= 1;
+ if (Code >= Range)
+ {
+ Code -= Range;
+ rep0 |= 1;
+ }
+ }
+ while (--numDirectBits != 0);
+ prob = p + Align;
+ rep0 <<= kNumAlignBits;
+ numDirectBits = kNumAlignBits;
+ }
+ {
+ int i = 1;
+ int mi = 1;
+ do
+ {
+ CProb *prob3 = prob + mi;
+ RC_GET_BIT2(prob3, mi, ; , rep0 |= i);
+ i <<= 1;
+ }
+ while(--numDirectBits != 0);
+ }
+ }
+ else
+ rep0 = posSlot;
+ if (++rep0 == (UInt32)(0))
+ {
+ /* it's for stream version */
+ len = kLzmaStreamWasFinishedId;
+ break;
+ }
+ }
+
+ len += kMatchMinLen;
+ #ifdef _LZMA_OUT_READ
+ if (rep0 > distanceLimit)
+ #else
+ if (rep0 > nowPos)
+ #endif
+ return LZMA_RESULT_DATA_ERROR;
+
+ #ifdef _LZMA_OUT_READ
+ if (dictionarySize - distanceLimit > (UInt32)len)
+ distanceLimit += len;
+ else
+ distanceLimit = dictionarySize;
+ #endif
+
+ do
+ {
+ #ifdef _LZMA_OUT_READ
+ UInt32 pos = dictionaryPos - rep0;
+ if (pos >= dictionarySize)
+ pos += dictionarySize;
+ previousByte = dictionary[pos];
+ dictionary[dictionaryPos] = previousByte;
+ if (++dictionaryPos == dictionarySize)
+ dictionaryPos = 0;
+ #else
+ previousByte = outStream[nowPos - rep0];
+ #endif
+ len--;
+ outStream[nowPos++] = previousByte;
+ }
+ while(len != 0 && nowPos < outSize);
+ }
+ }
+ RC_NORMALIZE;
+
+ #ifdef _LZMA_OUT_READ
+ vs->Range = Range;
+ vs->Code = Code;
+ vs->DictionaryPos = dictionaryPos;
+ vs->GlobalPos = globalPos + (UInt32)nowPos;
+ vs->DistanceLimit = distanceLimit;
+ vs->Reps[0] = rep0;
+ vs->Reps[1] = rep1;
+ vs->Reps[2] = rep2;
+ vs->Reps[3] = rep3;
+ vs->State = state;
+ vs->RemainLen = len;
+ vs->TempDictionary[0] = tempDictionary[0];
+ #endif
+
+ #ifdef _LZMA_IN_CB
+ vs->Buffer = Buffer;
+ vs->BufferLim = BufferLim;
+ #else
+ *inSizeProcessed = (SizeT)(Buffer - inStream);
+ #endif
+ *outSizeProcessed = nowPos;
+ return LZMA_RESULT_OK;
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_C/LzmaDecode.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_C/LzmaDecode.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_C/LzmaDecode.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_C/LzmaDecode.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,131 @@
+/*
+ LzmaDecode.h
+ LZMA Decoder interface
+
+ LZMA SDK 4.21 Copyright (c) 1999-2005 Igor Pavlov (2005-06-08)
+ http://www.7-zip.org/
+
+ LZMA SDK is licensed under two licenses:
+ 1) GNU Lesser General Public License (GNU LGPL)
+ 2) Common Public License (CPL)
+ It means that you can select one of these two licenses and
+ follow rules of that license.
+
+ SPECIAL EXCEPTION:
+ Igor Pavlov, as the author of this code, expressly permits you to
+ statically or dynamically link your code (or bind by name) to the
+ interfaces of this file without subjecting your linked code to the
+ terms of the CPL or GNU LGPL. Any modifications or additions
+ to this file, however, are subject to the LGPL or CPL terms.
+*/
+
+#ifndef __LZMADECODE_H
+#define __LZMADECODE_H
+
+/* #define _LZMA_IN_CB */
+/* Use callback for input data */
+
+/* #define _LZMA_OUT_READ */
+/* Use read function for output data */
+
+/* #define _LZMA_PROB32 */
+/* It can increase speed on some 32-bit CPUs,
+ but memory usage will be doubled in that case */
+
+/* #define _LZMA_LOC_OPT */
+/* Enable local speed optimizations inside code */
+
+/* #define _LZMA_SYSTEM_SIZE_T */
+/* Use system's size_t. You can use it to enable 64-bit sizes supporting*/
+
+#ifndef UInt32
+#ifdef _LZMA_UINT32_IS_ULONG
+#define UInt32 unsigned long
+#else
+#define UInt32 unsigned int
+#endif
+#endif
+
+#ifndef SizeT
+#ifdef _LZMA_SYSTEM_SIZE_T
+#include <stddef.h>
+#define SizeT size_t
+#else
+#define SizeT UInt32
+#endif
+#endif
+
+#ifdef _LZMA_PROB32
+#define CProb UInt32
+#else
+#define CProb unsigned short
+#endif
+
+#define LZMA_RESULT_OK 0
+#define LZMA_RESULT_DATA_ERROR 1
+
+#ifdef _LZMA_IN_CB
+typedef struct _ILzmaInCallback
+{
+ int (*Read)(void *object, const unsigned char **buffer, SizeT *bufferSize);
+} ILzmaInCallback;
+#endif
+
+#define LZMA_BASE_SIZE 1846
+#define LZMA_LIT_SIZE 768
+
+#define LZMA_PROPERTIES_SIZE 5
+
+typedef struct _CLzmaProperties
+{
+ int lc;
+ int lp;
+ int pb;
+ #ifdef _LZMA_OUT_READ
+ UInt32 DictionarySize;
+ #endif
+}CLzmaProperties;
+
+int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size);
+
+#define LzmaGetNumProbs(Properties) (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp)))
+
+#define kLzmaNeedInitId (-2)
+
+typedef struct _CLzmaDecoderState
+{
+ CLzmaProperties Properties;
+ CProb *Probs;
+
+ #ifdef _LZMA_IN_CB
+ const unsigned char *Buffer;
+ const unsigned char *BufferLim;
+ #endif
+
+ #ifdef _LZMA_OUT_READ
+ unsigned char *Dictionary;
+ UInt32 Range;
+ UInt32 Code;
+ UInt32 DictionaryPos;
+ UInt32 GlobalPos;
+ UInt32 DistanceLimit;
+ UInt32 Reps[4];
+ int State;
+ int RemainLen;
+ unsigned char TempDictionary[4];
+ #endif
+} CLzmaDecoderState;
+
+#ifdef _LZMA_OUT_READ
+#define LzmaDecoderInit(vs) { (vs)->RemainLen = kLzmaNeedInitId; }
+#endif
+
+int LzmaDecode(CLzmaDecoderState *vs,
+ #ifdef _LZMA_IN_CB
+ ILzmaInCallback *inCallback,
+ #else
+ const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
+ #endif
+ unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed);
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_C/LzmaDecodeSize.c squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_C/LzmaDecodeSize.c
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_C/LzmaDecodeSize.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_C/LzmaDecodeSize.c 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,716 @@
+/*
+ LzmaDecodeSize.c
+ LZMA Decoder (optimized for Size version)
+
+ LZMA SDK 4.27 Copyright (c) 1999-2005 Igor Pavlov (2005-08-07)
+ http://www.7-zip.org/
+
+ LZMA SDK is licensed under two licenses:
+ 1) GNU Lesser General Public License (GNU LGPL)
+ 2) Common Public License (CPL)
+ It means that you can select one of these two licenses and
+ follow rules of that license.
+
+ SPECIAL EXCEPTION:
+ Igor Pavlov, as the author of this code, expressly permits you to
+ statically or dynamically link your code (or bind by name) to the
+ interfaces of this file without subjecting your linked code to the
+ terms of the CPL or GNU LGPL. Any modifications or additions
+ to this file, however, are subject to the LGPL or CPL terms.
+*/
+
+#include "LzmaDecode.h"
+
+#ifndef Byte
+#define Byte unsigned char
+#endif
+
+#define kNumTopBits 24
+#define kTopValue ((UInt32)1 << kNumTopBits)
+
+#define kNumBitModelTotalBits 11
+#define kBitModelTotal (1 << kNumBitModelTotalBits)
+#define kNumMoveBits 5
+
+typedef struct _CRangeDecoder
+{
+ const Byte *Buffer;
+ const Byte *BufferLim;
+ UInt32 Range;
+ UInt32 Code;
+ #ifdef _LZMA_IN_CB
+ ILzmaInCallback *InCallback;
+ int Result;
+ #endif
+ int ExtraBytes;
+} CRangeDecoder;
+
+Byte RangeDecoderReadByte(CRangeDecoder *rd)
+{
+ if (rd->Buffer == rd->BufferLim)
+ {
+ #ifdef _LZMA_IN_CB
+ SizeT size;
+ rd->Result = rd->InCallback->Read(rd->InCallback, &rd->Buffer, &size);
+ rd->BufferLim = rd->Buffer + size;
+ if (size == 0)
+ #endif
+ {
+ rd->ExtraBytes = 1;
+ return 0xFF;
+ }
+ }
+ return (*rd->Buffer++);
+}
+
+/* #define ReadByte (*rd->Buffer++) */
+#define ReadByte (RangeDecoderReadByte(rd))
+
+void RangeDecoderInit(CRangeDecoder *rd
+ #ifndef _LZMA_IN_CB
+ , const Byte *stream, SizeT bufferSize
+ #endif
+ )
+{
+ int i;
+ #ifdef _LZMA_IN_CB
+ rd->Buffer = rd->BufferLim = 0;
+ #else
+ rd->Buffer = stream;
+ rd->BufferLim = stream + bufferSize;
+ #endif
+ rd->ExtraBytes = 0;
+ rd->Code = 0;
+ rd->Range = (0xFFFFFFFF);
+ for(i = 0; i < 5; i++)
+ rd->Code = (rd->Code << 8) | ReadByte;
+}
+
+#define RC_INIT_VAR UInt32 range = rd->Range; UInt32 code = rd->Code;
+#define RC_FLUSH_VAR rd->Range = range; rd->Code = code;
+#define RC_NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | ReadByte; }
+
+UInt32 RangeDecoderDecodeDirectBits(CRangeDecoder *rd, int numTotalBits)
+{
+ RC_INIT_VAR
+ UInt32 result = 0;
+ int i;
+ for (i = numTotalBits; i != 0; i--)
+ {
+ /* UInt32 t; */
+ range >>= 1;
+
+ result <<= 1;
+ if (code >= range)
+ {
+ code -= range;
+ result |= 1;
+ }
+ /*
+ t = (code - range) >> 31;
+ t &= 1;
+ code -= range & (t - 1);
+ result = (result + result) | (1 - t);
+ */
+ RC_NORMALIZE
+ }
+ RC_FLUSH_VAR
+ return result;
+}
+
+int RangeDecoderBitDecode(CProb *prob, CRangeDecoder *rd)
+{
+ UInt32 bound = (rd->Range >> kNumBitModelTotalBits) * *prob;
+ if (rd->Code < bound)
+ {
+ rd->Range = bound;
+ *prob += (kBitModelTotal - *prob) >> kNumMoveBits;
+ if (rd->Range < kTopValue)
+ {
+ rd->Code = (rd->Code << 8) | ReadByte;
+ rd->Range <<= 8;
+ }
+ return 0;
+ }
+ else
+ {
+ rd->Range -= bound;
+ rd->Code -= bound;
+ *prob -= (*prob) >> kNumMoveBits;
+ if (rd->Range < kTopValue)
+ {
+ rd->Code = (rd->Code << 8) | ReadByte;
+ rd->Range <<= 8;
+ }
+ return 1;
+ }
+}
+
+#define RC_GET_BIT2(prob, mi, A0, A1) \
+ UInt32 bound = (range >> kNumBitModelTotalBits) * *prob; \
+ if (code < bound) \
+ { A0; range = bound; *prob += (kBitModelTotal - *prob) >> kNumMoveBits; mi <<= 1; } \
+ else \
+ { A1; range -= bound; code -= bound; *prob -= (*prob) >> kNumMoveBits; mi = (mi + mi) + 1; } \
+ RC_NORMALIZE
+
+#define RC_GET_BIT(prob, mi) RC_GET_BIT2(prob, mi, ; , ;)
+
+int RangeDecoderBitTreeDecode(CProb *probs, int numLevels, CRangeDecoder *rd)
+{
+ int mi = 1;
+ int i;
+ #ifdef _LZMA_LOC_OPT
+ RC_INIT_VAR
+ #endif
+ for(i = numLevels; i != 0; i--)
+ {
+ #ifdef _LZMA_LOC_OPT
+ CProb *prob = probs + mi;
+ RC_GET_BIT(prob, mi)
+ #else
+ mi = (mi + mi) + RangeDecoderBitDecode(probs + mi, rd);
+ #endif
+ }
+ #ifdef _LZMA_LOC_OPT
+ RC_FLUSH_VAR
+ #endif
+ return mi - (1 << numLevels);
+}
+
+int RangeDecoderReverseBitTreeDecode(CProb *probs, int numLevels, CRangeDecoder *rd)
+{
+ int mi = 1;
+ int i;
+ int symbol = 0;
+ #ifdef _LZMA_LOC_OPT
+ RC_INIT_VAR
+ #endif
+ for(i = 0; i < numLevels; i++)
+ {
+ #ifdef _LZMA_LOC_OPT
+ CProb *prob = probs + mi;
+ RC_GET_BIT2(prob, mi, ; , symbol |= (1 << i))
+ #else
+ int bit = RangeDecoderBitDecode(probs + mi, rd);
+ mi = mi + mi + bit;
+ symbol |= (bit << i);
+ #endif
+ }
+ #ifdef _LZMA_LOC_OPT
+ RC_FLUSH_VAR
+ #endif
+ return symbol;
+}
+
+Byte LzmaLiteralDecode(CProb *probs, CRangeDecoder *rd)
+{
+ int symbol = 1;
+ #ifdef _LZMA_LOC_OPT
+ RC_INIT_VAR
+ #endif
+ do
+ {
+ #ifdef _LZMA_LOC_OPT
+ CProb *prob = probs + symbol;
+ RC_GET_BIT(prob, symbol)
+ #else
+ symbol = (symbol + symbol) | RangeDecoderBitDecode(probs + symbol, rd);
+ #endif
+ }
+ while (symbol < 0x100);
+ #ifdef _LZMA_LOC_OPT
+ RC_FLUSH_VAR
+ #endif
+ return symbol;
+}
+
+Byte LzmaLiteralDecodeMatch(CProb *probs, CRangeDecoder *rd, Byte matchByte)
+{
+ int symbol = 1;
+ #ifdef _LZMA_LOC_OPT
+ RC_INIT_VAR
+ #endif
+ do
+ {
+ int bit;
+ int matchBit = (matchByte >> 7) & 1;
+ matchByte <<= 1;
+ #ifdef _LZMA_LOC_OPT
+ {
+ CProb *prob = probs + 0x100 + (matchBit << 8) + symbol;
+ RC_GET_BIT2(prob, symbol, bit = 0, bit = 1)
+ }
+ #else
+ bit = RangeDecoderBitDecode(probs + 0x100 + (matchBit << 8) + symbol, rd);
+ symbol = (symbol << 1) | bit;
+ #endif
+ if (matchBit != bit)
+ {
+ while (symbol < 0x100)
+ {
+ #ifdef _LZMA_LOC_OPT
+ CProb *prob = probs + symbol;
+ RC_GET_BIT(prob, symbol)
+ #else
+ symbol = (symbol + symbol) | RangeDecoderBitDecode(probs + symbol, rd);
+ #endif
+ }
+ break;
+ }
+ }
+ while (symbol < 0x100);
+ #ifdef _LZMA_LOC_OPT
+ RC_FLUSH_VAR
+ #endif
+ return symbol;
+}
+
+#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)
+
+int LzmaLenDecode(CProb *p, CRangeDecoder *rd, int posState)
+{
+ if(RangeDecoderBitDecode(p + LenChoice, rd) == 0)
+ return RangeDecoderBitTreeDecode(p + LenLow +
+ (posState << kLenNumLowBits), kLenNumLowBits, rd);
+ if(RangeDecoderBitDecode(p + LenChoice2, rd) == 0)
+ return kLenNumLowSymbols + RangeDecoderBitTreeDecode(p + LenMid +
+ (posState << kLenNumMidBits), kLenNumMidBits, rd);
+ return kLenNumLowSymbols + kLenNumMidSymbols +
+ RangeDecoderBitTreeDecode(p + LenHigh, kLenNumHighBits, rd);
+}
+
+#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 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)
+
+#if Literal != LZMA_BASE_SIZE
+StopCompilingDueBUG
+#endif
+
+int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size)
+{
+ unsigned char prop0;
+ if (size < LZMA_PROPERTIES_SIZE)
+ return LZMA_RESULT_DATA_ERROR;
+ prop0 = propsData[0];
+ if (prop0 >= (9 * 5 * 5))
+ return LZMA_RESULT_DATA_ERROR;
+ {
+ for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5));
+ for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9);
+ propsRes->lc = prop0;
+ /*
+ unsigned char remainder = (unsigned char)(prop0 / 9);
+ propsRes->lc = prop0 % 9;
+ propsRes->pb = remainder / 5;
+ propsRes->lp = remainder % 5;
+ */
+ }
+
+ #ifdef _LZMA_OUT_READ
+ {
+ int i;
+ propsRes->DictionarySize = 0;
+ for (i = 0; i < 4; i++)
+ propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8);
+ if (propsRes->DictionarySize == 0)
+ propsRes->DictionarySize = 1;
+ }
+ #endif
+ return LZMA_RESULT_OK;
+}
+
+#define kLzmaStreamWasFinishedId (-1)
+
+int LzmaDecode(CLzmaDecoderState *vs,
+ #ifdef _LZMA_IN_CB
+ ILzmaInCallback *InCallback,
+ #else
+ const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
+ #endif
+ unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed)
+{
+ CProb *p = vs->Probs;
+ SizeT nowPos = 0;
+ Byte previousByte = 0;
+ UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1;
+ UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1;
+ int lc = vs->Properties.lc;
+ CRangeDecoder rd;
+
+ #ifdef _LZMA_OUT_READ
+
+ int state = vs->State;
+ UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3];
+ int len = vs->RemainLen;
+ UInt32 globalPos = vs->GlobalPos;
+ UInt32 distanceLimit = vs->DistanceLimit;
+
+ Byte *dictionary = vs->Dictionary;
+ UInt32 dictionarySize = vs->Properties.DictionarySize;
+ UInt32 dictionaryPos = vs->DictionaryPos;
+
+ Byte tempDictionary[4];
+
+ rd.Range = vs->Range;
+ rd.Code = vs->Code;
+ #ifdef _LZMA_IN_CB
+ rd.InCallback = InCallback;
+ rd.Buffer = vs->Buffer;
+ rd.BufferLim = vs->BufferLim;
+ #else
+ rd.Buffer = inStream;
+ rd.BufferLim = inStream + inSize;
+ #endif
+
+ #ifndef _LZMA_IN_CB
+ *inSizeProcessed = 0;
+ #endif
+ *outSizeProcessed = 0;
+ if (len == kLzmaStreamWasFinishedId)
+ return LZMA_RESULT_OK;
+
+ if (dictionarySize == 0)
+ {
+ dictionary = tempDictionary;
+ dictionarySize = 1;
+ tempDictionary[0] = vs->TempDictionary[0];
+ }
+
+ if (len == kLzmaNeedInitId)
+ {
+ {
+ UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
+ UInt32 i;
+ for (i = 0; i < numProbs; i++)
+ p[i] = kBitModelTotal >> 1;
+ rep0 = rep1 = rep2 = rep3 = 1;
+ state = 0;
+ globalPos = 0;
+ distanceLimit = 0;
+ dictionaryPos = 0;
+ dictionary[dictionarySize - 1] = 0;
+ RangeDecoderInit(&rd
+ #ifndef _LZMA_IN_CB
+ , inStream, inSize
+ #endif
+ );
+ #ifdef _LZMA_IN_CB
+ if (rd.Result != LZMA_RESULT_OK)
+ return rd.Result;
+ #endif
+ if (rd.ExtraBytes != 0)
+ return LZMA_RESULT_DATA_ERROR;
+ }
+ len = 0;
+ }
+ while(len != 0 && nowPos < outSize)
+ {
+ UInt32 pos = dictionaryPos - rep0;
+ if (pos >= dictionarySize)
+ pos += dictionarySize;
+ outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos];
+ if (++dictionaryPos == dictionarySize)
+ dictionaryPos = 0;
+ len--;
+ }
+ if (dictionaryPos == 0)
+ previousByte = dictionary[dictionarySize - 1];
+ else
+ previousByte = dictionary[dictionaryPos - 1];
+
+ #ifdef _LZMA_IN_CB
+ rd.Result = LZMA_RESULT_OK;
+ #endif
+ rd.ExtraBytes = 0;
+
+ #else /* if !_LZMA_OUT_READ */
+
+ int state = 0;
+ UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1;
+ int len = 0;
+
+ #ifndef _LZMA_IN_CB
+ *inSizeProcessed = 0;
+ #endif
+ *outSizeProcessed = 0;
+
+ {
+ UInt32 i;
+ UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
+ for (i = 0; i < numProbs; i++)
+ p[i] = kBitModelTotal >> 1;
+ }
+
+ #ifdef _LZMA_IN_CB
+ rd.InCallback = InCallback;
+ #endif
+ RangeDecoderInit(&rd
+ #ifndef _LZMA_IN_CB
+ , inStream, inSize
+ #endif
+ );
+
+ #ifdef _LZMA_IN_CB
+ if (rd.Result != LZMA_RESULT_OK)
+ return rd.Result;
+ #endif
+ if (rd.ExtraBytes != 0)
+ return LZMA_RESULT_DATA_ERROR;
+
+ #endif /* _LZMA_OUT_READ */
+
+
+ while(nowPos < outSize)
+ {
+ int posState = (int)(
+ (nowPos
+ #ifdef _LZMA_OUT_READ
+ + globalPos
+ #endif
+ )
+ & posStateMask);
+ #ifdef _LZMA_IN_CB
+ if (rd.Result != LZMA_RESULT_OK)
+ return rd.Result;
+ #endif
+ if (rd.ExtraBytes != 0)
+ return LZMA_RESULT_DATA_ERROR;
+ if (RangeDecoderBitDecode(p + IsMatch + (state << kNumPosBitsMax) + posState, &rd) == 0)
+ {
+ CProb *probs = p + Literal + (LZMA_LIT_SIZE *
+ (((
+ (nowPos
+ #ifdef _LZMA_OUT_READ
+ + globalPos
+ #endif
+ )
+ & literalPosMask) << lc) + (previousByte >> (8 - lc))));
+
+ if (state >= kNumLitStates)
+ {
+ Byte matchByte;
+ #ifdef _LZMA_OUT_READ
+ UInt32 pos = dictionaryPos - rep0;
+ if (pos >= dictionarySize)
+ pos += dictionarySize;
+ matchByte = dictionary[pos];
+ #else
+ matchByte = outStream[nowPos - rep0];
+ #endif
+ previousByte = LzmaLiteralDecodeMatch(probs, &rd, matchByte);
+ }
+ else
+ previousByte = LzmaLiteralDecode(probs, &rd);
+ outStream[nowPos++] = previousByte;
+ #ifdef _LZMA_OUT_READ
+ if (distanceLimit < dictionarySize)
+ distanceLimit++;
+
+ dictionary[dictionaryPos] = previousByte;
+ if (++dictionaryPos == dictionarySize)
+ dictionaryPos = 0;
+ #endif
+ if (state < 4) state = 0;
+ else if (state < 10) state -= 3;
+ else state -= 6;
+ }
+ else
+ {
+ if (RangeDecoderBitDecode(p + IsRep + state, &rd) == 1)
+ {
+ if (RangeDecoderBitDecode(p + IsRepG0 + state, &rd) == 0)
+ {
+ if (RangeDecoderBitDecode(p + IsRep0Long + (state << kNumPosBitsMax) + posState, &rd) == 0)
+ {
+ #ifdef _LZMA_OUT_READ
+ UInt32 pos;
+ #endif
+
+ #ifdef _LZMA_OUT_READ
+ if (distanceLimit == 0)
+ #else
+ if (nowPos == 0)
+ #endif
+ return LZMA_RESULT_DATA_ERROR;
+
+ state = state < 7 ? 9 : 11;
+ #ifdef _LZMA_OUT_READ
+ pos = dictionaryPos - rep0;
+ if (pos >= dictionarySize)
+ pos += dictionarySize;
+ previousByte = dictionary[pos];
+ dictionary[dictionaryPos] = previousByte;
+ if (++dictionaryPos == dictionarySize)
+ dictionaryPos = 0;
+ #else
+ previousByte = outStream[nowPos - rep0];
+ #endif
+ outStream[nowPos++] = previousByte;
+
+ #ifdef _LZMA_OUT_READ
+ if (distanceLimit < dictionarySize)
+ distanceLimit++;
+ #endif
+ continue;
+ }
+ }
+ else
+ {
+ UInt32 distance;
+ if(RangeDecoderBitDecode(p + IsRepG1 + state, &rd) == 0)
+ distance = rep1;
+ else
+ {
+ if(RangeDecoderBitDecode(p + IsRepG2 + state, &rd) == 0)
+ distance = rep2;
+ else
+ {
+ distance = rep3;
+ rep3 = rep2;
+ }
+ rep2 = rep1;
+ }
+ rep1 = rep0;
+ rep0 = distance;
+ }
+ len = LzmaLenDecode(p + RepLenCoder, &rd, posState);
+ state = state < 7 ? 8 : 11;
+ }
+ else
+ {
+ int posSlot;
+ rep3 = rep2;
+ rep2 = rep1;
+ rep1 = rep0;
+ state = state < 7 ? 7 : 10;
+ len = LzmaLenDecode(p + LenCoder, &rd, posState);
+ posSlot = RangeDecoderBitTreeDecode(p + PosSlot +
+ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
+ kNumPosSlotBits), kNumPosSlotBits, &rd);
+ if (posSlot >= kStartPosModelIndex)
+ {
+ int numDirectBits = ((posSlot >> 1) - 1);
+ rep0 = ((2 | ((UInt32)posSlot & 1)) << numDirectBits);
+ if (posSlot < kEndPosModelIndex)
+ {
+ rep0 += RangeDecoderReverseBitTreeDecode(
+ p + SpecPos + rep0 - posSlot - 1, numDirectBits, &rd);
+ }
+ else
+ {
+ rep0 += RangeDecoderDecodeDirectBits(&rd,
+ numDirectBits - kNumAlignBits) << kNumAlignBits;
+ rep0 += RangeDecoderReverseBitTreeDecode(p + Align, kNumAlignBits, &rd);
+ }
+ }
+ else
+ rep0 = posSlot;
+ if (++rep0 == (UInt32)(0))
+ {
+ /* it's for stream version */
+ len = kLzmaStreamWasFinishedId;
+ break;
+ }
+ }
+
+ len += kMatchMinLen;
+ #ifdef _LZMA_OUT_READ
+ if (rep0 > distanceLimit)
+ #else
+ if (rep0 > nowPos)
+ #endif
+ return LZMA_RESULT_DATA_ERROR;
+
+ #ifdef _LZMA_OUT_READ
+ if (dictionarySize - distanceLimit > (UInt32)len)
+ distanceLimit += len;
+ else
+ distanceLimit = dictionarySize;
+ #endif
+
+ do
+ {
+ #ifdef _LZMA_OUT_READ
+ UInt32 pos = dictionaryPos - rep0;
+ if (pos >= dictionarySize)
+ pos += dictionarySize;
+ previousByte = dictionary[pos];
+ dictionary[dictionaryPos] = previousByte;
+ if (++dictionaryPos == dictionarySize)
+ dictionaryPos = 0;
+ #else
+ previousByte = outStream[nowPos - rep0];
+ #endif
+ len--;
+ outStream[nowPos++] = previousByte;
+ }
+ while(len != 0 && nowPos < outSize);
+ }
+ }
+
+
+ #ifdef _LZMA_OUT_READ
+ vs->Range = rd.Range;
+ vs->Code = rd.Code;
+ vs->DictionaryPos = dictionaryPos;
+ vs->GlobalPos = globalPos + (UInt32)nowPos;
+ vs->DistanceLimit = distanceLimit;
+ vs->Reps[0] = rep0;
+ vs->Reps[1] = rep1;
+ vs->Reps[2] = rep2;
+ vs->Reps[3] = rep3;
+ vs->State = state;
+ vs->RemainLen = len;
+ vs->TempDictionary[0] = tempDictionary[0];
+ #endif
+
+ #ifdef _LZMA_IN_CB
+ vs->Buffer = rd.Buffer;
+ vs->BufferLim = rd.BufferLim;
+ #else
+ *inSizeProcessed = (SizeT)(rd.Buffer - inStream);
+ #endif
+ *outSizeProcessed = nowPos;
+ return LZMA_RESULT_OK;
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_C/LzmaStateDecode.c squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_C/LzmaStateDecode.c
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_C/LzmaStateDecode.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_C/LzmaStateDecode.c 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,521 @@
+/*
+ LzmaStateDecode.c
+ LZMA Decoder (State version)
+
+ LZMA SDK 4.21 Copyright (c) 1999-2005 Igor Pavlov (2005-06-08)
+ http://www.7-zip.org/
+
+ LZMA SDK is licensed under two licenses:
+ 1) GNU Lesser General Public License (GNU LGPL)
+ 2) Common Public License (CPL)
+ It means that you can select one of these two licenses and
+ follow rules of that license.
+
+ SPECIAL EXCEPTION:
+ Igor Pavlov, as the author of this Code, expressly permits you to
+ statically or dynamically link your Code (or bind by name) to the
+ interfaces of this file without subjecting your linked Code to the
+ terms of the CPL or GNU LGPL. Any modifications or additions
+ to this file, however, are subject to the LGPL or CPL terms.
+*/
+
+#include "LzmaStateDecode.h"
+
+#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_INIT Code = 0; Range = 0xFFFFFFFF; \
+ { int i; for(i = 0; i < 5; i++) { Code = (Code << 8) | RC_READ_BYTE; }}
+
+#define RC_NORMALIZE if (Range < kTopValue) { Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; }
+
+#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound)
+#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits;
+#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits;
+
+#define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \
+ { UpdateBit0(p); mi <<= 1; A0; } else \
+ { UpdateBit1(p); mi = (mi + mi) + 1; A1; }
+
+#define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;)
+
+#define RangeDecoderBitTreeDecode(probs, numLevels, res) \
+ { int i = numLevels; res = 1; \
+ do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0); \
+ res -= (1 << numLevels); }
+
+
+#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 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)
+
+#if Literal != LZMA_BASE_SIZE
+StopCompilingDueBUG
+#endif
+
+/* kRequiredInBufferSize = number of required input bytes for worst case:
+ longest match with longest distance.
+ kLzmaInBufferSize must be larger than kRequiredInBufferSize
+ 23 bits = 2 (match select) + 10 (len) + 6 (distance) + 4(align) + 1 (RC_NORMALIZE)
+*/
+
+#define kRequiredInBufferSize ((23 * (kNumBitModelTotalBits - kNumMoveBits + 1) + 26 + 9) / 8)
+
+#define kLzmaStreamWasFinishedId (-1)
+
+int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size)
+{
+ unsigned char prop0;
+ if (size < LZMA_PROPERTIES_SIZE)
+ return LZMA_RESULT_DATA_ERROR;
+ prop0 = propsData[0];
+ if (prop0 >= (9 * 5 * 5))
+ return LZMA_RESULT_DATA_ERROR;
+ {
+ for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5));
+ for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9);
+ propsRes->lc = prop0;
+ /*
+ unsigned char remainder = (unsigned char)(prop0 / 9);
+ propsRes->lc = prop0 % 9;
+ propsRes->pb = remainder / 5;
+ propsRes->lp = remainder % 5;
+ */
+ }
+
+ {
+ int i;
+ propsRes->DictionarySize = 0;
+ for (i = 0; i < 4; i++)
+ propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8);
+ if (propsRes->DictionarySize == 0)
+ propsRes->DictionarySize = 1;
+ return LZMA_RESULT_OK;
+ }
+}
+
+int LzmaDecode(
+ CLzmaDecoderState *vs,
+ const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
+ unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed,
+ int finishDecoding)
+{
+ UInt32 Range = vs->Range;
+ UInt32 Code = vs->Code;
+
+ unsigned char *Buffer = vs->Buffer;
+ int BufferSize = vs->BufferSize; /* don't change it to unsigned int */
+ CProb *p = vs->Probs;
+
+ int state = vs->State;
+ unsigned char previousByte;
+ UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3];
+ SizeT nowPos = 0;
+ UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1;
+ UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1;
+ int lc = vs->Properties.lc;
+ int len = vs->RemainLen;
+ UInt32 globalPos = vs->GlobalPos;
+ UInt32 distanceLimit = vs->DistanceLimit;
+
+ unsigned char *dictionary = vs->Dictionary;
+ UInt32 dictionarySize = vs->Properties.DictionarySize;
+ UInt32 dictionaryPos = vs->DictionaryPos;
+
+ unsigned char tempDictionary[4];
+
+ (*inSizeProcessed) = 0;
+ (*outSizeProcessed) = 0;
+ if (len == kLzmaStreamWasFinishedId)
+ return LZMA_RESULT_OK;
+
+ if (dictionarySize == 0)
+ {
+ dictionary = tempDictionary;
+ dictionarySize = 1;
+ tempDictionary[0] = vs->TempDictionary[0];
+ }
+
+ if (len == kLzmaNeedInitId)
+ {
+ while (inSize > 0 && BufferSize < kLzmaInBufferSize)
+ {
+ Buffer[BufferSize++] = *inStream++;
+ (*inSizeProcessed)++;
+ inSize--;
+ }
+ if (BufferSize < 5)
+ {
+ vs->BufferSize = BufferSize;
+ return finishDecoding ? LZMA_RESULT_DATA_ERROR : LZMA_RESULT_OK;
+ }
+ {
+ UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
+ UInt32 i;
+ for (i = 0; i < numProbs; i++)
+ p[i] = kBitModelTotal >> 1;
+ rep0 = rep1 = rep2 = rep3 = 1;
+ state = 0;
+ globalPos = 0;
+ distanceLimit = 0;
+ dictionaryPos = 0;
+ dictionary[dictionarySize - 1] = 0;
+ RC_INIT;
+ }
+ len = 0;
+ }
+ while(len != 0 && nowPos < outSize)
+ {
+ UInt32 pos = dictionaryPos - rep0;
+ if (pos >= dictionarySize)
+ pos += dictionarySize;
+ outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos];
+ if (++dictionaryPos == dictionarySize)
+ dictionaryPos = 0;
+ len--;
+ }
+ if (dictionaryPos == 0)
+ previousByte = dictionary[dictionarySize - 1];
+ else
+ previousByte = dictionary[dictionaryPos - 1];
+
+ while(1)
+ {
+ int bufferPos = (int)(Buffer - vs->Buffer);
+ if (BufferSize - bufferPos < kRequiredInBufferSize)
+ {
+ int i;
+ BufferSize -= bufferPos;
+ if (BufferSize < 0)
+ return LZMA_RESULT_DATA_ERROR;
+ for (i = 0; i < BufferSize; i++)
+ vs->Buffer[i] = Buffer[i];
+ Buffer = vs->Buffer;
+ while (inSize > 0 && BufferSize < kLzmaInBufferSize)
+ {
+ Buffer[BufferSize++] = *inStream++;
+ (*inSizeProcessed)++;
+ inSize--;
+ }
+ if (BufferSize < kRequiredInBufferSize && !finishDecoding)
+ break;
+ }
+ if (nowPos >= outSize)
+ break;
+ {
+ CProb *prob;
+ UInt32 bound;
+ int posState = (int)((nowPos + globalPos) & posStateMask);
+
+ prob = p + IsMatch + (state << kNumPosBitsMax) + posState;
+ IfBit0(prob)
+ {
+ int symbol = 1;
+ UpdateBit0(prob)
+ prob = p + Literal + (LZMA_LIT_SIZE *
+ ((((nowPos + globalPos)& literalPosMask) << lc) + (previousByte >> (8 - lc))));
+
+ if (state >= kNumLitStates)
+ {
+ int matchByte;
+ UInt32 pos = dictionaryPos - rep0;
+ if (pos >= dictionarySize)
+ pos += dictionarySize;
+ matchByte = dictionary[pos];
+ do
+ {
+ int bit;
+ CProb *probLit;
+ matchByte <<= 1;
+ bit = (matchByte & 0x100);
+ probLit = prob + 0x100 + bit + symbol;
+ RC_GET_BIT2(probLit, symbol, if (bit != 0) break, if (bit == 0) break)
+ }
+ while (symbol < 0x100);
+ }
+ while (symbol < 0x100)
+ {
+ CProb *probLit = prob + symbol;
+ RC_GET_BIT(probLit, symbol)
+ }
+ previousByte = (unsigned char)symbol;
+
+ outStream[nowPos++] = previousByte;
+ if (distanceLimit < dictionarySize)
+ distanceLimit++;
+
+ dictionary[dictionaryPos] = previousByte;
+ if (++dictionaryPos == dictionarySize)
+ dictionaryPos = 0;
+ if (state < 4) state = 0;
+ else if (state < 10) state -= 3;
+ else state -= 6;
+ }
+ else
+ {
+ UpdateBit1(prob);
+ prob = p + IsRep + state;
+ IfBit0(prob)
+ {
+ UpdateBit0(prob);
+ rep3 = rep2;
+ rep2 = rep1;
+ rep1 = rep0;
+ state = state < kNumLitStates ? 0 : 3;
+ prob = p + LenCoder;
+ }
+ else
+ {
+ UpdateBit1(prob);
+ prob = p + IsRepG0 + state;
+ IfBit0(prob)
+ {
+ UpdateBit0(prob);
+ prob = p + IsRep0Long + (state << kNumPosBitsMax) + posState;
+ IfBit0(prob)
+ {
+ UInt32 pos;
+ UpdateBit0(prob);
+ if (distanceLimit == 0)
+ return LZMA_RESULT_DATA_ERROR;
+ if (distanceLimit < dictionarySize)
+ distanceLimit++;
+ state = state < kNumLitStates ? 9 : 11;
+ pos = dictionaryPos - rep0;
+ if (pos >= dictionarySize)
+ pos += dictionarySize;
+ previousByte = dictionary[pos];
+ dictionary[dictionaryPos] = previousByte;
+ if (++dictionaryPos == dictionarySize)
+ dictionaryPos = 0;
+ outStream[nowPos++] = previousByte;
+ continue;
+ }
+ else
+ {
+ UpdateBit1(prob);
+ }
+ }
+ else
+ {
+ UInt32 distance;
+ UpdateBit1(prob);
+ prob = p + IsRepG1 + state;
+ IfBit0(prob)
+ {
+ UpdateBit0(prob);
+ distance = rep1;
+ }
+ else
+ {
+ UpdateBit1(prob);
+ prob = p + IsRepG2 + state;
+ IfBit0(prob)
+ {
+ UpdateBit0(prob);
+ distance = rep2;
+ }
+ else
+ {
+ UpdateBit1(prob);
+ distance = rep3;
+ rep3 = rep2;
+ }
+ rep2 = rep1;
+ }
+ rep1 = rep0;
+ rep0 = distance;
+ }
+ state = state < kNumLitStates ? 8 : 11;
+ prob = p + RepLenCoder;
+ }
+ {
+ int numBits, offset;
+ CProb *probLen = prob + LenChoice;
+ IfBit0(probLen)
+ {
+ UpdateBit0(probLen);
+ probLen = prob + LenLow + (posState << kLenNumLowBits);
+ offset = 0;
+ numBits = kLenNumLowBits;
+ }
+ else
+ {
+ UpdateBit1(probLen);
+ probLen = prob + LenChoice2;
+ IfBit0(probLen)
+ {
+ UpdateBit0(probLen);
+ probLen = prob + LenMid + (posState << kLenNumMidBits);
+ offset = kLenNumLowSymbols;
+ numBits = kLenNumMidBits;
+ }
+ else
+ {
+ UpdateBit1(probLen);
+ probLen = prob + LenHigh;
+ offset = kLenNumLowSymbols + kLenNumMidSymbols;
+ numBits = kLenNumHighBits;
+ }
+ }
+ RangeDecoderBitTreeDecode(probLen, numBits, len);
+ len += offset;
+ }
+
+ if (state < 4)
+ {
+ int posSlot;
+ state += kNumLitStates;
+ prob = p + PosSlot +
+ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
+ kNumPosSlotBits);
+ RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot);
+ if (posSlot >= kStartPosModelIndex)
+ {
+ int numDirectBits = ((posSlot >> 1) - 1);
+ rep0 = (2 | ((UInt32)posSlot & 1));
+ if (posSlot < kEndPosModelIndex)
+ {
+ rep0 <<= numDirectBits;
+ prob = p + SpecPos + rep0 - posSlot - 1;
+ }
+ else
+ {
+ numDirectBits -= kNumAlignBits;
+ do
+ {
+ RC_NORMALIZE
+ Range >>= 1;
+ rep0 <<= 1;
+ if (Code >= Range)
+ {
+ Code -= Range;
+ rep0 |= 1;
+ }
+ }
+ while (--numDirectBits != 0);
+ prob = p + Align;
+ rep0 <<= kNumAlignBits;
+ numDirectBits = kNumAlignBits;
+ }
+ {
+ int i = 1;
+ int mi = 1;
+ do
+ {
+ CProb *prob3 = prob + mi;
+ RC_GET_BIT2(prob3, mi, ; , rep0 |= i);
+ i <<= 1;
+ }
+ while(--numDirectBits != 0);
+ }
+ }
+ else
+ rep0 = posSlot;
+ if (++rep0 == (UInt32)(0))
+ {
+ /* it's for stream version */
+ len = kLzmaStreamWasFinishedId;
+ break;
+ }
+ }
+
+ len += kMatchMinLen;
+ if (rep0 > distanceLimit)
+ return LZMA_RESULT_DATA_ERROR;
+ if (dictionarySize - distanceLimit > (UInt32)len)
+ distanceLimit += len;
+ else
+ distanceLimit = dictionarySize;
+
+ do
+ {
+ UInt32 pos = dictionaryPos - rep0;
+ if (pos >= dictionarySize)
+ pos += dictionarySize;
+ previousByte = dictionary[pos];
+ dictionary[dictionaryPos] = previousByte;
+ if (++dictionaryPos == dictionarySize)
+ dictionaryPos = 0;
+ len--;
+ outStream[nowPos++] = previousByte;
+ }
+ while(len != 0 && nowPos < outSize);
+ }
+ }
+ }
+ RC_NORMALIZE;
+
+ BufferSize -= (int)(Buffer - vs->Buffer);
+ if (BufferSize < 0)
+ return LZMA_RESULT_DATA_ERROR;
+ {
+ int i;
+ for (i = 0; i < BufferSize; i++)
+ vs->Buffer[i] = Buffer[i];
+ }
+ vs->BufferSize = BufferSize;
+ vs->Range = Range;
+ vs->Code = Code;
+ vs->DictionaryPos = dictionaryPos;
+ vs->GlobalPos = (UInt32)(globalPos + nowPos);
+ vs->DistanceLimit = distanceLimit;
+ vs->Reps[0] = rep0;
+ vs->Reps[1] = rep1;
+ vs->Reps[2] = rep2;
+ vs->Reps[3] = rep3;
+ vs->State = state;
+ vs->RemainLen = len;
+ vs->TempDictionary[0] = tempDictionary[0];
+
+ (*outSizeProcessed) = nowPos;
+ return LZMA_RESULT_OK;
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_C/LzmaStateDecode.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_C/LzmaStateDecode.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_C/LzmaStateDecode.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_C/LzmaStateDecode.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,115 @@
+/*
+ LzmaStateDecode.h
+ LZMA Decoder interface (State version)
+
+ LZMA SDK 4.21 Copyright (c) 1999-2005 Igor Pavlov (2005-06-08)
+ http://www.7-zip.org/
+
+ LZMA SDK is licensed under two licenses:
+ 1) GNU Lesser General Public License (GNU LGPL)
+ 2) Common Public License (CPL)
+ It means that you can select one of these two licenses and
+ follow rules of that license.
+
+ SPECIAL EXCEPTION:
+ Igor Pavlov, as the author of this code, expressly permits you to
+ statically or dynamically link your code (or bind by name) to the
+ interfaces of this file without subjecting your linked code to the
+ terms of the CPL or GNU LGPL. Any modifications or additions
+ to this file, however, are subject to the LGPL or CPL terms.
+*/
+
+#ifndef __LZMASTATEDECODE_H
+#define __LZMASTATEDECODE_H
+
+/* #define _LZMA_PROB32 */
+/* It can increase speed on some 32-bit CPUs,
+ but memory usage will be doubled in that case */
+
+/* #define _LZMA_SYSTEM_SIZE_T */
+/* Use system's size_t. You can use it to enable 64-bit sizes supporting*/
+
+
+#ifndef UInt32
+#ifdef _LZMA_UINT32_IS_ULONG
+#define UInt32 unsigned long
+#else
+#define UInt32 unsigned int
+#endif
+#endif
+
+#ifndef SizeT
+#ifdef _LZMA_SYSTEM_SIZE_T
+#include <stddef.h>
+#define SizeT size_t
+#else
+#define SizeT UInt32
+#endif
+#endif
+
+#ifdef _LZMA_PROB32
+#define CProb UInt32
+#else
+#define CProb unsigned short
+#endif
+
+#define LZMA_RESULT_OK 0
+#define LZMA_RESULT_DATA_ERROR 1
+
+#define LZMA_BASE_SIZE 1846
+#define LZMA_LIT_SIZE 768
+
+#define LZMA_PROPERTIES_SIZE 5
+
+typedef struct _CLzmaProperties
+{
+ int lc;
+ int lp;
+ int pb;
+ UInt32 DictionarySize;
+}CLzmaProperties;
+
+int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size);
+
+#define LzmaGetNumProbs(lzmaProps) (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((lzmaProps)->lc + (lzmaProps)->lp)))
+
+#define kLzmaInBufferSize 64 /* don't change it. it must be larger than kRequiredInBufferSize */
+
+#define kLzmaNeedInitId (-2)
+
+typedef struct _CLzmaDecoderState
+{
+ CLzmaProperties Properties;
+ CProb *Probs;
+ unsigned char *Dictionary;
+
+ unsigned char Buffer[kLzmaInBufferSize];
+ int BufferSize;
+
+ UInt32 Range;
+ UInt32 Code;
+ UInt32 DictionaryPos;
+ UInt32 GlobalPos;
+ UInt32 DistanceLimit;
+ UInt32 Reps[4];
+ int State;
+ int RemainLen; /* -2: decoder needs internal initialization
+ -1: stream was finished,
+ 0: ok
+ > 0: need to write RemainLen bytes as match Reps[0],
+ */
+ unsigned char TempDictionary[4]; /* it's required when DictionarySize = 0 */
+} CLzmaDecoderState;
+
+#define LzmaDecoderInit(vs) { (vs)->RemainLen = kLzmaNeedInitId; (vs)->BufferSize = 0; }
+
+/* LzmaDecode: decoding from input stream to output stream.
+ If finishDecoding != 0, then there are no more bytes in input stream
+ after inStream[inSize - 1]. */
+
+int LzmaDecode(CLzmaDecoderState *vs,
+ const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
+ unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed,
+ int finishDecoding);
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_C/LzmaStateTest.c squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_C/LzmaStateTest.c
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_C/LzmaStateTest.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_C/LzmaStateTest.c 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,195 @@
+/*
+LzmaStateTest.c
+Test application for LZMA Decoder (State version)
+
+This file written and distributed to public domain by Igor Pavlov.
+This file is part of LZMA SDK 4.26 (2005-08-02)
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "LzmaStateDecode.h"
+
+const char *kCantReadMessage = "Can not read input file";
+const char *kCantWriteMessage = "Can not write output file";
+const char *kCantAllocateMessage = "Can not allocate memory";
+
+#define kInBufferSize (1 << 15)
+#define kOutBufferSize (1 << 15)
+
+unsigned char g_InBuffer[kInBufferSize];
+unsigned char g_OutBuffer[kOutBufferSize];
+
+size_t MyReadFile(FILE *file, void *data, size_t size)
+ { return fread(data, 1, size, file); }
+
+int MyReadFileAndCheck(FILE *file, void *data, size_t size)
+ { return (MyReadFile(file, data, size) == size); }
+
+int PrintError(char *buffer, const char *message)
+{
+ sprintf(buffer + strlen(buffer), "\nError: ");
+ sprintf(buffer + strlen(buffer), message);
+ return 1;
+}
+
+int main3(FILE *inFile, FILE *outFile, char *rs)
+{
+ /* We use two 32-bit integers to construct 64-bit integer for file size.
+ You can remove outSizeHigh, if you don't need >= 4GB supporting,
+ or you can use UInt64 outSize, if your compiler supports 64-bit integers*/
+ UInt32 outSize = 0;
+ UInt32 outSizeHigh = 0;
+
+ int waitEOS = 1;
+ /* waitEOS = 1, if there is no uncompressed size in headers,
+ so decoder will wait EOS (End of Stream Marker) in compressed stream */
+
+ int i;
+ int res = 0;
+ CLzmaDecoderState state; /* it's about 140 bytes structure, if int is 32-bit */
+ unsigned char properties[LZMA_PROPERTIES_SIZE];
+ SizeT inAvail = 0;
+ unsigned char *inBuffer = 0;
+
+ if (sizeof(UInt32) < 4)
+ return PrintError(rs, "LZMA decoder needs correct UInt32");
+
+ /* Read LZMA properties for compressed stream */
+
+ if (!MyReadFileAndCheck(inFile, properties, sizeof(properties)))
+ return PrintError(rs, kCantReadMessage);
+
+ /* Read uncompressed size */
+
+ for (i = 0; i < 8; i++)
+ {
+ unsigned char b;
+ if (!MyReadFileAndCheck(inFile, &b, 1))
+ return PrintError(rs, kCantReadMessage);
+ if (b != 0xFF)
+ waitEOS = 0;
+ if (i < 4)
+ outSize += (UInt32)(b) << (i * 8);
+ else
+ outSizeHigh += (UInt32)(b) << ((i - 4) * 8);
+ }
+
+ /* Decode LZMA properties and allocate memory */
+
+ if (LzmaDecodeProperties(&state.Properties, properties, LZMA_PROPERTIES_SIZE) != LZMA_RESULT_OK)
+ return PrintError(rs, "Incorrect stream properties");
+ state.Probs = (CProb *)malloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
+ if (state.Probs == 0)
+ return PrintError(rs, kCantAllocateMessage);
+
+ if (state.Properties.DictionarySize == 0)
+ state.Dictionary = 0;
+ else
+ {
+ state.Dictionary = (unsigned char *)malloc(state.Properties.DictionarySize);
+ if (state.Dictionary == 0)
+ {
+ free(state.Probs);
+ return PrintError(rs, kCantAllocateMessage);
+ }
+ }
+
+ /* Decompress */
+
+ LzmaDecoderInit(&state);
+
+ do
+ {
+ SizeT inProcessed, outProcessed;
+ int finishDecoding;
+ UInt32 outAvail = kOutBufferSize;
+ if (!waitEOS && outSizeHigh == 0 && outAvail > outSize)
+ outAvail = outSize;
+ if (inAvail == 0)
+ {
+ inAvail = (SizeT)MyReadFile(inFile, g_InBuffer, kInBufferSize);
+ inBuffer = g_InBuffer;
+ }
+ finishDecoding = (inAvail == 0);
+ res = LzmaDecode(&state,
+ inBuffer, inAvail, &inProcessed,
+ g_OutBuffer, outAvail, &outProcessed,
+ finishDecoding);
+ if (res != 0)
+ {
+ sprintf(rs + strlen(rs), "\nDecoding error = %d\n", res);
+ res = 1;
+ break;
+ }
+ inAvail -= inProcessed;
+ inBuffer += inProcessed;
+
+ if (outFile != 0)
+ if (fwrite(g_OutBuffer, 1, outProcessed, outFile) != outProcessed)
+ {
+ PrintError(rs, kCantWriteMessage);
+ res = 1;
+ break;
+ }
+
+ if (outSize < outProcessed)
+ outSizeHigh--;
+ outSize -= (UInt32)outProcessed;
+ outSize &= 0xFFFFFFFF;
+
+ if (outProcessed == 0 && finishDecoding)
+ {
+ if (!waitEOS && (outSize != 0 || outSizeHigh != 0))
+ res = 1;
+ break;
+ }
+ }
+ while ((outSize != 0 && outSizeHigh == 0) || outSizeHigh != 0 || waitEOS);
+
+ free(state.Dictionary);
+ free(state.Probs);
+ return res;
+}
+
+int main2(int numArgs, const char *args[], char *rs)
+{
+ FILE *inFile = 0;
+ FILE *outFile = 0;
+ int res;
+
+ sprintf(rs + strlen(rs), "\nLZMA Decoder 4.26 Copyright (c) 1999-2005 Igor Pavlov 2005-08-02\n");
+ if (numArgs < 2 || numArgs > 3)
+ {
+ sprintf(rs + strlen(rs), "\nUsage: lzmadec file.lzma [outFile]\n");
+ return 1;
+ }
+
+ inFile = fopen(args[1], "rb");
+ if (inFile == 0)
+ return PrintError(rs, "Can not open input file");
+
+ if (numArgs > 2)
+ {
+ outFile = fopen(args[2], "wb+");
+ if (outFile == 0)
+ return PrintError(rs, "Can not open output file");
+ }
+
+ res = main3(inFile, outFile, rs);
+
+ if (outFile != 0)
+ fclose(outFile);
+ fclose(inFile);
+ return res;
+}
+
+int main(int numArgs, const char *args[])
+{
+ char rs[800] = { 0 };
+ int res = main2(numArgs, args, rs);
+ printf(rs);
+ return res;
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_C/LzmaTest.c squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_C/LzmaTest.c
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_C/LzmaTest.c 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_C/LzmaTest.c 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,342 @@
+/*
+LzmaTest.c
+Test application for LZMA Decoder
+
+This file written and distributed to public domain by Igor Pavlov.
+This file is part of LZMA SDK 4.26 (2005-08-05)
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "LzmaDecode.h"
+
+const char *kCantReadMessage = "Can not read input file";
+const char *kCantWriteMessage = "Can not write output file";
+const char *kCantAllocateMessage = "Can not allocate memory";
+
+size_t MyReadFile(FILE *file, void *data, size_t size)
+{
+ if (size == 0)
+ return 0;
+ return fread(data, 1, size, file);
+}
+
+int MyReadFileAndCheck(FILE *file, void *data, size_t size)
+ { return (MyReadFile(file, data, size) == size);}
+
+size_t MyWriteFile(FILE *file, const void *data, size_t size)
+{
+ if (size == 0)
+ return 0;
+ return fwrite(data, 1, size, file);
+}
+
+int MyWriteFileAndCheck(FILE *file, const void *data, size_t size)
+ { return (MyWriteFile(file, data, size) == size); }
+
+#ifdef _LZMA_IN_CB
+#define kInBufferSize (1 << 15)
+typedef struct _CBuffer
+{
+ ILzmaInCallback InCallback;
+ FILE *File;
+ unsigned char Buffer[kInBufferSize];
+} CBuffer;
+
+int LzmaReadCompressed(void *object, const unsigned char **buffer, SizeT *size)
+{
+ CBuffer *b = (CBuffer *)object;
+ *buffer = b->Buffer;
+ *size = (SizeT)MyReadFile(b->File, b->Buffer, kInBufferSize);
+ return LZMA_RESULT_OK;
+}
+CBuffer g_InBuffer;
+
+#endif
+
+#ifdef _LZMA_OUT_READ
+#define kOutBufferSize (1 << 15)
+unsigned char g_OutBuffer[kOutBufferSize];
+#endif
+
+int PrintError(char *buffer, const char *message)
+{
+ sprintf(buffer + strlen(buffer), "\nError: ");
+ sprintf(buffer + strlen(buffer), message);
+ return 1;
+}
+
+int main3(FILE *inFile, FILE *outFile, char *rs)
+{
+ /* We use two 32-bit integers to construct 64-bit integer for file size.
+ You can remove outSizeHigh, if you don't need >= 4GB supporting,
+ or you can use UInt64 outSize, if your compiler supports 64-bit integers*/
+ UInt32 outSize = 0;
+ UInt32 outSizeHigh = 0;
+ #ifndef _LZMA_OUT_READ
+ SizeT outSizeFull;
+ unsigned char *outStream;
+ #endif
+
+ int waitEOS = 1;
+ /* waitEOS = 1, if there is no uncompressed size in headers,
+ so decoder will wait EOS (End of Stream Marker) in compressed stream */
+
+ #ifndef _LZMA_IN_CB
+ SizeT compressedSize;
+ unsigned char *inStream;
+ #endif
+
+ CLzmaDecoderState state; /* it's about 24-80 bytes structure, if int is 32-bit */
+ unsigned char properties[LZMA_PROPERTIES_SIZE];
+
+ int res;
+
+ #ifdef _LZMA_IN_CB
+ g_InBuffer.File = inFile;
+ #endif
+
+ if (sizeof(UInt32) < 4)
+ return PrintError(rs, "LZMA decoder needs correct UInt32");
+
+ #ifndef _LZMA_IN_CB
+ {
+ long length;
+ fseek(inFile, 0, SEEK_END);
+ length = ftell(inFile);
+ fseek(inFile, 0, SEEK_SET);
+ if ((long)(SizeT)length != length)
+ return PrintError(rs, "Too big compressed stream");
+ compressedSize = (SizeT)(length - (LZMA_PROPERTIES_SIZE + 8));
+ }
+ #endif
+
+ /* Read LZMA properties for compressed stream */
+
+ if (!MyReadFileAndCheck(inFile, properties, sizeof(properties)))
+ return PrintError(rs, kCantReadMessage);
+
+ /* Read uncompressed size */
+
+ {
+ int i;
+ for (i = 0; i < 8; i++)
+ {
+ unsigned char b;
+ if (!MyReadFileAndCheck(inFile, &b, 1))
+ return PrintError(rs, kCantReadMessage);
+ if (b != 0xFF)
+ waitEOS = 0;
+ if (i < 4)
+ outSize += (UInt32)(b) << (i * 8);
+ else
+ outSizeHigh += (UInt32)(b) << ((i - 4) * 8);
+ }
+
+ #ifndef _LZMA_OUT_READ
+ if (waitEOS)
+ return PrintError(rs, "Stream with EOS marker is not supported");
+ outSizeFull = (SizeT)outSize;
+ if (sizeof(SizeT) >= 8)
+ outSizeFull |= (((SizeT)outSizeHigh << 16) << 16);
+ else if (outSizeHigh != 0 || (UInt32)(SizeT)outSize != outSize)
+ return PrintError(rs, "Too big uncompressed stream");
+ #endif
+ }
+
+ /* Decode LZMA properties and allocate memory */
+
+ if (LzmaDecodeProperties(&state.Properties, properties, LZMA_PROPERTIES_SIZE) != LZMA_RESULT_OK)
+ return PrintError(rs, "Incorrect stream properties");
+ state.Probs = (CProb *)malloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
+
+ #ifdef _LZMA_OUT_READ
+ if (state.Properties.DictionarySize == 0)
+ state.Dictionary = 0;
+ else
+ state.Dictionary = (unsigned char *)malloc(state.Properties.DictionarySize);
+ #else
+ if (outSizeFull == 0)
+ outStream = 0;
+ else
+ outStream = (unsigned char *)malloc(outSizeFull);
+ #endif
+
+ #ifndef _LZMA_IN_CB
+ if (compressedSize == 0)
+ inStream = 0;
+ else
+ inStream = (unsigned char *)malloc(compressedSize);
+ #endif
+
+ if (state.Probs == 0
+ #ifdef _LZMA_OUT_READ
+ || (state.Dictionary == 0 && state.Properties.DictionarySize != 0)
+ #else
+ || (outStream == 0 && outSizeFull != 0)
+ #endif
+ #ifndef _LZMA_IN_CB
+ || (inStream == 0 && compressedSize != 0)
+ #endif
+ )
+ {
+ free(state.Probs);
+ #ifdef _LZMA_OUT_READ
+ free(state.Dictionary);
+ #else
+ free(outStream);
+ #endif
+ #ifndef _LZMA_IN_CB
+ free(inStream);
+ #endif
+ return PrintError(rs, kCantAllocateMessage);
+ }
+
+ /* Decompress */
+
+ #ifdef _LZMA_IN_CB
+ g_InBuffer.InCallback.Read = LzmaReadCompressed;
+ #else
+ if (!MyReadFileAndCheck(inFile, inStream, compressedSize))
+ return PrintError(rs, kCantReadMessage);
+ #endif
+
+ #ifdef _LZMA_OUT_READ
+ {
+ #ifndef _LZMA_IN_CB
+ SizeT inAvail = compressedSize;
+ const unsigned char *inBuffer = inStream;
+ #endif
+ LzmaDecoderInit(&state);
+ do
+ {
+ #ifndef _LZMA_IN_CB
+ SizeT inProcessed;
+ #endif
+ SizeT outProcessed;
+ SizeT outAvail = kOutBufferSize;
+ if (!waitEOS && outSizeHigh == 0 && outAvail > outSize)
+ outAvail = (SizeT)outSize;
+ res = LzmaDecode(&state,
+ #ifdef _LZMA_IN_CB
+ &g_InBuffer.InCallback,
+ #else
+ inBuffer, inAvail, &inProcessed,
+ #endif
+ g_OutBuffer, outAvail, &outProcessed);
+ if (res != 0)
+ {
+ sprintf(rs + strlen(rs), "\nDecoding error = %d\n", res);
+ res = 1;
+ break;
+ }
+ #ifndef _LZMA_IN_CB
+ inAvail -= inProcessed;
+ inBuffer += inProcessed;
+ #endif
+
+ if (outFile != 0)
+ if (!MyWriteFileAndCheck(outFile, g_OutBuffer, (size_t)outProcessed))
+ {
+ PrintError(rs, kCantWriteMessage);
+ res = 1;
+ break;
+ }
+
+ if (outSize < outProcessed)
+ outSizeHigh--;
+ outSize -= (UInt32)outProcessed;
+ outSize &= 0xFFFFFFFF;
+
+ if (outProcessed == 0)
+ {
+ if (!waitEOS && (outSize != 0 || outSizeHigh != 0))
+ res = 1;
+ break;
+ }
+ }
+ while ((outSize != 0 && outSizeHigh == 0) || outSizeHigh != 0 || waitEOS);
+ }
+
+ #else
+ {
+ #ifndef _LZMA_IN_CB
+ SizeT inProcessed;
+ #endif
+ SizeT outProcessed;
+ res = LzmaDecode(&state,
+ #ifdef _LZMA_IN_CB
+ &g_InBuffer.InCallback,
+ #else
+ inStream, compressedSize, &inProcessed,
+ #endif
+ outStream, outSizeFull, &outProcessed);
+ if (res != 0)
+ {
+ sprintf(rs + strlen(rs), "\nDecoding error = %d\n", res);
+ res = 1;
+ }
+ else if (outFile != 0)
+ {
+ if (!MyWriteFileAndCheck(outFile, outStream, (size_t)outProcessed))
+ {
+ PrintError(rs, kCantWriteMessage);
+ res = 1;
+ }
+ }
+ }
+ #endif
+
+ free(state.Probs);
+ #ifdef _LZMA_OUT_READ
+ free(state.Dictionary);
+ #else
+ free(outStream);
+ #endif
+ #ifndef _LZMA_IN_CB
+ free(inStream);
+ #endif
+ return res;
+}
+
+int main2(int numArgs, const char *args[], char *rs)
+{
+ FILE *inFile = 0;
+ FILE *outFile = 0;
+ int res;
+
+ sprintf(rs + strlen(rs), "\nLZMA Decoder 4.26 Copyright (c) 1999-2005 Igor Pavlov 2005-08-05\n");
+ if (numArgs < 2 || numArgs > 3)
+ {
+ sprintf(rs + strlen(rs), "\nUsage: lzmadec file.lzma [outFile]\n");
+ return 1;
+ }
+
+ inFile = fopen(args[1], "rb");
+ if (inFile == 0)
+ return PrintError(rs, "Can not open input file");
+
+ if (numArgs > 2)
+ {
+ outFile = fopen(args[2], "wb+");
+ if (outFile == 0)
+ return PrintError(rs, "Can not open output file");
+ }
+
+ res = main3(inFile, outFile, rs);
+
+ if (outFile != 0)
+ fclose(outFile);
+ fclose(inFile);
+ return res;
+}
+
+int main(int numArgs, const char *args[])
+{
+ char rs[800] = { 0 };
+ int res = main2(numArgs, args, rs);
+ printf(rs);
+ return res;
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_C/makefile squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_C/makefile
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_C/makefile 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_C/makefile 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,43 @@
+PROG = lzmaDec.exe
+
+!IFNDEF O
+!IFDEF CPU
+O=$(CPU)
+!ELSE
+O=O
+!ENDIF
+!ENDIF
+
+CFLAGS = $(CFLAGS) -nologo -c -Fo$O/ -GS-
+CFLAGS_O1 = $(CFLAGS) -O1
+CFLAGS_O2 = $(CFLAGS) -O2
+
+LFLAGS = $(LFLAGS) -nologo -OPT:NOWIN98
+
+PROGPATH = $O\$(PROG)
+
+COMPL_O1 = $(CPP) $(CFLAGS_O1) $**
+COMPL_O2 = $(CPP) $(CFLAGS_O2) $**
+COMPL = $(CPP) $(CFLAGS_O1) $**
+
+
+OBJS = \
+ $O\LzmaTest.obj \
+ $O\LzmaDecode.obj \
+
+all: $(PROGPATH)
+
+clean:
+ -del /Q $(PROGPATH) $O\*.exe $O\*.dll $O\*.obj $O\*.lib $O\*.exp $O\*.res $O\*.pch
+
+$O:
+ if not exist "$O" mkdir "$O"
+
+$(PROGPATH): $O $(OBJS)
+ link $(LFLAGS) -out:$(PROGPATH) $(OBJS) $(LIBS)
+
+
+$O\LzmaTest.obj: $(*B).c
+ $(COMPL)
+$O\LzmaDecode.obj: ../../Compress/LZMA_C/$(*B).c
+ $(COMPL_O2)
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_C/makefile.gcc squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_C/makefile.gcc
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_C/makefile.gcc 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_C/makefile.gcc 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,23 @@
+PROG = lzmadec
+CXX = gcc
+LIB =
+RM = rm -f
+CFLAGS = -c -O2 -Wall -pedantic -D _LZMA_PROB32
+
+OBJS = LzmaTest.o LzmaDecode.o
+
+all: $(PROG)
+
+$(PROG): $(OBJS)
+ $(CXX) -o $(PROG) $(LDFLAGS) $(OBJS) $(LIB)
+
+LzmaTest.o: LzmaTest.c
+ $(CXX) $(CFLAGS) LzmaTest.c
+
+LzmaDecode.o: LzmaDecode.c
+ $(CXX) $(CFLAGS) LzmaDecode.c
+
+
+clean:
+ -$(RM) $(PROG) $(OBJS)
+
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Lib/lzmadaptive.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Lib/lzmadaptive.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Lib/lzmadaptive.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Lib/lzmadaptive.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,21 @@
+#ifndef __LZMA_LIB_H__
+#define __LZMA_LIB_H__
+
+#include <zlib.h>
+
+// CJH: For Gentoo zlib compatibility
+#ifdef _Z_OF
+#undef OF
+#define OF _Z_OF
+#endif
+
+/* CJH: Depreciated.
+int lzmalib_uncompress OF((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen));
+int lzma7z_uncompress OF((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen));
+int lzmalinksys_uncompress OF((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen));
+*/
+
+int lzmawrt_uncompress OF((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen));
+int lzmaspec_uncompress OF((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen, int lc, int lp, int pb, int dictionary_size, int offset));
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Lib/makefile squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Lib/makefile
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Lib/makefile 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Lib/makefile 2016-08-25 09:06:03.223530354 -0400
@@ -0,0 +1,92 @@
+PROG = liblzmalib.a
+CXX = g++ -O3 -Wall
+AR = ar
+RM = rm -f
+CFLAGS = -c -I ../../../
+
+OBJS = \
+ ZLib.o \
+ LZMADecoder.o \
+ LZMAEncoder.o \
+ LZInWindow.o \
+ LZOutWindow.o \
+ RangeCoderBit.o \
+ InBuffer.o \
+ OutBuffer.o \
+ FileStreams.o \
+ Alloc.o \
+ C_FileIO.o \
+ CommandLineParser.o \
+ CRC.o \
+ StreamUtils.o \
+ String.o \
+ StringConvert.o \
+ StringToInt.o \
+ Vector.o \
+
+
+all: $(PROG)
+
+$(PROG): $(OBJS)
+ $(AR) r $(PROG) $(OBJS)
+
+ZLib.o: ZLib.cpp
+ $(CXX) $(CFLAGS) ZLib.cpp
+
+LZMADecoder.o: ../LZMA/LZMADecoder.cpp
+ $(CXX) $(CFLAGS) ../LZMA/LZMADecoder.cpp
+
+LZMAEncoder.o: ../LZMA/LZMAEncoder.cpp
+ $(CXX) $(CFLAGS) ../LZMA/LZMAEncoder.cpp
+
+LZInWindow.o: ../LZ/LZInWindow.cpp
+ $(CXX) $(CFLAGS) ../LZ/LZInWindow.cpp
+
+LZOutWindow.o: ../LZ/LZOutWindow.cpp
+ $(CXX) $(CFLAGS) ../LZ/LZOutWindow.cpp
+
+RangeCoderBit.o: ../RangeCoder/RangeCoderBit.cpp
+ $(CXX) $(CFLAGS) ../RangeCoder/RangeCoderBit.cpp
+
+InBuffer.o: ../../Common/InBuffer.cpp
+ $(CXX) $(CFLAGS) ../../Common/InBuffer.cpp
+
+OutBuffer.o: ../../Common/OutBuffer.cpp
+ $(CXX) $(CFLAGS) ../../Common/OutBuffer.cpp
+
+StreamUtils.o: ../../Common/StreamUtils.cpp
+ $(CXX) $(CFLAGS) ../../Common/StreamUtils.cpp
+
+FileStreams.o: ../../Common/FileStreams.cpp
+ $(CXX) $(CFLAGS) ../../Common/FileStreams.cpp
+
+Alloc.o: ../../../Common/Alloc.cpp
+ $(CXX) $(CFLAGS) ../../../Common/Alloc.cpp
+
+C_FileIO.o: ../../../Common/C_FileIO.cpp
+ $(CXX) $(CFLAGS) ../../../Common/C_FileIO.cpp
+
+CommandLineParser.o: ../../../Common/CommandLineParser.cpp
+ $(CXX) $(CFLAGS) ../../../Common/CommandLineParser.cpp
+
+CRC.o: ../../../Common/CRC.cpp
+ $(CXX) $(CFLAGS) ../../../Common/CRC.cpp
+
+MyWindows.o: ../../../Common/MyWindows.cpp
+ $(CXX) $(CFLAGS) ../../../Common/MyWindows.cpp
+
+String.o: ../../../Common/String.cpp
+ $(CXX) $(CFLAGS) ../../../Common/String.cpp
+
+StringConvert.o: ../../../Common/StringConvert.cpp
+ $(CXX) $(CFLAGS) ../../../Common/StringConvert.cpp
+
+StringToInt.o: ../../../Common/StringToInt.cpp
+ $(CXX) $(CFLAGS) ../../../Common/StringToInt.cpp
+
+Vector.o: ../../../Common/Vector.cpp
+ $(CXX) $(CFLAGS) ../../../Common/Vector.cpp
+
+clean:
+ -$(RM) $(PROG) $(OBJS)
+
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Lib/ZLib.cpp squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Lib/ZLib.cpp
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Lib/ZLib.cpp 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/LZMA_Lib/ZLib.cpp 2016-08-25 09:06:03.223530354 -0400
@@ -0,0 +1,451 @@
+/*
+ * lzma zlib simplified wrapper
+ *
+ * Copyright (c) 2005-2006 Oleg I. Vdovikin <oleg@cs.msu.su>
+ *
+ * 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., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * default values for encoder/decoder used by wrapper
+ */
+
+#include <stdio.h>
+#include <zlib.h>
+
+// CJH: For Gentoo zlib compatibility.
+#ifdef _Z_OF
+#undef OF
+#define OF _Z_OF
+#endif
+
+#define ZLIB_LC 3
+#define ZLIB_LP 0
+#define ZLIB_PB 2
+
+// CJH: Taken from E2100 squashfs implementation
+#define ZLIB_LC_E2100 0
+#define ZLIB_LP_E2100 0
+#define ZLIB_PB_E2100 2
+
+#ifdef WIN32
+#include <initguid.h>
+#else
+#define INITGUID
+#endif
+
+#include "../../../Common/MyWindows.h"
+#include "../LZMA/LZMADecoder.h"
+#include "../LZMA/LZMAEncoder.h"
+
+#define STG_E_SEEKERROR ((HRESULT)0x80030019L)
+#define STG_E_MEDIUMFULL ((HRESULT)0x80030070L)
+
+class CInMemoryStream:
+ public IInStream,
+ public IStreamGetSize,
+ public CMyUnknownImp
+{
+public:
+ CInMemoryStream(const Bytef *data, UInt64 size) :
+ m_data(data), m_size(size), m_offset(0) {}
+
+ virtual ~CInMemoryStream() {}
+
+ MY_UNKNOWN_IMP2(IInStream, IStreamGetSize)
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize)
+ {
+ if (size > m_size - m_offset)
+ size = m_size - m_offset;
+
+ if (size) {
+ memcpy(data, m_data + m_offset, size);
+ }
+
+ m_offset += size;
+
+ if (processedSize)
+ *processedSize = size;
+
+ return S_OK;
+ }
+
+ STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize)
+ {
+ return Read(data, size, processedSize);
+ }
+
+ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
+ {
+ UInt64 _offset;
+
+ if (seekOrigin == STREAM_SEEK_SET) _offset = offset;
+ else if (seekOrigin == STREAM_SEEK_CUR) _offset = m_offset + offset;
+ else if (seekOrigin == STREAM_SEEK_END) _offset = m_size;
+ else return STG_E_INVALIDFUNCTION;
+
+ if (_offset < 0 || _offset > m_size)
+ return STG_E_SEEKERROR;
+
+ m_offset = _offset;
+
+ if (newPosition)
+ *newPosition = m_offset;
+
+ return S_OK;
+ }
+
+ STDMETHOD(GetSize)(UInt64 *size)
+ {
+ *size = m_size;
+ return S_OK;
+ }
+protected:
+ const Bytef *m_data;
+ UInt64 m_size;
+ UInt64 m_offset;
+};
+
+class COutMemoryStream:
+ public IOutStream,
+ public CMyUnknownImp
+{
+public:
+ COutMemoryStream(Bytef *data, UInt64 maxsize) :
+ m_data(data), m_size(0), m_maxsize(maxsize), m_offset(0) {}
+ virtual ~COutMemoryStream() {}
+
+ MY_UNKNOWN_IMP1(IOutStream)
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize)
+ {
+ if (size > m_maxsize - m_offset)
+ size = m_maxsize - m_offset;
+
+ if (size) {
+ memcpy(m_data + m_offset, data, size);
+ }
+
+ m_offset += size;
+
+ if (m_offset > m_size)
+ m_size = m_offset;
+
+ if (processedSize)
+ *processedSize = size;
+
+ return S_OK;
+ }
+
+ STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize)
+ {
+ return Write(data, size, processedSize);
+ }
+
+ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
+ {
+ UInt64 _offset;
+
+ if (seekOrigin == STREAM_SEEK_SET) _offset = offset;
+ else if (seekOrigin == STREAM_SEEK_CUR) _offset = m_offset + offset;
+ else if (seekOrigin == STREAM_SEEK_END) _offset = m_size;
+ else return STG_E_INVALIDFUNCTION;
+
+ if (_offset < 0 || _offset > m_maxsize)
+ return STG_E_SEEKERROR;
+
+ m_offset = _offset;
+
+ if (newPosition)
+ *newPosition = m_offset;
+
+ return S_OK;
+ }
+
+ STDMETHOD(SetSize)(Int64 newSize)
+ {
+ if ((UInt64)newSize > m_maxsize)
+ return STG_E_MEDIUMFULL;
+
+ return S_OK;
+ }
+protected:
+ Bytef *m_data;
+ UInt64 m_size;
+ UInt64 m_maxsize;
+ UInt64 m_offset;
+};
+
+ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen,
+ int level))
+{
+ CInMemoryStream *inStreamSpec = new CInMemoryStream(source, sourceLen);
+ CMyComPtr<ISequentialInStream> inStream = inStreamSpec;
+
+ COutMemoryStream *outStreamSpec = new COutMemoryStream(dest, *destLen);
+ CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
+
+ NCompress::NLZMA::CEncoder *encoderSpec =
+ new NCompress::NLZMA::CEncoder;
+ CMyComPtr<ICompressCoder> encoder = encoderSpec;
+
+ PROPID propIDs[] =
+ {
+ NCoderPropID::kDictionarySize,
+ NCoderPropID::kPosStateBits,
+ NCoderPropID::kLitContextBits,
+ NCoderPropID::kLitPosBits,
+ NCoderPropID::kAlgorithm,
+ NCoderPropID::kNumFastBytes,
+ NCoderPropID::kMatchFinder,
+ NCoderPropID::kEndMarker
+ };
+ const int kNumProps = sizeof(propIDs) / sizeof(propIDs[0]);
+
+ PROPVARIANT properties[kNumProps];
+ for (int p = 0; p < 6; p++)
+ properties[p].vt = VT_UI4;
+ properties[0].ulVal = UInt32(1 << (level + 14));
+ properties[1].ulVal = UInt32(ZLIB_PB);
+ properties[2].ulVal = UInt32(ZLIB_LC); // for normal files
+ properties[3].ulVal = UInt32(ZLIB_LP); // for normal files
+ properties[4].ulVal = UInt32(2);
+ properties[5].ulVal = UInt32(128);
+
+ properties[6].vt = VT_BSTR;
+ properties[6].bstrVal = (BSTR)(const wchar_t *)L"BT4";
+
+ properties[7].vt = VT_BOOL;
+ properties[7].boolVal = VARIANT_TRUE;
+
+ if (encoderSpec->SetCoderProperties(propIDs, properties, kNumProps) != S_OK)
+ return Z_MEM_ERROR; // should not happen
+
+ HRESULT result = encoder->Code(inStream, outStream, 0, 0, 0);
+ if (result == E_OUTOFMEMORY)
+ {
+ return Z_MEM_ERROR;
+ }
+ else if (result != S_OK)
+ {
+ return Z_BUF_ERROR; // should not happen
+ }
+
+ UInt64 fileSize;
+ outStreamSpec->Seek(0, STREAM_SEEK_END, &fileSize);
+ *destLen = fileSize;
+
+ return Z_OK;
+}
+
+/*
+ * CJH: These are depreciated, and left here merely for future reference.
+ *
+// CJH: s/uncompress/lzmalib_uncompress/
+extern "C" int lzmalib_uncompress OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen))
+{
+ // CJH: 7zip ID implemented by some LZMA implementations
+ if(strncmp((char *) source, "7zip", 4) == 0)
+ {
+ source += 4;
+ sourceLen -= 4;
+ }
+
+ CInMemoryStream *inStreamSpec = new CInMemoryStream(source, sourceLen);
+ CMyComPtr<ISequentialInStream> inStream = inStreamSpec;
+
+ COutMemoryStream *outStreamSpec = new COutMemoryStream(dest, *destLen);
+ CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
+
+ NCompress::NLZMA::CDecoder *decoderSpec =
+ new NCompress::NLZMA::CDecoder;
+ CMyComPtr<ICompressCoder> decoder = decoderSpec;
+
+ if (decoderSpec->SetDecoderPropertiesRaw(ZLIB_LC,
+ ZLIB_LP, ZLIB_PB, (1 << 23)) != S_OK) return Z_DATA_ERROR;
+
+ UInt64 fileSize = *destLen;
+
+ if (decoder->Code(inStream, outStream, 0, &fileSize, 0) != S_OK)
+ {
+ return Z_DATA_ERROR;
+ }
+
+ outStreamSpec->Seek(0, STREAM_SEEK_END, &fileSize);
+ *destLen = fileSize;
+
+ return Z_OK;
+}
+
+// CJH: A decompressor used by some Linksys SquashFS images
+extern "C" int lzmalinksys_uncompress OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen))
+{
+ CInMemoryStream *inStreamSpec = new CInMemoryStream(source, sourceLen);
+ CMyComPtr<ISequentialInStream> inStream = inStreamSpec;
+
+ COutMemoryStream *outStreamSpec = new COutMemoryStream(dest, *destLen);
+ CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
+
+ NCompress::NLZMA::CDecoder *decoderSpec =
+ new NCompress::NLZMA::CDecoder;
+ CMyComPtr<ICompressCoder> decoder = decoderSpec;
+
+ if (decoderSpec->SetDecoderPropertiesRaw(ZLIB_LC_E2100,
+ ZLIB_LP_E2100, ZLIB_PB_E2100, (1 << 23)) != S_OK) return Z_DATA_ERROR;
+
+ UInt64 fileSize = *destLen;
+
+ if (decoder->Code(inStream, outStream, 0, &fileSize, 0) != S_OK)
+ {
+ return Z_DATA_ERROR;
+ }
+
+ outStreamSpec->Seek(0, STREAM_SEEK_END, &fileSize);
+ *destLen = fileSize;
+
+ return Z_OK;
+}
+
+// CJH: A decompressor for "squashfs7z" images
+extern "C" int lzma7z_uncompress OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen))
+{
+ // CJH: This variation encodes the properties values + size into the first nine bytes
+ CInMemoryStream *inStreamSpec = new CInMemoryStream(source+9, sourceLen-9);
+ CMyComPtr<ISequentialInStream> inStream = inStreamSpec;
+
+ COutMemoryStream *outStreamSpec = new COutMemoryStream(dest, *destLen);
+ CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
+
+ NCompress::NLZMA::CDecoder *decoderSpec =
+ new NCompress::NLZMA::CDecoder;
+ CMyComPtr<ICompressCoder> decoder = decoderSpec;
+
+ // CJH: This variation uses SetDecoderProperties2
+ //if (decoderSpec->SetDecoderPropertiesRaw(source[1],
+ // source[2], source[0], (1 << 23)) != S_OK) return Z_DATA_ERROR;
+ if (decoderSpec->SetDecoderProperties2(source+4, 5) != S_OK)
+ return Z_DATA_ERROR;
+
+ UInt64 fileSize = *destLen;
+
+ if (decoder->Code(inStream, outStream, 0, &fileSize, 0) != S_OK)
+ {
+ return Z_DATA_ERROR;
+ }
+
+ outStreamSpec->Seek(0, STREAM_SEEK_END, &fileSize);
+ *destLen = fileSize;
+
+ return Z_OK;
+}
+
+*/
+
+// CJH: A decompressor for LZMA DD-WRT SquashFS images
+extern "C" int lzmawrt_uncompress OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen))
+{
+ // CJH: DD-WRT encodes the properties values into the first four bytes
+ CInMemoryStream *inStreamSpec = new CInMemoryStream(source+4, sourceLen-4);
+ CMyComPtr<ISequentialInStream> inStream = inStreamSpec;
+
+ COutMemoryStream *outStreamSpec = new COutMemoryStream(dest, *destLen);
+ CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
+
+ NCompress::NLZMA::CDecoder *decoderSpec =
+ new NCompress::NLZMA::CDecoder;
+ CMyComPtr<ICompressCoder> decoder = decoderSpec;
+
+ /*
+ * CJH: DD-WRT encodes the LZMA properties into the beginning of each compressed block.
+ * Sanity check these values to prevent errors in the LZMA library.
+ */
+ //printf("WRT properties: %d %d %d\n", (unsigned int) source[1],
+ // (unsigned int) source[2],
+ // (unsigned int) source[0]);
+ if((unsigned int) source[1] > 4 ||
+ (unsigned int) source[2] > 4 ||
+ (unsigned int) source[0] > 4 ||
+ ((unsigned int) source[1] + (unsigned int) source[2]) > 4)
+ {
+ return Z_DATA_ERROR;
+ }
+
+ if (decoderSpec->SetDecoderPropertiesRaw(source[1],
+ source[2], source[0], (1 << 23)) != S_OK) return Z_DATA_ERROR;
+
+ UInt64 fileSize = *destLen;
+
+ if (decoder->Code(inStream, outStream, 0, &fileSize, 0) != S_OK)
+ {
+ return Z_DATA_ERROR;
+ }
+
+ outStreamSpec->Seek(0, STREAM_SEEK_END, &fileSize);
+ *destLen = fileSize;
+
+ return Z_OK;
+}
+
+// CJH: A decompressor used for brute forcing commonly modified LZMA fields
+extern "C" int lzmaspec_uncompress OF((Bytef *dest,
+ uLongf *destLen,
+ const Bytef *source,
+ uLong sourceLen,
+ int lc,
+ int lp,
+ int pb,
+ int dictionary_size,
+ int offset))
+{
+ CInMemoryStream *inStreamSpec = new CInMemoryStream(source+offset, sourceLen-offset);
+ CMyComPtr<ISequentialInStream> inStream = inStreamSpec;
+
+ COutMemoryStream *outStreamSpec = new COutMemoryStream(dest, *destLen);
+ CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
+
+ NCompress::NLZMA::CDecoder *decoderSpec = new NCompress::NLZMA::CDecoder;
+ CMyComPtr<ICompressCoder> decoder = decoderSpec;
+
+ // CJH: Use the default dictionary size if none was specified
+ if (dictionary_size <= 0)
+ {
+ dictionary_size = (1 << 23);
+ }
+
+ if (decoderSpec->SetDecoderPropertiesRaw(lc,
+ lp, pb, dictionary_size) != S_OK) return Z_DATA_ERROR;
+
+ UInt64 fileSize = *destLen;
+
+ if (decoder->Code(inStream, outStream, 0, &fileSize, 0) != S_OK)
+ {
+ return Z_DATA_ERROR;
+ }
+
+ outStreamSpec->Seek(0, STREAM_SEEK_END, &fileSize);
+ *destLen = fileSize;
+
+ return Z_OK;
+}
+
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/RangeCoder/RangeCoderBit.cpp squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/RangeCoder/RangeCoderBit.cpp
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/RangeCoder/RangeCoderBit.cpp 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/RangeCoder/RangeCoderBit.cpp 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,80 @@
+// Compress/RangeCoder/RangeCoderBit.cpp
+
+#include "StdAfx.h"
+
+#include "RangeCoderBit.h"
+
+namespace NCompress {
+namespace NRangeCoder {
+
+UInt32 CPriceTables::ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
+static CPriceTables g_PriceTables;
+
+CPriceTables::CPriceTables() { Init(); }
+
+void CPriceTables::Init()
+{
+ const int kNumBits = (kNumBitModelTotalBits - kNumMoveReducingBits);
+ for(int i = kNumBits - 1; i >= 0; i--)
+ {
+ UInt32 start = 1 << (kNumBits - i - 1);
+ UInt32 end = 1 << (kNumBits - i);
+ for (UInt32 j = start; j < end; j++)
+ ProbPrices[j] = (i << kNumBitPriceShiftBits) +
+ (((end - j) << kNumBitPriceShiftBits) >> (kNumBits - i - 1));
+ }
+
+ /*
+ // simplest: bad solution
+ for(UInt32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
+ ProbPrices[i] = kBitPrice;
+ */
+
+ /*
+ const double kDummyMultMid = (1.0 / kBitPrice) / 2;
+ const double kDummyMultMid = 0;
+ // float solution
+ double ln2 = log(double(2));
+ double lnAll = log(double(kBitModelTotal >> kNumMoveReducingBits));
+ for(UInt32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
+ ProbPrices[i] = UInt32((fabs(lnAll - log(double(i))) / ln2 + kDummyMultMid) * kBitPrice);
+ */
+
+ /*
+ // experimental, slow, solution:
+ for(UInt32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
+ {
+ const int kCyclesBits = 5;
+ const UInt32 kCycles = (1 << kCyclesBits);
+
+ UInt32 range = UInt32(-1);
+ UInt32 bitCount = 0;
+ for (UInt32 j = 0; j < kCycles; j++)
+ {
+ range >>= (kNumBitModelTotalBits - kNumMoveReducingBits);
+ range *= i;
+ while(range < (1 << 31))
+ {
+ range <<= 1;
+ bitCount++;
+ }
+ }
+ bitCount <<= kNumBitPriceShiftBits;
+ range -= (1 << 31);
+ for (int k = kNumBitPriceShiftBits - 1; k >= 0; k--)
+ {
+ range <<= 1;
+ if (range > (1 << 31))
+ {
+ bitCount += (1 << k);
+ range -= (1 << 31);
+ }
+ }
+ ProbPrices[i] = (bitCount
+ // + (1 << (kCyclesBits - 1))
+ ) >> kCyclesBits;
+ }
+ */
+}
+
+}}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/RangeCoder/RangeCoderBit.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/RangeCoder/RangeCoderBit.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/RangeCoder/RangeCoderBit.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/RangeCoder/RangeCoderBit.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,120 @@
+// Compress/RangeCoder/RangeCoderBit.h
+
+#ifndef __COMPRESS_RANGECODER_BIT_H
+#define __COMPRESS_RANGECODER_BIT_H
+
+#include "RangeCoder.h"
+
+namespace NCompress {
+namespace NRangeCoder {
+
+const int kNumBitModelTotalBits = 11;
+const UInt32 kBitModelTotal = (1 << kNumBitModelTotalBits);
+
+const int kNumMoveReducingBits = 2;
+
+const int kNumBitPriceShiftBits = 6;
+const UInt32 kBitPrice = 1 << kNumBitPriceShiftBits;
+
+class CPriceTables
+{
+public:
+ static UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
+ static void Init();
+ CPriceTables();
+};
+
+template <int numMoveBits>
+class CBitModel
+{
+public:
+ UInt32 Prob;
+ void UpdateModel(UInt32 symbol)
+ {
+ /*
+ Prob -= (Prob + ((symbol - 1) & ((1 << numMoveBits) - 1))) >> numMoveBits;
+ Prob += (1 - symbol) << (kNumBitModelTotalBits - numMoveBits);
+ */
+ if (symbol == 0)
+ Prob += (kBitModelTotal - Prob) >> numMoveBits;
+ else
+ Prob -= (Prob) >> numMoveBits;
+ }
+public:
+ void Init() { Prob = kBitModelTotal / 2; }
+};
+
+template <int numMoveBits>
+class CBitEncoder: public CBitModel<numMoveBits>
+{
+public:
+ void Encode(CEncoder *encoder, UInt32 symbol)
+ {
+ /*
+ encoder->EncodeBit(this->Prob, kNumBitModelTotalBits, symbol);
+ this->UpdateModel(symbol);
+ */
+ UInt32 newBound = (encoder->Range >> kNumBitModelTotalBits) * this->Prob;
+ if (symbol == 0)
+ {
+ encoder->Range = newBound;
+ this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits;
+ }
+ else
+ {
+ encoder->Low += newBound;
+ encoder->Range -= newBound;
+ this->Prob -= (this->Prob) >> numMoveBits;
+ }
+ if (encoder->Range < kTopValue)
+ {
+ encoder->Range <<= 8;
+ encoder->ShiftLow();
+ }
+ }
+ UInt32 GetPrice(UInt32 symbol) const
+ {
+ return CPriceTables::ProbPrices[
+ (((this->Prob - symbol) ^ ((-(int)symbol))) & (kBitModelTotal - 1)) >> kNumMoveReducingBits];
+ }
+ UInt32 GetPrice0() const { return CPriceTables::ProbPrices[this->Prob >> kNumMoveReducingBits]; }
+ UInt32 GetPrice1() const { return CPriceTables::ProbPrices[(kBitModelTotal - this->Prob) >> kNumMoveReducingBits]; }
+};
+
+
+template <int numMoveBits>
+class CBitDecoder: public CBitModel<numMoveBits>
+{
+public:
+ UInt32 Decode(CDecoder *decoder)
+ {
+ UInt32 newBound = (decoder->Range >> kNumBitModelTotalBits) * this->Prob;
+ if (decoder->Code < newBound)
+ {
+ decoder->Range = newBound;
+ this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits;
+ if (decoder->Range < kTopValue)
+ {
+ decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte();
+ decoder->Range <<= 8;
+ }
+ return 0;
+ }
+ else
+ {
+ decoder->Range -= newBound;
+ decoder->Code -= newBound;
+ this->Prob -= (this->Prob) >> numMoveBits;
+ if (decoder->Range < kTopValue)
+ {
+ decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte();
+ decoder->Range <<= 8;
+ }
+ return 1;
+ }
+ }
+};
+
+}}
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/RangeCoder/RangeCoderBitTree.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/RangeCoder/RangeCoderBitTree.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/RangeCoder/RangeCoderBitTree.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/RangeCoder/RangeCoderBitTree.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,161 @@
+// Compress/RangeCoder/RangeCoderBitTree.h
+
+#ifndef __COMPRESS_RANGECODER_BIT_TREE_H
+#define __COMPRESS_RANGECODER_BIT_TREE_H
+
+#include "RangeCoderBit.h"
+#include "RangeCoderOpt.h"
+
+namespace NCompress {
+namespace NRangeCoder {
+
+template <int numMoveBits, int NumBitLevels>
+class CBitTreeEncoder
+{
+ CBitEncoder<numMoveBits> Models[1 << NumBitLevels];
+public:
+ void Init()
+ {
+ for(UInt32 i = 1; i < (1 << NumBitLevels); i++)
+ Models[i].Init();
+ }
+ void Encode(CEncoder *rangeEncoder, UInt32 symbol)
+ {
+ UInt32 modelIndex = 1;
+ for (int bitIndex = NumBitLevels; bitIndex != 0 ;)
+ {
+ bitIndex--;
+ UInt32 bit = (symbol >> bitIndex) & 1;
+ Models[modelIndex].Encode(rangeEncoder, bit);
+ modelIndex = (modelIndex << 1) | bit;
+ }
+ };
+ void ReverseEncode(CEncoder *rangeEncoder, UInt32 symbol)
+ {
+ UInt32 modelIndex = 1;
+ for (int i = 0; i < NumBitLevels; i++)
+ {
+ UInt32 bit = symbol & 1;
+ Models[modelIndex].Encode(rangeEncoder, bit);
+ modelIndex = (modelIndex << 1) | bit;
+ symbol >>= 1;
+ }
+ }
+ UInt32 GetPrice(UInt32 symbol) const
+ {
+ symbol |= (1 << NumBitLevels);
+ UInt32 price = 0;
+ while (symbol != 1)
+ {
+ price += Models[symbol >> 1].GetPrice(symbol & 1);
+ symbol >>= 1;
+ }
+ return price;
+ }
+ UInt32 ReverseGetPrice(UInt32 symbol) const
+ {
+ UInt32 price = 0;
+ UInt32 modelIndex = 1;
+ for (int i = NumBitLevels; i != 0; i--)
+ {
+ UInt32 bit = symbol & 1;
+ symbol >>= 1;
+ price += Models[modelIndex].GetPrice(bit);
+ modelIndex = (modelIndex << 1) | bit;
+ }
+ return price;
+ }
+};
+
+template <int numMoveBits, int NumBitLevels>
+class CBitTreeDecoder
+{
+ CBitDecoder<numMoveBits> Models[1 << NumBitLevels];
+public:
+ void Init()
+ {
+ for(UInt32 i = 1; i < (1 << NumBitLevels); i++)
+ Models[i].Init();
+ }
+ UInt32 Decode(CDecoder *rangeDecoder)
+ {
+ UInt32 modelIndex = 1;
+ RC_INIT_VAR
+ for(int bitIndex = NumBitLevels; bitIndex != 0; bitIndex--)
+ {
+ // modelIndex = (modelIndex << 1) + Models[modelIndex].Decode(rangeDecoder);
+ RC_GETBIT(numMoveBits, Models[modelIndex].Prob, modelIndex)
+ }
+ RC_FLUSH_VAR
+ return modelIndex - (1 << NumBitLevels);
+ };
+ UInt32 ReverseDecode(CDecoder *rangeDecoder)
+ {
+ UInt32 modelIndex = 1;
+ UInt32 symbol = 0;
+ RC_INIT_VAR
+ for(int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
+ {
+ // UInt32 bit = Models[modelIndex].Decode(rangeDecoder);
+ // modelIndex <<= 1;
+ // modelIndex += bit;
+ // symbol |= (bit << bitIndex);
+ RC_GETBIT2(numMoveBits, Models[modelIndex].Prob, modelIndex, ; , symbol |= (1 << bitIndex))
+ }
+ RC_FLUSH_VAR
+ return symbol;
+ }
+};
+
+template <int numMoveBits>
+void ReverseBitTreeEncode(CBitEncoder<numMoveBits> *Models,
+ CEncoder *rangeEncoder, int NumBitLevels, UInt32 symbol)
+{
+ UInt32 modelIndex = 1;
+ for (int i = 0; i < NumBitLevels; i++)
+ {
+ UInt32 bit = symbol & 1;
+ Models[modelIndex].Encode(rangeEncoder, bit);
+ modelIndex = (modelIndex << 1) | bit;
+ symbol >>= 1;
+ }
+}
+
+template <int numMoveBits>
+UInt32 ReverseBitTreeGetPrice(CBitEncoder<numMoveBits> *Models,
+ UInt32 NumBitLevels, UInt32 symbol)
+{
+ UInt32 price = 0;
+ UInt32 modelIndex = 1;
+ for (int i = NumBitLevels; i != 0; i--)
+ {
+ UInt32 bit = symbol & 1;
+ symbol >>= 1;
+ price += Models[modelIndex].GetPrice(bit);
+ modelIndex = (modelIndex << 1) | bit;
+ }
+ return price;
+}
+
+template <int numMoveBits>
+UInt32 ReverseBitTreeDecode(CBitDecoder<numMoveBits> *Models,
+ CDecoder *rangeDecoder, int NumBitLevels)
+{
+ UInt32 modelIndex = 1;
+ UInt32 symbol = 0;
+ RC_INIT_VAR
+ for(int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
+ {
+ // UInt32 bit = Models[modelIndex].Decode(rangeDecoder);
+ // modelIndex <<= 1;
+ // modelIndex += bit;
+ // symbol |= (bit << bitIndex);
+ RC_GETBIT2(numMoveBits, Models[modelIndex].Prob, modelIndex, ; , symbol |= (1 << bitIndex))
+ }
+ RC_FLUSH_VAR
+ return symbol;
+}
+
+}}
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/RangeCoder/RangeCoder.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/RangeCoder/RangeCoder.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/RangeCoder/RangeCoder.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/RangeCoder/RangeCoder.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,205 @@
+// Compress/RangeCoder/RangeCoder.h
+
+#ifndef __COMPRESS_RANGECODER_H
+#define __COMPRESS_RANGECODER_H
+
+#include "../../Common/InBuffer.h"
+#include "../../Common/OutBuffer.h"
+
+namespace NCompress {
+namespace NRangeCoder {
+
+const int kNumTopBits = 24;
+const UInt32 kTopValue = (1 << kNumTopBits);
+
+class CEncoder
+{
+ UInt32 _cacheSize;
+ Byte _cache;
+public:
+ UInt64 Low;
+ UInt32 Range;
+ COutBuffer Stream;
+ bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); }
+
+ void SetStream(ISequentialOutStream *stream) { Stream.SetStream(stream); }
+ void Init()
+ {
+ Stream.Init();
+ Low = 0;
+ Range = 0xFFFFFFFF;
+ _cacheSize = 1;
+ _cache = 0;
+ }
+
+ void FlushData()
+ {
+ // Low += 1;
+ for(int i = 0; i < 5; i++)
+ ShiftLow();
+ }
+
+ HRESULT FlushStream() { return Stream.Flush(); }
+
+ void ReleaseStream() { Stream.ReleaseStream(); }
+
+ void Encode(UInt32 start, UInt32 size, UInt32 total)
+ {
+ Low += start * (Range /= total);
+ Range *= size;
+ while (Range < kTopValue)
+ {
+ Range <<= 8;
+ ShiftLow();
+ }
+ }
+
+ void ShiftLow()
+ {
+ if ((UInt32)Low < (UInt32)0xFF000000 || (int)(Low >> 32) != 0)
+ {
+ Byte temp = _cache;
+ do
+ {
+ Stream.WriteByte((Byte)(temp + (Byte)(Low >> 32)));
+ temp = 0xFF;
+ }
+ while(--_cacheSize != 0);
+ _cache = (Byte)((UInt32)Low >> 24);
+ }
+ _cacheSize++;
+ Low = (UInt32)Low << 8;
+ }
+
+ void EncodeDirectBits(UInt32 value, int numTotalBits)
+ {
+ for (int i = numTotalBits - 1; i >= 0; i--)
+ {
+ Range >>= 1;
+ if (((value >> i) & 1) == 1)
+ Low += Range;
+ if (Range < kTopValue)
+ {
+ Range <<= 8;
+ ShiftLow();
+ }
+ }
+ }
+
+ void EncodeBit(UInt32 size0, UInt32 numTotalBits, UInt32 symbol)
+ {
+ UInt32 newBound = (Range >> numTotalBits) * size0;
+ if (symbol == 0)
+ Range = newBound;
+ else
+ {
+ Low += newBound;
+ Range -= newBound;
+ }
+ while (Range < kTopValue)
+ {
+ Range <<= 8;
+ ShiftLow();
+ }
+ }
+
+ UInt64 GetProcessedSize() { return Stream.GetProcessedSize() + _cacheSize + 4; }
+};
+
+class CDecoder
+{
+public:
+ CInBuffer Stream;
+ UInt32 Range;
+ UInt32 Code;
+ bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); }
+
+ void Normalize()
+ {
+ while (Range < kTopValue)
+ {
+ Code = (Code << 8) | Stream.ReadByte();
+ Range <<= 8;
+ }
+ }
+
+ void SetStream(ISequentialInStream *stream) { Stream.SetStream(stream); }
+ void Init()
+ {
+ Stream.Init();
+ Code = 0;
+ Range = 0xFFFFFFFF;
+ for(int i = 0; i < 5; i++)
+ Code = (Code << 8) | Stream.ReadByte();
+ }
+
+ void ReleaseStream() { Stream.ReleaseStream(); }
+
+ UInt32 GetThreshold(UInt32 total)
+ {
+ return (Code) / ( Range /= total);
+ }
+
+ void Decode(UInt32 start, UInt32 size)
+ {
+ Code -= start * Range;
+ Range *= size;
+ Normalize();
+ }
+
+ UInt32 DecodeDirectBits(int numTotalBits)
+ {
+ UInt32 range = Range;
+ UInt32 code = Code;
+ UInt32 result = 0;
+ for (int i = numTotalBits; i != 0; i--)
+ {
+ range >>= 1;
+ /*
+ result <<= 1;
+ if (code >= range)
+ {
+ code -= range;
+ result |= 1;
+ }
+ */
+ UInt32 t = (code - range) >> 31;
+ code -= range & (t - 1);
+ result = (result << 1) | (1 - t);
+
+ if (range < kTopValue)
+ {
+ code = (code << 8) | Stream.ReadByte();
+ range <<= 8;
+ }
+ }
+ Range = range;
+ Code = code;
+ return result;
+ }
+
+ UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits)
+ {
+ UInt32 newBound = (Range >> numTotalBits) * size0;
+ UInt32 symbol;
+ if (Code < newBound)
+ {
+ symbol = 0;
+ Range = newBound;
+ }
+ else
+ {
+ symbol = 1;
+ Code -= newBound;
+ Range -= newBound;
+ }
+ Normalize();
+ return symbol;
+ }
+
+ UInt64 GetProcessedSize() {return Stream.GetProcessedSize(); }
+};
+
+}}
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/RangeCoder/RangeCoderOpt.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/RangeCoder/RangeCoderOpt.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/RangeCoder/RangeCoderOpt.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/RangeCoder/RangeCoderOpt.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,31 @@
+// Compress/RangeCoder/RangeCoderOpt.h
+
+#ifndef __COMPRESS_RANGECODER_OPT_H
+#define __COMPRESS_RANGECODER_OPT_H
+
+#define RC_INIT_VAR \
+ UInt32 range = rangeDecoder->Range; \
+ UInt32 code = rangeDecoder->Code;
+
+#define RC_FLUSH_VAR \
+ rangeDecoder->Range = range; \
+ rangeDecoder->Code = code;
+
+#define RC_NORMALIZE \
+ if (range < NCompress::NRangeCoder::kTopValue) \
+ { code = (code << 8) | rangeDecoder->Stream.ReadByte(); range <<= 8; }
+
+#define RC_GETBIT2(numMoveBits, prob, mi, A0, A1) \
+ { UInt32 bound = (range >> NCompress::NRangeCoder::kNumBitModelTotalBits) * prob; \
+ if (code < bound) \
+ { A0; range = bound; \
+ prob += (NCompress::NRangeCoder::kBitModelTotal - prob) >> numMoveBits; \
+ mi <<= 1; } \
+ else \
+ { A1; range -= bound; code -= bound; prob -= (prob) >> numMoveBits; \
+ mi = (mi + mi) + 1; }} \
+ RC_NORMALIZE
+
+#define RC_GETBIT(numMoveBits, prob, mi) RC_GETBIT2(numMoveBits, prob, mi, ; , ;)
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/RangeCoder/StdAfx.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/RangeCoder/StdAfx.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/Compress/RangeCoder/StdAfx.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/Compress/RangeCoder/StdAfx.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,6 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/ICoder.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/ICoder.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/ICoder.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/ICoder.h 2016-08-25 09:06:03.223530354 -0400
@@ -0,0 +1,156 @@
+// ICoder.h
+
+#ifndef __ICODER_H
+#define __ICODER_H
+
+#include "IStream.h"
+
+// "23170F69-40C1-278A-0000-000400xx0000"
+#define CODER_INTERFACE(i, x) \
+DEFINE_GUID(IID_ ## i, \
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x04, 0x00, x, 0x00, 0x00); \
+struct i: public IUnknown
+
+CODER_INTERFACE(ICompressProgressInfo, 0x04)
+{
+ STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize) PURE;
+};
+
+CODER_INTERFACE(ICompressCoder, 0x05)
+{
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UInt64 *inSize,
+ const UInt64 *outSize,
+ ICompressProgressInfo *progress) PURE;
+};
+
+CODER_INTERFACE(ICompressCoder2, 0x18)
+{
+ STDMETHOD(Code)(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 **outSizes,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress) PURE;
+};
+
+namespace NCoderPropID
+{
+ enum EEnum
+ {
+ kDictionarySize = 0x400,
+ kUsedMemorySize,
+ kOrder,
+ kPosStateBits = 0x440,
+ kLitContextBits,
+ kLitPosBits,
+ kNumFastBytes = 0x450,
+ kMatchFinder,
+ kNumPasses = 0x460,
+ kAlgorithm = 0x470,
+ kMultiThread = 0x480,
+ kEndMarker = 0x490
+ };
+}
+
+CODER_INTERFACE(ICompressSetCoderProperties, 0x20)
+{
+ STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
+ const PROPVARIANT *properties, UInt32 numProperties) PURE;
+};
+
+/*
+CODER_INTERFACE(ICompressSetCoderProperties, 0x21)
+{
+ STDMETHOD(SetDecoderProperties)(ISequentialInStream *inStream) PURE;
+};
+*/
+
+CODER_INTERFACE(ICompressSetDecoderProperties2, 0x22)
+{
+ STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size) PURE;
+};
+
+CODER_INTERFACE(ICompressWriteCoderProperties, 0x23)
+{
+ STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStreams) PURE;
+};
+
+CODER_INTERFACE(ICompressGetInStreamProcessedSize, 0x24)
+{
+ STDMETHOD(GetInStreamProcessedSize)(UInt64 *value) PURE;
+};
+
+CODER_INTERFACE(ICompressGetSubStreamSize, 0x30)
+{
+ STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value) PURE;
+};
+
+CODER_INTERFACE(ICompressSetInStream, 0x31)
+{
+ STDMETHOD(SetInStream)(ISequentialInStream *inStream) PURE;
+ STDMETHOD(ReleaseInStream)() PURE;
+};
+
+CODER_INTERFACE(ICompressSetOutStream, 0x32)
+{
+ STDMETHOD(SetOutStream)(ISequentialOutStream *outStream) PURE;
+ STDMETHOD(ReleaseOutStream)() PURE;
+};
+
+CODER_INTERFACE(ICompressSetInStreamSize, 0x33)
+{
+ STDMETHOD(SetInStreamSize)(const UInt64 *inSize) PURE;
+};
+
+CODER_INTERFACE(ICompressSetOutStreamSize, 0x34)
+{
+ STDMETHOD(SetOutStreamSize)(const UInt64 *outSize) PURE;
+};
+
+CODER_INTERFACE(ICompressFilter, 0x40)
+{
+ STDMETHOD(Init)() PURE;
+ STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size) PURE;
+ // Filter return outSize (UInt32)
+ // if (outSize <= size): Filter have converted outSize bytes
+ // if (outSize > size): Filter have not converted anything.
+ // and it needs at least outSize bytes to convert one block
+ // (it's for crypto block algorithms).
+};
+
+CODER_INTERFACE(ICryptoProperties, 0x80)
+{
+ STDMETHOD(SetKey)(const Byte *data, UInt32 size) PURE;
+ STDMETHOD(SetInitVector)(const Byte *data, UInt32 size) PURE;
+};
+
+CODER_INTERFACE(ICryptoSetPassword, 0x90)
+{
+ STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size) PURE;
+};
+
+CODER_INTERFACE(ICryptoSetCRC, 0xA0)
+{
+ STDMETHOD(CryptoSetCRC)(UInt32 crc) PURE;
+};
+
+//////////////////////
+// It's for DLL file
+namespace NMethodPropID
+{
+ enum EEnum
+ {
+ kID,
+ kName,
+ kDecoder,
+ kEncoder,
+ kInStreams,
+ kOutStreams,
+ kDescription
+ };
+}
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/7zip/IStream.h squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/IStream.h
--- squashfs-tools/LZMA/lzmadaptive/C/7zip/IStream.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/7zip/IStream.h 2016-08-25 09:06:03.227530354 -0400
@@ -0,0 +1,62 @@
+// IStream.h
+
+#ifndef __ISTREAM_H
+#define __ISTREAM_H
+
+#include "../Common/MyUnknown.h"
+#include "../Common/Types.h"
+
+// "23170F69-40C1-278A-0000-000300xx0000"
+
+#define STREAM_INTERFACE_SUB(i, b, x) \
+DEFINE_GUID(IID_ ## i, \
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x03, 0x00, x, 0x00, 0x00); \
+struct i: public b
+
+#define STREAM_INTERFACE(i, x) STREAM_INTERFACE_SUB(i, IUnknown, x)
+
+STREAM_INTERFACE(ISequentialInStream, 0x01)
+{
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) PURE;
+ /*
+ Out: if size != 0, return_value = S_OK and (*processedSize == 0),
+ then there are no more bytes in stream.
+ if (size > 0) && there are bytes in stream,
+ this function must read at least 1 byte.
+ This function is allowed to read less than number of remaining bytes in stream.
+ You must call Read function in loop, if you need exact amount of data
+ */
+};
+
+STREAM_INTERFACE(ISequentialOutStream, 0x02)
+{
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize) PURE;
+ /*
+ if (size > 0) this function must write at least 1 byte.
+ This function is allowed to write less than "size".
+ You must call Write function in loop, if you need to write exact amount of data
+ */
+};
+
+STREAM_INTERFACE_SUB(IInStream, ISequentialInStream, 0x03)
+{
+ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE;
+};
+
+STREAM_INTERFACE_SUB(IOutStream, ISequentialOutStream, 0x04)
+{
+ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE;
+ STDMETHOD(SetSize)(Int64 newSize) PURE;
+};
+
+STREAM_INTERFACE(IStreamGetSize, 0x06)
+{
+ STDMETHOD(GetSize)(UInt64 *size) PURE;
+};
+
+STREAM_INTERFACE(IOutStreamFlush, 0x07)
+{
+ STDMETHOD(Flush)() PURE;
+};
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/Common/Alloc.cpp squashfs-tools-patched/LZMA/lzmadaptive/C/Common/Alloc.cpp
--- squashfs-tools/LZMA/lzmadaptive/C/Common/Alloc.cpp 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/Common/Alloc.cpp 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,118 @@
+// Common/Alloc.cpp
+
+#include "StdAfx.h"
+
+#ifdef _WIN32
+#include "MyWindows.h"
+#else
+#include <stdlib.h>
+#endif
+
+#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) throw()
+{
+ if (size == 0)
+ return 0;
+ #ifdef _SZ_ALLOC_DEBUG
+ fprintf(stderr, "\nAlloc %10d bytes; count = %10d", size, g_allocCount++);
+ #endif
+ return ::malloc(size);
+}
+
+void MyFree(void *address) throw()
+{
+ #ifdef _SZ_ALLOC_DEBUG
+ if (address != 0)
+ fprintf(stderr, "\nFree; count = %10d", --g_allocCount);
+ #endif
+
+ ::free(address);
+}
+
+#ifdef _WIN32
+
+void *MidAlloc(size_t size) throw()
+{
+ 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) throw()
+{
+ #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);
+}
+
+static SIZE_T g_LargePageSize =
+ #ifdef _WIN64
+ (1 << 21);
+ #else
+ (1 << 22);
+ #endif
+
+typedef SIZE_T (WINAPI *GetLargePageMinimumP)();
+
+bool SetLargePageSize()
+{
+ GetLargePageMinimumP largePageMinimum = (GetLargePageMinimumP)
+ ::GetProcAddress(::GetModuleHandle(TEXT("kernel32.dll")), "GetLargePageMinimum");
+ if (largePageMinimum == 0)
+ return false;
+ SIZE_T size = largePageMinimum();
+ if (size == 0 || (size & (size - 1)) != 0)
+ return false;
+ g_LargePageSize = size;
+ return true;
+}
+
+
+void *BigAlloc(size_t size) throw()
+{
+ if (size == 0)
+ return 0;
+ #ifdef _SZ_ALLOC_DEBUG
+ fprintf(stderr, "\nAlloc_Big %10d bytes; count = %10d", size, g_allocCountBig++);
+ #endif
+
+ if (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;
+ }
+ return ::VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);
+}
+
+void BigFree(void *address) throw()
+{
+ #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
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/Common/Alloc.h squashfs-tools-patched/LZMA/lzmadaptive/C/Common/Alloc.h
--- squashfs-tools/LZMA/lzmadaptive/C/Common/Alloc.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/Common/Alloc.h 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,29 @@
+// Common/Alloc.h
+
+#ifndef __COMMON_ALLOC_H
+#define __COMMON_ALLOC_H
+
+#include <stddef.h>
+
+void *MyAlloc(size_t size) throw();
+void MyFree(void *address) throw();
+
+#ifdef _WIN32
+
+bool SetLargePageSize();
+
+void *MidAlloc(size_t size) throw();
+void MidFree(void *address) throw();
+void *BigAlloc(size_t size) throw();
+void BigFree(void *address) throw();
+
+#else
+
+#define MidAlloc(size) MyAlloc(size)
+#define MidFree(address) MyFree(address)
+#define BigAlloc(size) MyAlloc(size)
+#define BigFree(address) MyFree(address)
+
+#endif
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/Common/C_FileIO.cpp squashfs-tools-patched/LZMA/lzmadaptive/C/Common/C_FileIO.cpp
--- squashfs-tools/LZMA/lzmadaptive/C/Common/C_FileIO.cpp 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/Common/C_FileIO.cpp 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,78 @@
+// Common/C_FileIO.h
+
+#include "C_FileIO.h"
+
+#include <fcntl.h>
+#include <unistd.h>
+
+namespace NC {
+namespace NFile {
+namespace NIO {
+
+bool CFileBase::OpenBinary(const char *name, int flags)
+{
+ #ifdef O_BINARY
+ flags |= O_BINARY;
+ #endif
+ Close();
+ _handle = ::open(name, flags, 0666);
+ return _handle != -1;
+}
+
+bool CFileBase::Close()
+{
+ if(_handle == -1)
+ return true;
+ if (close(_handle) != 0)
+ return false;
+ _handle = -1;
+ return true;
+}
+
+bool CFileBase::GetLength(UInt64 &length) const
+{
+ off_t curPos = Seek(0, SEEK_CUR);
+ off_t lengthTemp = Seek(0, SEEK_END);
+ Seek(curPos, SEEK_SET);
+ length = (UInt64)lengthTemp;
+ return true;
+}
+
+off_t CFileBase::Seek(off_t distanceToMove, int moveMethod) const
+{
+ return ::lseek(_handle, distanceToMove, moveMethod);
+}
+
+/////////////////////////
+// CInFile
+
+bool CInFile::Open(const char *name)
+{
+ return CFileBase::OpenBinary(name, O_RDONLY);
+}
+
+ssize_t CInFile::Read(void *data, size_t size)
+{
+ return read(_handle, data, size);
+}
+
+/////////////////////////
+// COutFile
+
+bool COutFile::Create(const char *name, bool createAlways)
+{
+ if (createAlways)
+ {
+ Close();
+ _handle = ::creat(name, 0666);
+ return _handle != -1;
+ }
+ return OpenBinary(name, O_CREAT | O_EXCL | O_WRONLY);
+}
+
+ssize_t COutFile::Write(const void *data, size_t size)
+{
+ return write(_handle, data, size);
+}
+
+}}}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/Common/C_FileIO.h squashfs-tools-patched/LZMA/lzmadaptive/C/Common/C_FileIO.h
--- squashfs-tools/LZMA/lzmadaptive/C/Common/C_FileIO.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/Common/C_FileIO.h 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,45 @@
+// Common/C_FileIO.h
+
+#ifndef __COMMON_C_FILEIO_H
+#define __COMMON_C_FILEIO_H
+
+#include <stdio.h>
+#include <sys/types.h>
+
+#include "Types.h"
+#include "MyWindows.h"
+
+namespace NC {
+namespace NFile {
+namespace NIO {
+
+class CFileBase
+{
+protected:
+ int _handle;
+ bool OpenBinary(const char *name, int flags);
+public:
+ CFileBase(): _handle(-1) {};
+ ~CFileBase() { Close(); }
+ bool Close();
+ bool GetLength(UInt64 &length) const;
+ off_t Seek(off_t distanceToMove, int moveMethod) const;
+};
+
+class CInFile: public CFileBase
+{
+public:
+ bool Open(const char *name);
+ ssize_t Read(void *data, size_t size);
+};
+
+class COutFile: public CFileBase
+{
+public:
+ bool Create(const char *name, bool createAlways);
+ ssize_t Write(const void *data, size_t size);
+};
+
+}}}
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/Common/CommandLineParser.cpp squashfs-tools-patched/LZMA/lzmadaptive/C/Common/CommandLineParser.cpp
--- squashfs-tools/LZMA/lzmadaptive/C/Common/CommandLineParser.cpp 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/Common/CommandLineParser.cpp 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,263 @@
+// CommandLineParser.cpp
+
+#include "StdAfx.h"
+
+#include "CommandLineParser.h"
+
+namespace NCommandLineParser {
+
+void SplitCommandLine(const UString &src, UString &dest1, UString &dest2)
+{
+ dest1.Empty();
+ dest2.Empty();
+ bool quoteMode = false;
+ int i;
+ for (i = 0; i < src.Length(); i++)
+ {
+ wchar_t c = src[i];
+ if (c == L'\"')
+ quoteMode = !quoteMode;
+ else if (c == L' ' && !quoteMode)
+ {
+ i++;
+ break;
+ }
+ else
+ dest1 += c;
+ }
+ dest2 = src.Mid(i);
+}
+
+void SplitCommandLine(const UString &s, UStringVector &parts)
+{
+ UString sTemp = s;
+ sTemp.Trim();
+ parts.Clear();
+ while (true)
+ {
+ UString s1, s2;
+ SplitCommandLine(sTemp, s1, s2);
+ // s1.Trim();
+ // s2.Trim();
+ if (!s1.IsEmpty())
+ parts.Add(s1);
+ if (s2.IsEmpty())
+ return;
+ sTemp = s2;
+ }
+}
+
+
+static const wchar_t kSwitchID1 = '-';
+// static const wchar_t kSwitchID2 = '/';
+
+static const wchar_t kSwitchMinus = '-';
+static const wchar_t *kStopSwitchParsing = L"--";
+
+static bool IsItSwitchChar(wchar_t c)
+{
+ return (c == kSwitchID1 /*|| c == kSwitchID2 */);
+}
+
+CParser::CParser(int numSwitches):
+ _numSwitches(numSwitches)
+{
+ _switches = new CSwitchResult[_numSwitches];
+}
+
+CParser::~CParser()
+{
+ delete []_switches;
+}
+
+void CParser::ParseStrings(const CSwitchForm *switchForms,
+ const UStringVector &commandStrings)
+{
+ int numCommandStrings = commandStrings.Size();
+ bool stopSwitch = false;
+ for (int i = 0; i < numCommandStrings; i++)
+ {
+ const UString &s = commandStrings[i];
+ if (stopSwitch)
+ NonSwitchStrings.Add(s);
+ else
+ if (s == kStopSwitchParsing)
+ stopSwitch = true;
+ else
+ if (!ParseString(s, switchForms))
+ NonSwitchStrings.Add(s);
+ }
+}
+
+// if string contains switch then function updates switch structures
+// out: (string is a switch)
+bool CParser::ParseString(const UString &s, const CSwitchForm *switchForms)
+{
+ int len = s.Length();
+ if (len == 0)
+ return false;
+ int pos = 0;
+ if (!IsItSwitchChar(s[pos]))
+ return false;
+ while(pos < len)
+ {
+ if (IsItSwitchChar(s[pos]))
+ pos++;
+ const int kNoLen = -1;
+ int matchedSwitchIndex = 0; // GCC Warning
+ int maxLen = kNoLen;
+ for(int switchIndex = 0; switchIndex < _numSwitches; switchIndex++)
+ {
+ int switchLen = MyStringLen(switchForms[switchIndex].IDString);
+ if (switchLen <= maxLen || pos + switchLen > len)
+ continue;
+
+ UString temp = s + pos;
+ temp = temp.Left(switchLen);
+ if(temp.CompareNoCase(switchForms[switchIndex].IDString) == 0)
+ // if(_strnicmp(switchForms[switchIndex].IDString, LPCSTR(s) + pos, switchLen) == 0)
+ {
+ matchedSwitchIndex = switchIndex;
+ maxLen = switchLen;
+ }
+ }
+ if (maxLen == kNoLen)
+ throw "maxLen == kNoLen";
+ CSwitchResult &matchedSwitch = _switches[matchedSwitchIndex];
+ const CSwitchForm &switchForm = switchForms[matchedSwitchIndex];
+ if ((!switchForm.Multi) && matchedSwitch.ThereIs)
+ throw "switch must be single";
+ matchedSwitch.ThereIs = true;
+ pos += maxLen;
+ int tailSize = len - pos;
+ NSwitchType::EEnum type = switchForm.Type;
+ switch(type)
+ {
+ case NSwitchType::kPostMinus:
+ {
+ if (tailSize == 0)
+ matchedSwitch.WithMinus = false;
+ else
+ {
+ matchedSwitch.WithMinus = (s[pos] == kSwitchMinus);
+ if (matchedSwitch.WithMinus)
+ pos++;
+ }
+ break;
+ }
+ case NSwitchType::kPostChar:
+ {
+ if (tailSize < switchForm.MinLen)
+ throw "switch is not full";
+ UString set = switchForm.PostCharSet;
+ const int kEmptyCharValue = -1;
+ if (tailSize == 0)
+ matchedSwitch.PostCharIndex = kEmptyCharValue;
+ else
+ {
+ int index = set.Find(s[pos]);
+ if (index < 0)
+ matchedSwitch.PostCharIndex = kEmptyCharValue;
+ else
+ {
+ matchedSwitch.PostCharIndex = index;
+ pos++;
+ }
+ }
+ break;
+ }
+ case NSwitchType::kLimitedPostString:
+ case NSwitchType::kUnLimitedPostString:
+ {
+ int minLen = switchForm.MinLen;
+ if (tailSize < minLen)
+ throw "switch is not full";
+ if (type == NSwitchType::kUnLimitedPostString)
+ {
+ matchedSwitch.PostStrings.Add(s.Mid(pos));
+ return true;
+ }
+ int maxLen = switchForm.MaxLen;
+ UString stringSwitch = s.Mid(pos, minLen);
+ pos += minLen;
+ for(int i = minLen; i < maxLen && pos < len; i++, pos++)
+ {
+ wchar_t c = s[pos];
+ if (IsItSwitchChar(c))
+ break;
+ stringSwitch += c;
+ }
+ matchedSwitch.PostStrings.Add(stringSwitch);
+ break;
+ }
+ case NSwitchType::kSimple:
+ break;
+ }
+ }
+ return true;
+}
+
+const CSwitchResult& CParser::operator[](size_t index) const
+{
+ return _switches[index];
+}
+
+/////////////////////////////////
+// Command parsing procedures
+
+int ParseCommand(int numCommandForms, const CCommandForm *commandForms,
+ const UString &commandString, UString &postString)
+{
+ for(int i = 0; i < numCommandForms; i++)
+ {
+ const UString id = commandForms[i].IDString;
+ if (commandForms[i].PostStringMode)
+ {
+ if(commandString.Find(id) == 0)
+ {
+ postString = commandString.Mid(id.Length());
+ return i;
+ }
+ }
+ else
+ if (commandString == id)
+ {
+ postString.Empty();
+ return i;
+ }
+ }
+ return -1;
+}
+
+bool ParseSubCharsCommand(int numForms, const CCommandSubCharsSet *forms,
+ const UString &commandString, CIntVector &indices)
+{
+ indices.Clear();
+ int numUsedChars = 0;
+ for(int i = 0; i < numForms; i++)
+ {
+ const CCommandSubCharsSet &set = forms[i];
+ int currentIndex = -1;
+ int len = MyStringLen(set.Chars);
+ for(int j = 0; j < len; j++)
+ {
+ wchar_t c = set.Chars[j];
+ int newIndex = commandString.Find(c);
+ if (newIndex >= 0)
+ {
+ if (currentIndex >= 0)
+ return false;
+ if (commandString.Find(c, newIndex + 1) >= 0)
+ return false;
+ currentIndex = j;
+ numUsedChars++;
+ }
+ }
+ if(currentIndex == -1 && !set.EmptyAllowed)
+ return false;
+ indices.Add(currentIndex);
+ }
+ return (numUsedChars == commandString.Length());
+}
+
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/Common/CommandLineParser.h squashfs-tools-patched/LZMA/lzmadaptive/C/Common/CommandLineParser.h
--- squashfs-tools/LZMA/lzmadaptive/C/Common/CommandLineParser.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/Common/CommandLineParser.h 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,82 @@
+// Common/CommandLineParser.h
+
+#ifndef __COMMON_COMMANDLINEPARSER_H
+#define __COMMON_COMMANDLINEPARSER_H
+
+#include "Common/String.h"
+
+namespace NCommandLineParser {
+
+void SplitCommandLine(const UString &src, UString &dest1, UString &dest2);
+void SplitCommandLine(const UString &s, UStringVector &parts);
+
+namespace NSwitchType {
+ enum EEnum
+ {
+ kSimple,
+ kPostMinus,
+ kLimitedPostString,
+ kUnLimitedPostString,
+ kPostChar
+ };
+}
+
+struct CSwitchForm
+{
+ const wchar_t *IDString;
+ NSwitchType::EEnum Type;
+ bool Multi;
+ int MinLen;
+ int MaxLen;
+ const wchar_t *PostCharSet;
+};
+
+struct CSwitchResult
+{
+ bool ThereIs;
+ bool WithMinus;
+ UStringVector PostStrings;
+ int PostCharIndex;
+ CSwitchResult(): ThereIs(false) {};
+};
+
+class CParser
+{
+ int _numSwitches;
+ CSwitchResult *_switches;
+ bool ParseString(const UString &s, const CSwitchForm *switchForms);
+public:
+ UStringVector NonSwitchStrings;
+ CParser(int numSwitches);
+ ~CParser();
+ void ParseStrings(const CSwitchForm *switchForms,
+ const UStringVector &commandStrings);
+ const CSwitchResult& operator[](size_t index) const;
+};
+
+/////////////////////////////////
+// Command parsing procedures
+
+struct CCommandForm
+{
+ wchar_t *IDString;
+ bool PostStringMode;
+};
+
+// Returns: Index of form and postString; -1, if there is no match
+int ParseCommand(int numCommandForms, const CCommandForm *commandForms,
+ const UString &commandString, UString &postString);
+
+struct CCommandSubCharsSet
+{
+ wchar_t *Chars;
+ bool EmptyAllowed;
+};
+
+// Returns: indices of finded chars; -1 if there is no match
+bool ParseSubCharsCommand(int numForms, const CCommandSubCharsSet *forms,
+ const UString &commandString, CIntVector &indices);
+
+}
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/Common/ComTry.h squashfs-tools-patched/LZMA/lzmadaptive/C/Common/ComTry.h
--- squashfs-tools/LZMA/lzmadaptive/C/Common/ComTry.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/Common/ComTry.h 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,17 @@
+// ComTry.h
+
+#ifndef __COM_TRY_H
+#define __COM_TRY_H
+
+#include "MyWindows.h"
+// #include "Exception.h"
+// #include "NewHandler.h"
+
+#define COM_TRY_BEGIN try {
+#define COM_TRY_END } catch(...) { return E_OUTOFMEMORY; }
+
+ // catch(const CNewException &) { return E_OUTOFMEMORY; }\
+ // catch(const CSystemException &e) { return e.ErrorCode; }\
+ // catch(...) { return E_FAIL; }
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/Common/CRC.cpp squashfs-tools-patched/LZMA/lzmadaptive/C/Common/CRC.cpp
--- squashfs-tools/LZMA/lzmadaptive/C/Common/CRC.cpp 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/Common/CRC.cpp 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,61 @@
+// Common/CRC.cpp
+
+#include "StdAfx.h"
+
+#include "CRC.h"
+
+static const UInt32 kCRCPoly = 0xEDB88320;
+
+UInt32 CCRC::Table[256];
+
+void CCRC::InitTable()
+{
+ for (UInt32 i = 0; i < 256; i++)
+ {
+ UInt32 r = i;
+ for (int j = 0; j < 8; j++)
+ if (r & 1)
+ r = (r >> 1) ^ kCRCPoly;
+ else
+ r >>= 1;
+ CCRC::Table[i] = r;
+ }
+}
+
+class CCRCTableInit
+{
+public:
+ CCRCTableInit() { CCRC::InitTable(); }
+} g_CRCTableInit;
+
+void CCRC::UpdateByte(Byte b)
+{
+ _value = Table[((Byte)(_value)) ^ b] ^ (_value >> 8);
+}
+
+void CCRC::UpdateUInt16(UInt16 v)
+{
+ UpdateByte(Byte(v));
+ UpdateByte(Byte(v >> 8));
+}
+
+void CCRC::UpdateUInt32(UInt32 v)
+{
+ for (int i = 0; i < 4; i++)
+ UpdateByte((Byte)(v >> (8 * i)));
+}
+
+void CCRC::UpdateUInt64(UInt64 v)
+{
+ for (int i = 0; i < 8; i++)
+ UpdateByte((Byte)(v >> (8 * i)));
+}
+
+void CCRC::Update(const void *data, size_t size)
+{
+ UInt32 v = _value;
+ const Byte *p = (const Byte *)data;
+ for (; size > 0 ; size--, p++)
+ v = Table[((Byte)(v)) ^ *p] ^ (v >> 8);
+ _value = v;
+}
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/Common/CRC.h squashfs-tools-patched/LZMA/lzmadaptive/C/Common/CRC.h
--- squashfs-tools/LZMA/lzmadaptive/C/Common/CRC.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/Common/CRC.h 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,36 @@
+// Common/CRC.h
+
+#ifndef __COMMON_CRC_H
+#define __COMMON_CRC_H
+
+#include <stddef.h>
+#include "Types.h"
+
+class CCRC
+{
+ UInt32 _value;
+public:
+ static UInt32 Table[256];
+ static void InitTable();
+
+ CCRC(): _value(0xFFFFFFFF){};
+ void Init() { _value = 0xFFFFFFFF; }
+ void UpdateByte(Byte v);
+ void UpdateUInt16(UInt16 v);
+ void UpdateUInt32(UInt32 v);
+ void UpdateUInt64(UInt64 v);
+ void Update(const void *data, size_t size);
+ UInt32 GetDigest() const { return _value ^ 0xFFFFFFFF; }
+ static UInt32 CalculateDigest(const void *data, size_t size)
+ {
+ CCRC crc;
+ crc.Update(data, size);
+ return crc.GetDigest();
+ }
+ static bool VerifyDigest(UInt32 digest, const void *data, size_t size)
+ {
+ return (CalculateDigest(data, size) == digest);
+ }
+};
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/Common/Defs.h squashfs-tools-patched/LZMA/lzmadaptive/C/Common/Defs.h
--- squashfs-tools/LZMA/lzmadaptive/C/Common/Defs.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/Common/Defs.h 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,20 @@
+// Common/Defs.h
+
+#ifndef __COMMON_DEFS_H
+#define __COMMON_DEFS_H
+
+template <class T> inline T MyMin(T a, T b)
+ { return a < b ? a : b; }
+template <class T> inline T MyMax(T a, T b)
+ { return a > b ? a : b; }
+
+template <class T> inline int MyCompare(T a, T b)
+ { return a < b ? -1 : (a == b ? 0 : 1); }
+
+inline int BoolToInt(bool value)
+ { return (value ? 1: 0); }
+
+inline bool IntToBool(int value)
+ { return (value != 0); }
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/Common/MyCom.h squashfs-tools-patched/LZMA/lzmadaptive/C/Common/MyCom.h
--- squashfs-tools/LZMA/lzmadaptive/C/Common/MyCom.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/Common/MyCom.h 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,203 @@
+// MyCom.h
+
+#ifndef __MYCOM_H
+#define __MYCOM_H
+
+#include "MyWindows.h"
+
+#define RINOK(x) { HRESULT __result_ = (x); if(__result_ != S_OK) return __result_; }
+
+template <class T>
+class CMyComPtr
+{
+ T* _p;
+public:
+ // typedef T _PtrClass;
+ CMyComPtr() { _p = NULL;}
+ CMyComPtr(T* p) {if ((_p = p) != NULL) p->AddRef(); }
+ CMyComPtr(const CMyComPtr<T>& lp)
+ {
+ if ((_p = lp._p) != NULL)
+ _p->AddRef();
+ }
+ ~CMyComPtr() { if (_p) _p->Release(); }
+ void Release() { if (_p) { _p->Release(); _p = NULL; } }
+ operator T*() const { return (T*)_p; }
+ // T& operator*() const { return *_p; }
+ T** operator&() { return &_p; }
+ T* operator->() const { return _p; }
+ T* operator=(T* p)
+ {
+ if (p != 0)
+ p->AddRef();
+ if (_p)
+ _p->Release();
+ _p = p;
+ return p;
+ }
+ T* operator=(const CMyComPtr<T>& lp) { return (*this = lp._p); }
+ bool operator!() const { return (_p == NULL); }
+ // bool operator==(T* pT) const { return _p == pT; }
+ // Compare two objects for equivalence
+ void Attach(T* p2)
+ {
+ Release();
+ _p = p2;
+ }
+ T* Detach()
+ {
+ T* pt = _p;
+ _p = NULL;
+ return pt;
+ }
+ #ifdef _WIN32
+ HRESULT CoCreateInstance(REFCLSID rclsid, REFIID iid, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
+ {
+ return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, (void**)&_p);
+ }
+ #endif
+ /*
+ HRESULT CoCreateInstance(LPCOLESTR szProgID, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
+ {
+ CLSID clsid;
+ HRESULT hr = CLSIDFromProgID(szProgID, &clsid);
+ ATLASSERT(_p == NULL);
+ if (SUCCEEDED(hr))
+ hr = ::CoCreateInstance(clsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&_p);
+ return hr;
+ }
+ */
+ template <class Q>
+ HRESULT QueryInterface(REFGUID iid, Q** pp) const
+ {
+ return _p->QueryInterface(iid, (void**)pp);
+ }
+};
+
+//////////////////////////////////////////////////////////
+
+class CMyComBSTR
+{
+public:
+ BSTR m_str;
+ CMyComBSTR() { m_str = NULL; }
+ CMyComBSTR(LPCOLESTR pSrc) { m_str = ::SysAllocString(pSrc); }
+ // CMyComBSTR(int nSize) { m_str = ::SysAllocStringLen(NULL, nSize); }
+ // CMyComBSTR(int nSize, LPCOLESTR sz) { m_str = ::SysAllocStringLen(sz, nSize); }
+ CMyComBSTR(const CMyComBSTR& src) { m_str = src.MyCopy(); }
+ /*
+ CMyComBSTR(REFGUID src)
+ {
+ LPOLESTR szGuid;
+ StringFromCLSID(src, &szGuid);
+ m_str = ::SysAllocString(szGuid);
+ CoTaskMemFree(szGuid);
+ }
+ */
+ ~CMyComBSTR() { ::SysFreeString(m_str); }
+ CMyComBSTR& operator=(const CMyComBSTR& src)
+ {
+ if (m_str != src.m_str)
+ {
+ if (m_str)
+ ::SysFreeString(m_str);
+ m_str = src.MyCopy();
+ }
+ return *this;
+ }
+ CMyComBSTR& operator=(LPCOLESTR pSrc)
+ {
+ ::SysFreeString(m_str);
+ m_str = ::SysAllocString(pSrc);
+ return *this;
+ }
+ unsigned int Length() const { return ::SysStringLen(m_str); }
+ operator BSTR() const { return m_str; }
+ BSTR* operator&() { return &m_str; }
+ BSTR MyCopy() const
+ {
+ int byteLen = ::SysStringByteLen(m_str);
+ BSTR res = ::SysAllocStringByteLen(NULL, byteLen);
+ memmove(res, m_str, byteLen);
+ return res;
+ }
+ void Attach(BSTR src) { m_str = src; }
+ BSTR Detach()
+ {
+ BSTR s = m_str;
+ m_str = NULL;
+ return s;
+ }
+ void Empty()
+ {
+ ::SysFreeString(m_str);
+ m_str = NULL;
+ }
+ bool operator!() const { return (m_str == NULL); }
+};
+
+
+//////////////////////////////////////////////////////////
+
+class CMyUnknownImp
+{
+public:
+ ULONG __m_RefCount;
+ CMyUnknownImp(): __m_RefCount(0) {}
+};
+
+#define MY_QUERYINTERFACE_BEGIN STDMETHOD(QueryInterface) \
+ (REFGUID iid, void **outObject) {
+
+#define MY_QUERYINTERFACE_ENTRY(i) if (iid == IID_ ## i) \
+ { *outObject = (void *)(i *)this; AddRef(); return S_OK; }
+
+#define MY_QUERYINTERFACE_END return E_NOINTERFACE; }
+
+#define MY_ADDREF_RELEASE \
+STDMETHOD_(ULONG, AddRef)() { return ++__m_RefCount; } \
+STDMETHOD_(ULONG, Release)() { if (--__m_RefCount != 0) \
+ return __m_RefCount; delete this; return 0; }
+
+#define MY_UNKNOWN_IMP_SPEC(i) \
+ MY_QUERYINTERFACE_BEGIN \
+ i \
+ MY_QUERYINTERFACE_END \
+ MY_ADDREF_RELEASE
+
+
+#define MY_UNKNOWN_IMP STDMETHOD(QueryInterface)(REFGUID, void **) { \
+ MY_QUERYINTERFACE_END \
+ MY_ADDREF_RELEASE
+
+#define MY_UNKNOWN_IMP1(i) MY_UNKNOWN_IMP_SPEC( \
+ MY_QUERYINTERFACE_ENTRY(i) \
+ )
+
+#define MY_UNKNOWN_IMP2(i1, i2) MY_UNKNOWN_IMP_SPEC( \
+ MY_QUERYINTERFACE_ENTRY(i1) \
+ MY_QUERYINTERFACE_ENTRY(i2) \
+ )
+
+#define MY_UNKNOWN_IMP3(i1, i2, i3) MY_UNKNOWN_IMP_SPEC( \
+ MY_QUERYINTERFACE_ENTRY(i1) \
+ MY_QUERYINTERFACE_ENTRY(i2) \
+ MY_QUERYINTERFACE_ENTRY(i3) \
+ )
+
+#define MY_UNKNOWN_IMP4(i1, i2, i3, i4) MY_UNKNOWN_IMP_SPEC( \
+ MY_QUERYINTERFACE_ENTRY(i1) \
+ MY_QUERYINTERFACE_ENTRY(i2) \
+ MY_QUERYINTERFACE_ENTRY(i3) \
+ MY_QUERYINTERFACE_ENTRY(i4) \
+ )
+
+#define MY_UNKNOWN_IMP5(i1, i2, i3, i4, i5) MY_UNKNOWN_IMP_SPEC( \
+ MY_QUERYINTERFACE_ENTRY(i1) \
+ MY_QUERYINTERFACE_ENTRY(i2) \
+ MY_QUERYINTERFACE_ENTRY(i3) \
+ MY_QUERYINTERFACE_ENTRY(i4) \
+ MY_QUERYINTERFACE_ENTRY(i5) \
+ )
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/Common/MyGuidDef.h squashfs-tools-patched/LZMA/lzmadaptive/C/Common/MyGuidDef.h
--- squashfs-tools/LZMA/lzmadaptive/C/Common/MyGuidDef.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/Common/MyGuidDef.h 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,54 @@
+// Common/MyGuidDef.h
+
+#ifndef GUID_DEFINED
+#define GUID_DEFINED
+
+#include "Types.h"
+
+typedef struct {
+ UInt32 Data1;
+ UInt16 Data2;
+ UInt16 Data3;
+ unsigned char Data4[8];
+} GUID;
+
+#ifdef __cplusplus
+#define REFGUID const GUID &
+#else
+#define REFGUID const GUID *
+#endif
+
+#define REFCLSID REFGUID
+#define REFIID REFGUID
+
+#ifdef __cplusplus
+inline bool operator==(REFGUID g1, REFGUID g2)
+{
+ for (int i = 0; i < (int)sizeof(g1); i++)
+ if (((unsigned char *)&g1)[i] != ((unsigned char *)&g2)[i])
+ return false;
+ return true;
+}
+inline bool operator!=(REFGUID g1, REFGUID g2) { return !(g1 == g2); }
+#endif
+
+#ifdef __cplusplus
+ #define MY_EXTERN_C extern "C"
+#else
+ #define MY_EXTERN_C extern
+#endif
+
+#endif // GUID_DEFINED
+
+
+#ifdef DEFINE_GUID
+#undef DEFINE_GUID
+#endif
+
+#ifdef INITGUID
+ #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
+ MY_EXTERN_C const GUID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
+#else
+ #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
+ MY_EXTERN_C const GUID name
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/Common/MyInitGuid.h squashfs-tools-patched/LZMA/lzmadaptive/C/Common/MyInitGuid.h
--- squashfs-tools/LZMA/lzmadaptive/C/Common/MyInitGuid.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/Common/MyInitGuid.h 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,13 @@
+// Common/MyInitGuid.h
+
+#ifndef __COMMON_MYINITGUID_H
+#define __COMMON_MYINITGUID_H
+
+#ifdef _WIN32
+#include <initguid.h>
+#else
+#define INITGUID
+#include "MyGuidDef.h"
+#endif
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/Common/MyUnknown.h squashfs-tools-patched/LZMA/lzmadaptive/C/Common/MyUnknown.h
--- squashfs-tools/LZMA/lzmadaptive/C/Common/MyUnknown.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/Common/MyUnknown.h 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,24 @@
+// MyUnknown.h
+
+#ifndef __MYUNKNOWN_H
+#define __MYUNKNOWN_H
+
+#ifdef _WIN32
+
+#ifdef _WIN32_WCE
+#if (_WIN32_WCE > 300)
+#include <basetyps.h>
+#else
+#define MIDL_INTERFACE(x) struct
+#endif
+#else
+#include <basetyps.h>
+#endif
+
+#include <unknwn.h>
+
+#else
+#include "MyWindows.h"
+#endif
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/Common/MyWindows.h squashfs-tools-patched/LZMA/lzmadaptive/C/Common/MyWindows.h
--- squashfs-tools/LZMA/lzmadaptive/C/Common/MyWindows.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/Common/MyWindows.h 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,183 @@
+// MyWindows.h
+
+#ifndef __MYWINDOWS_H
+#define __MYWINDOWS_H
+
+#ifdef _WIN32
+
+#include <windows.h>
+
+#else
+
+#include <stddef.h> // for wchar_t
+#include <string.h>
+
+#include "MyGuidDef.h"
+
+typedef char CHAR;
+typedef unsigned char UCHAR;
+typedef unsigned char BYTE;
+
+typedef short SHORT;
+typedef unsigned short USHORT;
+typedef unsigned short WORD;
+typedef short VARIANT_BOOL;
+
+typedef int INT;
+typedef Int32 INT32;
+typedef unsigned int UINT;
+typedef UInt32 UINT32;
+typedef INT32 LONG; // LONG, ULONG and DWORD must be 32-bit
+typedef UINT32 ULONG;
+typedef UINT32 DWORD;
+
+typedef Int64 LONGLONG;
+typedef UInt64 ULONGLONG;
+
+typedef struct LARGE_INTEGER { LONGLONG QuadPart; }LARGE_INTEGER;
+typedef struct _ULARGE_INTEGER { ULONGLONG QuadPart;} ULARGE_INTEGER;
+
+typedef const CHAR *LPCSTR;
+typedef CHAR TCHAR;
+typedef const TCHAR *LPCTSTR;
+typedef wchar_t WCHAR;
+typedef WCHAR OLECHAR;
+typedef const WCHAR *LPCWSTR;
+typedef OLECHAR *BSTR;
+typedef const OLECHAR *LPCOLESTR;
+typedef OLECHAR *LPOLESTR;
+
+typedef struct _FILETIME
+{
+ DWORD dwLowDateTime;
+ DWORD dwHighDateTime;
+}FILETIME;
+
+#define HRESULT LONG
+#define FAILED(Status) ((HRESULT)(Status)<0)
+typedef ULONG PROPID;
+typedef LONG SCODE;
+
+#define S_OK ((HRESULT)0x00000000L)
+#define S_FALSE ((HRESULT)0x00000001L)
+#define E_NOINTERFACE ((HRESULT)0x80004002L)
+#define E_ABORT ((HRESULT)0x80004004L)
+#define E_FAIL ((HRESULT)0x80004005L)
+#define STG_E_INVALIDFUNCTION ((HRESULT)0x80030001L)
+#define E_OUTOFMEMORY ((HRESULT)0x8007000EL)
+#define E_INVALIDARG ((HRESULT)0x80070057L)
+
+#ifdef _MSC_VER
+#define STDMETHODCALLTYPE __stdcall
+#else
+#define STDMETHODCALLTYPE
+#endif
+
+#define STDMETHOD_(t, f) virtual t STDMETHODCALLTYPE f
+#define STDMETHOD(f) STDMETHOD_(HRESULT, f)
+#define STDMETHODIMP_(type) type STDMETHODCALLTYPE
+#define STDMETHODIMP STDMETHODIMP_(HRESULT)
+
+#define PURE = 0
+
+#define MIDL_INTERFACE(x) struct
+
+struct IUnknown
+{
+ STDMETHOD(QueryInterface) (REFIID iid, void **outObject) PURE;
+ STDMETHOD_(ULONG, AddRef)() PURE;
+ STDMETHOD_(ULONG, Release)() PURE;
+};
+
+typedef IUnknown *LPUNKNOWN;
+
+#define VARIANT_TRUE ((VARIANT_BOOL)-1)
+#define VARIANT_FALSE ((VARIANT_BOOL)0)
+
+enum VARENUM
+{
+ VT_EMPTY = 0,
+ VT_NULL = 1,
+ VT_I2 = 2,
+ VT_I4 = 3,
+ VT_R4 = 4,
+ VT_R8 = 5,
+ VT_CY = 6,
+ VT_DATE = 7,
+ VT_BSTR = 8,
+ VT_DISPATCH = 9,
+ VT_ERROR = 10,
+ VT_BOOL = 11,
+ VT_VARIANT = 12,
+ VT_UNKNOWN = 13,
+ VT_DECIMAL = 14,
+ VT_I1 = 16,
+ VT_UI1 = 17,
+ VT_UI2 = 18,
+ VT_UI4 = 19,
+ VT_I8 = 20,
+ VT_UI8 = 21,
+ VT_INT = 22,
+ VT_UINT = 23,
+ VT_VOID = 24,
+ VT_HRESULT = 25,
+ VT_FILETIME = 64
+};
+
+typedef unsigned short VARTYPE;
+typedef WORD PROPVAR_PAD1;
+typedef WORD PROPVAR_PAD2;
+typedef WORD PROPVAR_PAD3;
+
+typedef struct tagPROPVARIANT
+{
+ VARTYPE vt;
+ PROPVAR_PAD1 wReserved1;
+ PROPVAR_PAD2 wReserved2;
+ PROPVAR_PAD3 wReserved3;
+ union
+ {
+ CHAR cVal;
+ UCHAR bVal;
+ SHORT iVal;
+ USHORT uiVal;
+ LONG lVal;
+ ULONG ulVal;
+ INT intVal;
+ UINT uintVal;
+ LARGE_INTEGER hVal;
+ ULARGE_INTEGER uhVal;
+ VARIANT_BOOL boolVal;
+ SCODE scode;
+ FILETIME filetime;
+ BSTR bstrVal;
+ };
+} PROPVARIANT;
+
+typedef PROPVARIANT tagVARIANT;
+typedef tagVARIANT VARIANT;
+typedef VARIANT VARIANTARG;
+
+MY_EXTERN_C BSTR SysAllocStringByteLen(LPCSTR psz, UINT len);
+MY_EXTERN_C BSTR SysAllocString(const OLECHAR *sz);
+MY_EXTERN_C void SysFreeString(BSTR bstr);
+MY_EXTERN_C UINT SysStringByteLen(BSTR bstr);
+MY_EXTERN_C UINT SysStringLen(BSTR bstr);
+
+MY_EXTERN_C DWORD GetLastError();
+MY_EXTERN_C HRESULT VariantClear(VARIANTARG *prop);
+MY_EXTERN_C HRESULT VariantCopy(VARIANTARG *dest, VARIANTARG *src);
+MY_EXTERN_C LONG CompareFileTime(const FILETIME* ft1, const FILETIME* ft2);
+
+#define CP_ACP 0
+#define CP_OEMCP 1
+
+typedef enum tagSTREAM_SEEK
+{
+ STREAM_SEEK_SET = 0,
+ STREAM_SEEK_CUR = 1,
+ STREAM_SEEK_END = 2
+} STREAM_SEEK;
+
+#endif
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/Common/NewHandler.cpp squashfs-tools-patched/LZMA/lzmadaptive/C/Common/NewHandler.cpp
--- squashfs-tools/LZMA/lzmadaptive/C/Common/NewHandler.cpp 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/Common/NewHandler.cpp 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,114 @@
+// NewHandler.cpp
+
+#include "StdAfx.h"
+
+#include <stdlib.h>
+
+#include "NewHandler.h"
+
+// #define DEBUG_MEMORY_LEAK
+
+#ifndef DEBUG_MEMORY_LEAK
+
+void *
+#ifdef _MSC_VER
+__cdecl
+#endif
+operator new(size_t size)
+{
+ // void *p = ::HeapAlloc(::GetProcessHeap(), 0, size);
+ void *p = ::malloc(size);
+ if (p == 0)
+ throw CNewException();
+ return p;
+}
+
+void
+#ifdef _MSC_VER
+__cdecl
+#endif
+operator delete(void *p) throw()
+{
+ /*
+ if (p == 0)
+ return;
+ ::HeapFree(::GetProcessHeap(), 0, p);
+ */
+ ::free(p);
+}
+
+#else
+
+#pragma init_seg(lib)
+const int kDebugSize = 1000000;
+static void *a[kDebugSize];
+static int index = 0;
+
+static int numAllocs = 0;
+void * __cdecl operator new(size_t size)
+{
+ numAllocs++;
+ void *p = HeapAlloc(GetProcessHeap(), 0, size);
+ if (index == 40)
+ {
+ int t = 1;
+ }
+ if (index < kDebugSize)
+ {
+ a[index] = p;
+ index++;
+ }
+ if (p == 0)
+ throw CNewException();
+ printf("Alloc %6d, size = %8d\n", numAllocs, size);
+ return p;
+}
+
+class CC
+{
+public:
+ CC()
+ {
+ for (int i = 0; i < kDebugSize; i++)
+ a[i] = 0;
+ }
+ ~CC()
+ {
+ for (int i = 0; i < kDebugSize; i++)
+ if (a[i] != 0)
+ return;
+ }
+} g_CC;
+
+
+void __cdecl operator delete(void *p)
+{
+ if (p == 0)
+ return;
+ /*
+ for (int i = 0; i < index; i++)
+ if (a[i] == p)
+ a[i] = 0;
+ */
+ HeapFree(GetProcessHeap(), 0, p);
+ numAllocs--;
+ printf("Free %d\n", numAllocs);
+}
+
+#endif
+
+/*
+int MemErrorVC(size_t)
+{
+ throw CNewException();
+ // return 1;
+}
+CNewHandlerSetter::CNewHandlerSetter()
+{
+ // MemErrorOldVCFunction = _set_new_handler(MemErrorVC);
+}
+CNewHandlerSetter::~CNewHandlerSetter()
+{
+ // _set_new_handler(MemErrorOldVCFunction);
+}
+*/
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/Common/NewHandler.h squashfs-tools-patched/LZMA/lzmadaptive/C/Common/NewHandler.h
--- squashfs-tools/LZMA/lzmadaptive/C/Common/NewHandler.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/Common/NewHandler.h 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,14 @@
+// Common/NewHandler.h
+
+#ifndef __COMMON_NEWHANDLER_H
+#define __COMMON_NEWHANDLER_H
+
+class CNewException {};
+
+void
+#ifdef _MSC_VER
+__cdecl
+#endif
+operator delete(void *p) throw();
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/Common/StdAfx.h squashfs-tools-patched/LZMA/lzmadaptive/C/Common/StdAfx.h
--- squashfs-tools/LZMA/lzmadaptive/C/Common/StdAfx.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/Common/StdAfx.h 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,9 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+// #include "MyWindows.h"
+#include "NewHandler.h"
+
+#endif
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/Common/StringConvert.cpp squashfs-tools-patched/LZMA/lzmadaptive/C/Common/StringConvert.cpp
--- squashfs-tools/LZMA/lzmadaptive/C/Common/StringConvert.cpp 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/Common/StringConvert.cpp 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,93 @@
+// Common/StringConvert.cpp
+
+#include "StdAfx.h"
+
+#include "StringConvert.h"
+
+#ifndef _WIN32
+#include <stdlib.h>
+#endif
+
+#ifdef _WIN32
+UString MultiByteToUnicodeString(const AString &srcString, UINT codePage)
+{
+ UString resultString;
+ if(!srcString.IsEmpty())
+ {
+ int numChars = MultiByteToWideChar(codePage, 0, srcString,
+ srcString.Length(), resultString.GetBuffer(srcString.Length()),
+ srcString.Length() + 1);
+ #ifndef _WIN32_WCE
+ if(numChars == 0)
+ throw 282228;
+ #endif
+ resultString.ReleaseBuffer(numChars);
+ }
+ return resultString;
+}
+
+AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage)
+{
+ AString resultString;
+ if(!srcString.IsEmpty())
+ {
+ int numRequiredBytes = srcString.Length() * 2;
+ int numChars = WideCharToMultiByte(codePage, 0, srcString,
+ srcString.Length(), resultString.GetBuffer(numRequiredBytes),
+ numRequiredBytes + 1, NULL, NULL);
+ #ifndef _WIN32_WCE
+ if(numChars == 0)
+ throw 282229;
+ #endif
+ resultString.ReleaseBuffer(numChars);
+ }
+ return resultString;
+}
+
+#ifndef _WIN32_WCE
+AString SystemStringToOemString(const CSysString &srcString)
+{
+ AString result;
+ CharToOem(srcString, result.GetBuffer(srcString.Length() * 2));
+ result.ReleaseBuffer();
+ return result;
+}
+#endif
+
+#else
+
+UString MultiByteToUnicodeString(const AString &srcString, UINT codePage)
+{
+ UString resultString;
+ for (int i = 0; i < srcString.Length(); i++)
+ resultString += wchar_t(srcString[i]);
+ /*
+ if(!srcString.IsEmpty())
+ {
+ int numChars = mbstowcs(resultString.GetBuffer(srcString.Length()), srcString, srcString.Length() + 1);
+ if (numChars < 0) throw "Your environment does not support UNICODE";
+ resultString.ReleaseBuffer(numChars);
+ }
+ */
+ return resultString;
+}
+
+AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage)
+{
+ AString resultString;
+ for (int i = 0; i < srcString.Length(); i++)
+ resultString += char(srcString[i]);
+ /*
+ if(!srcString.IsEmpty())
+ {
+ int numRequiredBytes = srcString.Length() * 6 + 1;
+ int numChars = wcstombs(resultString.GetBuffer(numRequiredBytes), srcString, numRequiredBytes);
+ if (numChars < 0) throw "Your environment does not support UNICODE";
+ resultString.ReleaseBuffer(numChars);
+ }
+ */
+ return resultString;
+}
+
+#endif
+
diff --strip-trailing-cr -NBbaur squashfs-tools/LZMA/lzmadaptive/C/Common/StringConvert.h squashfs-tools-patched/LZMA/lzmadaptive/C/Common/StringConvert.h
--- squashfs-tools/LZMA/lzmadaptive/C/Common/StringConvert.h 1969-12-31 19:00:00.000000000 -0500
+++ squashfs-tools-patched/LZMA/lzmadaptive/C/Common/StringConvert.h 2016-08-25 09:06:03.231530353 -0400
@@ -0,0 +1,71 @@
+// Common/StringConvert.h
+
+#ifndef __COMMON_STRINGCONVERT_H
+#define __COMMON_STRINGCONVERT_H
+
+#include "MyWindows.h"
+#include "Common/String.h"
+#include "Types.h"
+
+UString MultiByteToUnicodeString(const AString &srcString, UINT codePage = CP_ACP);
+AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage = CP_ACP);
+
+inline const wchar_t* GetUnicodeString(const wchar_t* unicodeString)
+ { return unicodeString; }
+inline const UStri
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment