diff options
31 files changed, 2017 insertions, 1869 deletions
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 367d5a7..5d5dd33 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -52,9 +52,8 @@ #endif #ifdef CONFIG_LZMA -#define _7ZIP_BYTE_DEFINED /* Byte already defined by zlib */ #include <lzma/LzmaTypes.h> -#include <lzma/LzmaDecode.h> +#include <lzma/LzmaDec.h> #include <lzma/LzmaTools.h> #endif /* CONFIG_LZMA */ @@ -390,7 +389,7 @@ static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress) int ret = lzmaBuffToBuffDecompress( (unsigned char *)load, &unc_len, (unsigned char *)image_start, image_len); - if (ret != LZMA_RESULT_OK) { + if (ret != SZ_OK) { printf ("LZMA: uncompress or overwrite error %d " "- must RESET board to recover\n", ret); show_boot_progress (-6); diff --git a/include/common.h b/include/common.h index a6c7c07..6e689b2 100644 --- a/include/common.h +++ b/include/common.h @@ -697,6 +697,7 @@ void show_boot_progress(int val); #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#define ROUND(a,b) (((a) + (b)) & ~((b) - 1)) #define DIV_ROUND(n,d) (((n) + ((d)/2)) / (d)) #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) #define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y)) diff --git a/include/configs/afeb9260.h b/include/configs/afeb9260.h index 8a1c4f5..74677d8 100644 --- a/include/configs/afeb9260.h +++ b/include/configs/afeb9260.h @@ -161,7 +161,6 @@ #define CONFIG_SYS_LONGHELP 1 #define CONFIG_CMDLINE_EDITING 1 -#define ROUND(A, B) (((A) + (B)) & ~((B) - 1)) /* * Size of malloc() pool */ diff --git a/include/configs/at91cap9adk.h b/include/configs/at91cap9adk.h index df73661..0ef3554 100644 --- a/include/configs/at91cap9adk.h +++ b/include/configs/at91cap9adk.h @@ -203,7 +203,6 @@ #define CONFIG_SYS_LONGHELP 1 #define CONFIG_CMDLINE_EDITING 1 -#define ROUND(A, B) (((A) + (B)) & ~((B) - 1)) /* * Size of malloc() pool */ diff --git a/include/configs/at91rm9200ek.h b/include/configs/at91rm9200ek.h index c898c73..58ec94a 100644 --- a/include/configs/at91rm9200ek.h +++ b/include/configs/at91rm9200ek.h @@ -311,7 +311,6 @@ struct bd_info_ext { */ #define CONFIG_SYS_HZ_CLOCK (AT91C_MASTER_CLOCK / 2) -#define ROUND(A, B) (((A) + (B)) & ~((B) - 1)) /* * Size of malloc() pool */ diff --git a/include/configs/at91sam9260ek.h b/include/configs/at91sam9260ek.h index 7eef9a3..6cee593 100644 --- a/include/configs/at91sam9260ek.h +++ b/include/configs/at91sam9260ek.h @@ -207,7 +207,6 @@ #define CONFIG_SYS_LONGHELP 1 #define CONFIG_CMDLINE_EDITING 1 -#define ROUND(A, B) (((A) + (B)) & ~((B) - 1)) /* * Size of malloc() pool */ diff --git a/include/configs/at91sam9261ek.h b/include/configs/at91sam9261ek.h index 028a04f..3d108ab 100644 --- a/include/configs/at91sam9261ek.h +++ b/include/configs/at91sam9261ek.h @@ -225,7 +225,6 @@ #define CONFIG_SYS_LONGHELP 1 #define CONFIG_CMDLINE_EDITING 1 -#define ROUND(A, B) (((A) + (B)) & ~((B) - 1)) /* * Size of malloc() pool */ diff --git a/include/configs/at91sam9263ek.h b/include/configs/at91sam9263ek.h index 9539d18..32f3f62 100644 --- a/include/configs/at91sam9263ek.h +++ b/include/configs/at91sam9263ek.h @@ -335,7 +335,6 @@ #define CONFIG_SYS_HUSH_PARSER #define CONFIG_SYS_PROMPT_HUSH_PS2 "> " -#define ROUND(A, B) (((A) + (B)) & ~((B) - 1)) /* * Size of malloc() pool */ diff --git a/include/configs/at91sam9m10g45ek.h b/include/configs/at91sam9m10g45ek.h index af97afe..4b46c31 100644 --- a/include/configs/at91sam9m10g45ek.h +++ b/include/configs/at91sam9m10g45ek.h @@ -212,7 +212,6 @@ #define CONFIG_SYS_HUSH_PARSER #define CONFIG_SYS_PROMPT_HUSH_PS2 "> " -#define ROUND(A, B) (((A) + (B)) & ~((B) - 1)) /* * Size of malloc() pool */ diff --git a/include/configs/at91sam9rlek.h b/include/configs/at91sam9rlek.h index bc2a32b..9167304 100644 --- a/include/configs/at91sam9rlek.h +++ b/include/configs/at91sam9rlek.h @@ -170,7 +170,6 @@ #define CONFIG_SYS_LONGHELP 1 #define CONFIG_CMDLINE_EDITING 1 -#define ROUND(A, B) (((A) + (B)) & ~((B) - 1)) /* * Size of malloc() pool */ diff --git a/include/configs/pm9261.h b/include/configs/pm9261.h index 315d7f8..203a14c 100644 --- a/include/configs/pm9261.h +++ b/include/configs/pm9261.h @@ -368,7 +368,6 @@ #define CONFIG_SYS_LONGHELP 1 #define CONFIG_CMDLINE_EDITING 1 -#define ROUND(A, B) (((A) + (B)) & ~((B) - 1)) /* * Size of malloc() pool */ diff --git a/include/configs/pm9263.h b/include/configs/pm9263.h index f8197b1..a6ff28c 100644 --- a/include/configs/pm9263.h +++ b/include/configs/pm9263.h @@ -397,7 +397,6 @@ #define CONFIG_SYS_LONGHELP 1 #define CONFIG_CMDLINE_EDITING 1 -#define ROUND(A, B) (((A) + (B)) & ~((B) - 1)) /* * Size of malloc() pool */ diff --git a/include/configs/qemu-mips.h b/include/configs/qemu-mips.h index 8444462..cbacdf9 100644 --- a/include/configs/qemu-mips.h +++ b/include/configs/qemu-mips.h @@ -163,6 +163,8 @@ #undef CONFIG_MEMSIZE_IN_BYTES +#define CONFIG_LZMA + /*----------------------------------------------------------------------- * Cache Configuration */ diff --git a/include/lzma/LzmaDecode.h b/include/lzma/LzmaDec.h index 8fdb2c0..967cdd1 100644 --- a/include/lzma/LzmaDecode.h +++ b/include/lzma/LzmaDec.h @@ -1,7 +1,7 @@ /* - * Fake include for LzmaDecode.h + * Fake include for LzmaDec.h * - * Copyright (C) 2007-2008 Industrie Dial Face S.p.A. + * Copyright (C) 2007-2009 Industrie Dial Face S.p.A. * Luigi 'Comio' Mantellini (luigi.mantellini@idf-hit.com) * * See file CREDITS for list of people who contributed to this @@ -23,9 +23,9 @@ * MA 02111-1307 USA */ -#ifndef __LZMADECODE_H__FAKE__ -#define __LZMADECODE_H__FAKE__ +#ifndef __LZMADEC_H__FAKE__ +#define __LZMADEC_H__FAKE__ -#include "../../lib_generic/lzma/LzmaDecode.h" +#include "../../lib_generic/lzma/LzmaDec.h" #endif diff --git a/include/lzma/LzmaTools.h b/include/lzma/LzmaTools.h index 7c5eea1..87943c0 100644 --- a/include/lzma/LzmaTools.h +++ b/include/lzma/LzmaTools.h @@ -1,7 +1,7 @@ /* * Fake include for LzmaTools.h * - * Copyright (C) 2007-2008 Industrie Dial Face S.p.A. + * Copyright (C) 2007-2009 Industrie Dial Face S.p.A. * Luigi 'Comio' Mantellini (luigi.mantellini@idf-hit.com) * * See file CREDITS for list of people who contributed to this diff --git a/include/lzma/LzmaTypes.h b/include/lzma/LzmaTypes.h index 02daa59..86160a4 100644 --- a/include/lzma/LzmaTypes.h +++ b/include/lzma/LzmaTypes.h @@ -1,7 +1,7 @@ /* - * Fake include for LzmaTypes.h + * Fake include for Types.h * - * Copyright (C) 2007-2008 Industrie Dial Face S.p.A. + * Copyright (C) 2007-2009 Industrie Dial Face S.p.A. * Luigi 'Comio' Mantellini (luigi.mantellini@idf-hit.com) * * See file CREDITS for list of people who contributed to this @@ -23,9 +23,14 @@ * MA 02111-1307 USA */ -#ifndef __LZMATYPES_H__FAKE__ -#define __LZMATYPES_H__FAKE__ +#ifndef __TYPES_H__FAKE__ +#define __TYPES_H__FAKE__ -#include "../../lib_generic/lzma/LzmaTypes.h" +/* + *This avoids the collition with zlib.h Byte definition + */ +#define Byte LZByte + +#include "../../lib_generic/lzma/Types.h" #endif diff --git a/lib_generic/lzma/LGPL.txt b/lib_generic/lzma/LGPL.txt deleted file mode 100644 index 9e76f5b..0000000 --- a/lib_generic/lzma/LGPL.txt +++ /dev/null @@ -1,502 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - <one line to give the library's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - <signature of Ty Coon>, 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! diff --git a/lib_generic/lzma/LzmaDec.c b/lib_generic/lzma/LzmaDec.c new file mode 100644 index 0000000..89d934a --- /dev/null +++ b/lib_generic/lzma/LzmaDec.c @@ -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 --git a/lib_generic/lzma/LzmaDec.h b/lib_generic/lzma/LzmaDec.h new file mode 100644 index 0000000..7fba87f --- /dev/null +++ b/lib_generic/lzma/LzmaDec.h @@ -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 --git a/lib_generic/lzma/LzmaDecode.c b/lib_generic/lzma/LzmaDecode.c deleted file mode 100644 index 3470e55..0000000 --- a/lib_generic/lzma/LzmaDecode.c +++ /dev/null @@ -1,584 +0,0 @@ -/* - LzmaDecode.c - LZMA Decoder (optimized for Speed version) - - LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01) - 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" - -#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 --git a/lib_generic/lzma/LzmaDecode.h b/lib_generic/lzma/LzmaDecode.h deleted file mode 100644 index bd75525..0000000 --- a/lib_generic/lzma/LzmaDecode.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - LzmaDecode.h - LZMA Decoder interface - - LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01) - 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 - -#include "LzmaTypes.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 */ - -#ifdef _LZMA_PROB32 -#define CProb UInt32 -#else -#define CProb UInt16 -#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 --git a/lib_generic/lzma/LzmaTools.c b/lib_generic/lzma/LzmaTools.c index 5ac42e5..c2a91e5 100644 --- a/lib_generic/lzma/LzmaTools.c +++ b/lib_generic/lzma/LzmaTools.c @@ -1,7 +1,7 @@ /* - * Usefuls routines based on the LzmaTest.c file from LZMA SDK 4.57 + * Usefuls routines based on the LzmaTest.c file from LZMA SDK 4.65 * - * Copyright (C) 2007-2008 Industrie Dial Face S.p.A. + * Copyright (C) 2007-2009 Industrie Dial Face S.p.A. * Luigi 'Comio' Mantellini (luigi.mantellini@idf-hit.com) * * Copyright (C) 1999-2005 Igor Pavlov @@ -40,103 +40,88 @@ #ifdef CONFIG_LZMA #define LZMA_PROPERTIES_OFFSET 0 -#define LZMA_SIZE_OFFSET LZMA_PROPERTIES_SIZE +#define LZMA_SIZE_OFFSET LZMA_PROPS_SIZE #define LZMA_DATA_OFFSET LZMA_SIZE_OFFSET+sizeof(uint64_t) #include "LzmaTools.h" -#include "LzmaDecode.h" +#include "LzmaDec.h" #include <linux/string.h> #include <malloc.h> +static void *SzAlloc(void *p, size_t size) { p = p; return malloc(size); } +static void SzFree(void *p, void *address) { p = p; free(address); } + int lzmaBuffToBuffDecompress (unsigned char *outStream, SizeT *uncompressedSize, - unsigned char *inStream, SizeT length) + unsigned char *inStream, SizeT length) { - int res = LZMA_RESULT_DATA_ERROR; - int i; - - SizeT outSizeFull = 0xFFFFFFFF; /* 4GBytes limit */ - SizeT inProcessed; - SizeT outProcessed; - SizeT outSize; - SizeT outSizeHigh; - CLzmaDecoderState state; /* it's about 24-80 bytes structure, if int is 32-bit */ - unsigned char properties[LZMA_PROPERTIES_SIZE]; - SizeT compressedSize = (SizeT)(length - LZMA_DATA_OFFSET); - - debug ("LZMA: Image address............... 0x%lx\n", inStream); - debug ("LZMA: Properties address.......... 0x%lx\n", inStream + LZMA_PROPERTIES_OFFSET); - debug ("LZMA: Uncompressed size address... 0x%lx\n", inStream + LZMA_SIZE_OFFSET); - debug ("LZMA: Compressed data address..... 0x%lx\n", inStream + LZMA_DATA_OFFSET); - debug ("LZMA: Destination address......... 0x%lx\n", outStream); - - memcpy(properties, inStream + LZMA_PROPERTIES_OFFSET, LZMA_PROPERTIES_SIZE); - - memset(&state, 0, sizeof(state)); - res = LzmaDecodeProperties(&state.Properties, - properties, - LZMA_PROPERTIES_SIZE); - if (res != LZMA_RESULT_OK) { - return res; - } - - outSize = 0; - outSizeHigh = 0; - /* Read the uncompressed size */ - for (i = 0; i < 8; i++) { - unsigned char b = inStream[LZMA_SIZE_OFFSET + i]; - if (i < 4) { - outSize += (UInt32)(b) << (i * 8); - } else { - outSizeHigh += (UInt32)(b) << ((i - 4) * 8); - } - } - - outSizeFull = (SizeT)outSize; - if (sizeof(SizeT) >= 8) { - /* - * SizeT is a 64 bit uint => We can manage files larger than 4GB! - * - */ - outSizeFull |= (((SizeT)outSizeHigh << 16) << 16); - } else if (outSizeHigh != 0 || (UInt32)(SizeT)outSize != outSize) { - /* - * SizeT is a 32 bit uint => We cannot manage files larger than - * 4GB! - * - */ - debug ("LZMA: 64bit support not enabled.\n"); - return LZMA_RESULT_DATA_ERROR; - } - - debug ("LZMA: Uncompresed size............ 0x%lx\n", outSizeFull); - debug ("LZMA: Compresed size.............. 0x%lx\n", compressedSize); - debug ("LZMA: Dynamic memory needed....... 0x%lx", LzmaGetNumProbs(&state.Properties) * sizeof(CProb)); - - state.Probs = (CProb *)malloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb)); - - if (state.Probs == 0 - || (outStream == 0 && outSizeFull != 0) - || (inStream == 0 && compressedSize != 0)) { - free(state.Probs); - debug ("\n"); - return LZMA_RESULT_DATA_ERROR; - } - - debug (" allocated.\n"); - - /* Decompress */ - - res = LzmaDecode(&state, - inStream + LZMA_DATA_OFFSET, compressedSize, &inProcessed, - outStream, outSizeFull, &outProcessed); - if (res != LZMA_RESULT_OK) { - return res; - } - - *uncompressedSize = outProcessed; - free(state.Probs); - return res; + int res = SZ_ERROR_DATA; + int i; + ISzAlloc g_Alloc; + + SizeT outSizeFull = 0xFFFFFFFF; /* 4GBytes limit */ + SizeT inProcessed; + SizeT outProcessed; + SizeT outSize; + SizeT outSizeHigh; + ELzmaStatus state; + SizeT compressedSize = (SizeT)(length - LZMA_PROPS_SIZE); + + debug ("LZMA: Image address............... 0x%lx\n", inStream); + debug ("LZMA: Properties address.......... 0x%lx\n", inStream + LZMA_PROPERTIES_OFFSET); + debug ("LZMA: Uncompressed size address... 0x%lx\n", inStream + LZMA_SIZE_OFFSET); + debug ("LZMA: Compressed data address..... 0x%lx\n", inStream + LZMA_DATA_OFFSET); + debug ("LZMA: Destination address......... 0x%lx\n", outStream); + + memset(&state, 0, sizeof(state)); + + outSize = 0; + outSizeHigh = 0; + /* Read the uncompressed size */ + for (i = 0; i < 8; i++) { + unsigned char b = inStream[LZMA_SIZE_OFFSET + i]; + if (i < 4) { + outSize += (UInt32)(b) << (i * 8); + } else { + outSizeHigh += (UInt32)(b) << ((i - 4) * 8); + } + } + + outSizeFull = (SizeT)outSize; + if (sizeof(SizeT) >= 8) { + /* + * SizeT is a 64 bit uint => We can manage files larger than 4GB! + * + */ + outSizeFull |= (((SizeT)outSizeHigh << 16) << 16); + } else if (outSizeHigh != 0 || (UInt32)(SizeT)outSize != outSize) { + /* + * SizeT is a 32 bit uint => We cannot manage files larger than + * 4GB! + * + */ + debug ("LZMA: 64bit support not enabled.\n"); + return SZ_ERROR_DATA; + } + + debug ("LZMA: Uncompresed size............ 0x%lx\n", outSizeFull); + debug ("LZMA: Compresed size.............. 0x%lx\n", compressedSize); + + g_Alloc.Alloc = SzAlloc; + g_Alloc.Free = SzFree; + + /* Decompress */ + outProcessed = outSizeFull; + res = LzmaDecode( + outStream, &outProcessed, + inStream + LZMA_DATA_OFFSET, &compressedSize, + inStream, LZMA_PROPS_SIZE, LZMA_FINISH_ANY, &state, &g_Alloc); + *uncompressedSize = outProcessed; + if (res != SZ_OK) { + return res; + } + + return res; } #endif diff --git a/lib_generic/lzma/LzmaTools.h b/lib_generic/lzma/LzmaTools.h index c91fb89..2db80fc 100644 --- a/lib_generic/lzma/LzmaTools.h +++ b/lib_generic/lzma/LzmaTools.h @@ -1,5 +1,5 @@ /* - * Usefuls routines based on the LzmaTest.c file from LZMA SDK 4.57 + * Usefuls routines based on the LzmaTest.c file from LZMA SDK 4.65 * * Copyright (C) 2007-2008 Industrie Dial Face S.p.A. * Luigi 'Comio' Mantellini (luigi.mantellini@idf-hit.com) @@ -28,7 +28,7 @@ #ifndef __LZMA_TOOL_H__ #define __LZMA_TOOL_H__ -#include "LzmaTypes.h" +#include <lzma/LzmaTypes.h> extern int lzmaBuffToBuffDecompress (unsigned char *outStream, SizeT *uncompressedSize, unsigned char *inStream, SizeT length); diff --git a/lib_generic/lzma/LzmaTypes.h b/lib_generic/lzma/LzmaTypes.h deleted file mode 100644 index 83f96f4..0000000 --- a/lib_generic/lzma/LzmaTypes.h +++ /dev/null @@ -1,45 +0,0 @@ -/* -LzmaTypes.h - -Types for LZMA Decoder - -This file written and distributed to public domain by Igor Pavlov. -This file is part of LZMA SDK 4.40 (2006-05-01) -*/ - -#ifndef __LZMATYPES_H -#define __LZMATYPES_H - -#ifndef _7ZIP_BYTE_DEFINED -#define _7ZIP_BYTE_DEFINED -typedef unsigned char Byte; -#endif - -#ifndef _7ZIP_UINT16_DEFINED -#define _7ZIP_UINT16_DEFINED -typedef unsigned short UInt16; -#endif - -#ifndef _7ZIP_UINT32_DEFINED -#define _7ZIP_UINT32_DEFINED -#ifdef _LZMA_UINT32_IS_ULONG -typedef unsigned long UInt32; -#else -typedef unsigned int UInt32; -#endif -#endif - -/* #define _LZMA_NO_SYSTEM_SIZE_T */ -/* You can use it, if you don't want <stddef.h> */ - -#ifndef _7ZIP_SIZET_DEFINED -#define _7ZIP_SIZET_DEFINED -#ifdef _LZMA_NO_SYSTEM_SIZE_T -typedef UInt32 SizeT; -#else -#include <stddef.h> -typedef size_t SizeT; -#endif -#endif - -#endif diff --git a/lib_generic/lzma/Makefile b/lib_generic/lzma/Makefile index 3400cd9..2916f21 100644 --- a/lib_generic/lzma/Makefile +++ b/lib_generic/lzma/Makefile @@ -30,7 +30,9 @@ LIB = $(obj)liblzma.a SOBJS = -COBJS-$(CONFIG_LZMA) += LzmaDecode.o LzmaTools.o +CFLAGS += -D_LZMA_PROB32 -I$(TOPDIR)/include/linux + +COBJS-$(CONFIG_LZMA) += LzmaDec.o LzmaTools.o COBJS = $(COBJS-y) SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) diff --git a/lib_generic/lzma/README.txt b/lib_generic/lzma/README.txt index fdb3086..23a9be2 100644 --- a/lib_generic/lzma/README.txt +++ b/lib_generic/lzma/README.txt @@ -7,14 +7,14 @@ Author: Igor Pavlov The import is made using the import_lzmasdk.sh script that: * untars the lzmaXYY.tar.bz2 file (from the download web page) -* copies the files LzmaDecode.h, LzmaTypes.h, LzmaDecode.c, history.txt, - LGPL.txt, and lzma.txt from source archive into the lib_lzma directory (pwd). +* copies the files LzmaDec.h, Types.h, LzmaDec.c, history.txt, + and lzma.txt from source archive into the lib_lzma directory (pwd). Example: - ./import_lzmasdk.sh ~/lzma457.tar.bz2 + . import_lzmasdk.sh ~/lzma465.tar.bz2 -Notice: The files from lzma sdk are not _modified_ by this script! +Notice: The files from lzma sdk are _not modified_ by this script! The files LzmaTools.{c,h} are provided to export the lzmaBuffToBuffDecompress() function that wraps the complex LzmaDecode() function from the LZMA SDK. The diff --git a/lib_generic/lzma/Types.h b/lib_generic/lzma/Types.h new file mode 100644 index 0000000..1af5cfc --- /dev/null +++ b/lib_generic/lzma/Types.h @@ -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 --git a/lib_generic/lzma/history.txt b/lib_generic/lzma/history.txt index dad1858..624fb1d 100644 --- a/lib_generic/lzma/history.txt +++ b/lib_generic/lzma/history.txt @@ -1,192 +1,230 @@ HISTORY of the LZMA SDK ----------------------- - 4.57 2007-12-12 - ------------------------- - - Speed optimizations in Ñ++ LZMA Decoder. - - Small changes for more compatibility with some C/C++ compilers. +4.65 2009-02-03 +------------------------- +- Some minor fixes - 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.63 2008-12-31 +------------------------- +- Some minor fixes - 4.43 2006-06-04 - ------------------------- - - Small changes for more compatibility with some C/C++ compilers. +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.42 2006-05-15 - ------------------------- - - Small changes in .h files in ANSI-C version. +4.60 beta 2008-08-19 +------------------------- +- Some minor fixes. - 4.39 beta 2006-04-14 - ------------------------- - - 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.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.37 beta 2005-04-06 - ------------------------- - - Fixes in C++ code: code could no be compiled if _NO_EXCEPTIONS was defined. +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.35 beta 2005-03-02 - ------------------------- - - Bug was fixed in C++ version of LZMA Decoder: - If encoded stream was corrupted, decoder could access memory - outside of allocated range. +4.57 2007-12-12 +------------------------- +- Speed optimizations in Ñ++ LZMA Decoder. +- Small changes for more compatibility with some C/C++ compilers. - 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.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.32 2005-12-09 - ------------------------- - - Java version of LZMA SDK was included +4.43 2006-06-04 +------------------------- +- Small changes for more compatibility with some C/C++ compilers. - 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 - - 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.42 2006-05-15 +------------------------- +- Small changes in .h files in ANSI-C version. - 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.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.27 2005-08-07 - ------------------------- - - Bug in LzmaDecodeSize.c was fixed: - if _LZMA_IN_CB and _LZMA_OUT_READ were defined, - decompressing worked incorrectly. +4.37 beta 2005-04-06 +------------------------- +- Fixes in C++ code: code could no be compiled if _NO_EXCEPTIONS was defined. - 4.26 2005-08-05 - ------------------------- - - Fixes in 7z_C code and LzmaTest.c: - previous versions could work incorrectly, - if malloc(0) returns 0 +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.23 2005-06-29 - ------------------------- - - Small fixes in C++ code +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.22 2005-06-10 - ------------------------- - - Small fixes +4.32 2005-12-09 +------------------------- +- Java version of LZMA SDK was included - 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.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.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.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.16 2005-03-29 - ------------------------- - - 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.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.06 2004-09-05 - ------------------------- - - Bug in v4.05 was fixed: - LZMA-Encoder didn't release output stream in some cases. +4.26 2005-08-05 +------------------------- +- Fixes in 7z_C code and LzmaTest.c: + previous versions could work incorrectly, + if malloc(0) returns 0 - 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.23 2005-06-29 +------------------------- +- Small fixes in C++ code - 4.04 2004-07-28 - ------------------------- - - More compatibility with some C++ compilers +4.22 2005-06-10 +------------------------- +- Small fixes - 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.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.02 2004-06-10 - ------------------------- - - C++ LZMA Encoder/Decoder code now is more portable - and it can be compiled by GCC on Linux. +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.01 2004-02-15 - ------------------------- - - Some detection of data corruption was enabled. - LzmaDecode.c / RangeDecoderReadByte - ..... - { - rd->ExtraBytes = 1; - return 0xFF; - } +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.00 2004-02-13 - ------------------------- - - Original version of LZMA SDK +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-2007: Improvements to LZMA compressing/decompressing code, - keeping compatibility with original LZMA format + 2001-2008: Improvements to LZMA compressing/decompressing code, + keeping compatibility with original LZMA format 1996-2001: Development of LZMA compression format Some milestones: diff --git a/lib_generic/lzma/import_lzmasdk.sh b/lib_generic/lzma/import_lzmasdk.sh index 5212e48..1e0f686 100644 --- a/lib_generic/lzma/import_lzmasdk.sh +++ b/lib_generic/lzma/import_lzmasdk.sh @@ -17,14 +17,12 @@ fi BASENAME=`basename $1 .tar.bz2` TMPDIR=/tmp/tmp_lib_$BASENAME -FILES="C/Compress/Lzma/LzmaDecode.h - C/Compress/Lzma/LzmaTypes.h - C/Compress/Lzma/LzmaDecode.c +FILES="C/LzmaDec.h + C/Types.h + C/LzmaDec.c history.txt - LGPL.txt lzma.txt" - mkdir -p $TMPDIR echo "Untar $1 -> $TMPDIR" tar -jxf $1 -C $TMPDIR diff --git a/lib_generic/lzma/license.txt b/lib_generic/lzma/license.txt new file mode 100644 index 0000000..48b9820 --- /dev/null +++ b/lib_generic/lzma/license.txt @@ -0,0 +1,3 @@ + License + +LZMA SDK is placed in the public domain. diff --git a/lib_generic/lzma/lzma.txt b/lib_generic/lzma/lzma.txt index 5f1a0c9..aa20f9d 100644 --- a/lib_generic/lzma/lzma.txt +++ b/lib_generic/lzma/lzma.txt @@ -1,8 +1,6 @@ -LZMA SDK 4.57 +LZMA SDK 4.65 ------------- -LZMA SDK Copyright (C) 1999-2007 Igor Pavlov - LZMA SDK provides the documentation, samples, header files, libraries, and tools you need to develop applications that use LZMA compression. @@ -20,70 +18,7 @@ decompressing. LICENSE ------- -LZMA SDK is available under any of the following licenses: - -1) GNU Lesser General Public License (GNU LGPL) -2) Common Public License (CPL) -3) Simplified license for unmodified code (read SPECIAL EXCEPTION) -4) Proprietary license - -It means that you can select one of these four options and follow rules of that license. - - -1,2) GNU LGPL and CPL licenses are pretty similar and both these -licenses are classified as - - "Free software licenses" at http://www.gnu.org/ - - "OSI-approved" at http://www.opensource.org/ - - -3) 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 files from LZMA SDK without subjecting your linked -code to the terms of the CPL or GNU LGPL. -Any modifications or additions to files from LZMA SDK, however, -are subject to the GNU LGPL or CPL terms. - -SPECIAL EXCEPTION allows you to use LZMA SDK in applications with closed code, -while you keep LZMA SDK code unmodified. - - -SPECIAL EXCEPTION #2: Igor Pavlov, as the author of this code, expressly permits -you to use this code under the same terms and conditions contained in the License -Agreement you have for any previous version of LZMA SDK developed by Igor Pavlov. - -SPECIAL EXCEPTION #2 allows owners of proprietary licenses to use latest version -of LZMA SDK as update for previous versions. - - -SPECIAL EXCEPTION #3: Igor Pavlov, as the author of this code, expressly permits -you to use code of the following files: -BranchTypes.h, LzmaTypes.h, LzmaTest.c, LzmaStateTest.c, LzmaAlone.cpp, -LzmaAlone.cs, LzmaAlone.java -as public domain code. - - -4) Proprietary license - -LZMA SDK also can be available under a proprietary license which -can include: - -1) Right to modify code without subjecting modified code to the -terms of the CPL or GNU LGPL -2) Technical support for code - -To request such proprietary license or any additional consultations, -send email message from that page: -http://www.7-zip.org/support.html - - -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 - -You should have received a copy of the Common Public License -along with this library. +LZMA SDK is written and placed in the public domain by Igor Pavlov. LZMA SDK Contents @@ -91,87 +26,71 @@ LZMA SDK Contents LZMA SDK includes: - - C++ source code of LZMA compressing and decompressing - - ANSI-C compatible source code for LZMA decompressing - - C# source code for LZMA compressing and decompressing - - Java source code for LZMA compressing and decompressing + - ANSI-C/C++/C#/Java source code for LZMA compressing and decompressing - Compiled file->file LZMA compressing/decompressing program for Windows system -ANSI-C LZMA decompression code was ported from original C++ sources to C. -Also it was simplified and optimized for code size. -But it is fully compatible with LZMA from 7-Zip. - UNIX/Linux version ------------------ -To compile C++ version of file->file LZMA, go to directory -C/7zip/Compress/LZMA_Alone -and type "make" or "make clean all" to recompile all. +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, change string in makefile -LIB = -lm -to string +To compile with static libraries, you can use LIB = -lm -static Files --------------------- -C - C source code -CPP - CPP source code -CS - C# source code -Java - Java source code -lzma.txt - LZMA SDK description (this file) +lzma.txt - LZMA SDK description (this file) 7zFormat.txt - 7z Format description -7zC.txt - 7z ANSI-C Decoder description (this file) +7zC.txt - 7z ANSI-C Decoder description methods.txt - Compression method IDs for .7z -LGPL.txt - GNU Lesser General Public License -CPL.html - Common Public License -lzma.exe - Compiled file->file LZMA encoder/decoder for Windows -history.txt - history of the LZMA SDK +lzma.exe - Compiled file->file LZMA encoder/decoder for Windows +history.txt - history of the LZMA SDK Source code structure --------------------- -C - C files - Compress - files related to compression/decompression - Lz - files related to LZ (Lempel-Ziv) compression algorithm - Lzma - ANSI-C compatible LZMA decompressor +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. - LzmaDecode.h - interface for LZMA decoding on ANSI-C - LzmaDecode.c - LZMA decoding on ANSI-C (new fastest version) - LzmaDecodeSize.c - LZMA decoding on ANSI-C (old size-optimized version) - LzmaTest.c - test application that decodes LZMA encoded file - LzmaTypes.h - basic types for LZMA Decoder - LzmaStateDecode.h - interface for LZMA decoding (State version) - LzmaStateDecode.c - LZMA decoding on ANSI-C (State version) - LzmaStateTest.c - test application (State version) + LzmaLib - LZMA Library (.DLL for Windows) - Branch - Filters for x86, IA-64, ARM, ARM-Thumb, PowerPC and SPARC code + LzmaUtil - LZMA Utility (file->file LZMA encoder/decoder). Archive - files related to archiving - 7z_C - 7z ANSI-C Decoder - + 7z - 7z ANSI-C Decoder -CPP -- CPP files +CPP/ -- CPP files Common - common files for C++ projects Windows - common files for Windows related code - 7zip - files related to 7-Zip Project + + 7zip - files related to 7-Zip Project Common - common files for 7-Zip Compress - files related to compression/decompression - LZ - files related to LZ (Lempel-Ziv) compression algorithm - - Copy - Copy coder + Copy - Copy coder RangeCoder - Range Coder (special code of compression/decompression) - LZMA - LZMA compression/decompression on C++ + 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 + Branch - Filters for x86, IA-64, ARM, ARM-Thumb, PowerPC and SPARC code Archive - files related to archiving @@ -180,67 +99,61 @@ CPP -- CPP files 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. + 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 + UI - User Interface files - Client7z - Test application for 7za.dll, 7zr.dll, 7zxr.dll + Client7z - Test application for 7za.dll, 7zr.dll, 7zxr.dll Common - Common UI files Console - Code for console archiver -CS - C# files +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 + LZMA - LZMA compression/decompression LzmaAlone - file->file LZMA compression/decompression RangeCoder - Range Coder (special code of compression/decompression) -Java - Java files +Java/ - Java files SevenZip Compression - files related to compression/decompression - LZ - files related to LZ (Lempel-Ziv) compression algorithm - LZMA - LZMA 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. - -You can find ANSI-C LZMA decompressing code at folder - C/7zip/Compress/Lzma -7-Zip doesn't use that ANSI-C LZMA code and that code was developed -specially for this SDK. And files from C/7zip/Compress/Lzma do not need -files from other directories of SDK for compiling. +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 1 MB/s on 1 GHz CPU + - Estimated compressing speed: about 2 MB/s on 2 GHz CPU - Estimated decompressing speed: - - 8-12 MB/s on 1 GHz Intel Pentium 3 or AMD Athlon - - 500-1000 KB/s on 100 MHz ARM, MIPS, PowerPC or other simple RISC - - Small memory requirements for decompressing (8-32 KB + DictionarySize) - - Small code size for decompressing: 2-8 KB (depending from - speed optimizations) + - 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 to speed of LZMA decompression: +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 -Speed of LZMA decompressing mostly depends from CPU speed. +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. @@ -251,7 +164,7 @@ How To Use Using LZMA encoder/decoder executable -------------------------------------- -Usage: LZMA <e|d> inputFile outputFile [<switches>...] +Usage: LZMA <e|d> inputFile outputFile [<switches>...] e: encode file @@ -260,11 +173,11 @@ Usage: LZMA <e|d> inputFile outputFile [<switches>...] 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 AMD Athlon 64 X2 CPU - results. Also Benchmark checks possible hardware errors (RAM + 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. Also you - can change number of iterations. Example for 30 iterations: + (-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. @@ -272,52 +185,52 @@ Usage: LZMA <e|d> inputFile outputFile [<switches>...] -a{N}: set compression mode 0 = fast, 1 = normal - default: 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). + 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. + 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. + 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. + 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. + 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). + 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). + Memory requirements depend from dictionary size + (parameter "d" in table below). - MF_ID Memory Description + 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. + 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. + 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 + -si: Read data from stdin (it will write End Of Stream marker). + -so: Write data to stdout Examples: @@ -345,32 +258,29 @@ Compression ratio hints Recommendations --------------- -To increase compression ratio for LZMA compressing it's desirable +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, ...). -Using Filters -------------- -You can increase compression ratio for some data types, using +Filters +------- +You can increase the compression ratio for some data types, using special filters before compressing. For example, it's possible to -increase compression ratio on 5-10% for code for those CPU ISAs: +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/C++ source code of such filters in folder "7zip/Compress/Branch" +You can find C source code of such filters in C/Bra*.* files -You can check compression ratio gain of these filters with such +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=bc_arm -m1=lzma - -With filter for big-endian ARM code (using additional Swap4 filter): - 7z a a3.7z a.bin -m0=swap4 -m1=bc_arm -m2=lzma + 7z a a2.7z a.bin -m0=arm -m1=lzma It works in such manner: Compressing = Filter_encoding + LZMA_encoding @@ -383,8 +293,7 @@ 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. Source code of these CALL filters is pretty simple -(about 20 lines of C++), so you can convert it from C++ version yourself. +compressible. For some ISAs (for example, for MIPS) it's impossible to get gain from such filter. @@ -392,272 +301,294 @@ For some ISAs (for example, for MIPS) it's impossible to get gain from such filt LZMA compressed file format --------------------------- Offset Size Description - 0 1 Special LZMA properties for compressed data - 1 4 Dictionary size (little endian) - 5 8 Uncompressed size (little endian). -1 means unknown size - 13 Compressed data + 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 ~~~~~~~~~~~~~~~~~~~ -To compile ANSI-C LZMA Decoder you can use one of the following files sets: -1) LzmaDecode.h + LzmaDecode.c + LzmaTest.c (fastest version) -2) LzmaDecode.h + LzmaDecodeSize.c + LzmaTest.c (old size-optimized version) -3) LzmaStateDecode.h + LzmaStateDecode.c + LzmaStateTest.c (zlib-like interface) +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 ------------------------------------- -LZMA decoder doesn't allocate memory itself, so you must -allocate memory and send it to LZMA. - Stack usage of LZMA decoding function for local variables is not -larger than 200 bytes. +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 5 interfaces: +LZMA Decoder (ANSI-C version) now supports 2 interfaces: 1) Single-call Decompressing -2) Single-call Decompressing with input stream callback -3) Multi-call Decompressing with output buffer -4) Multi-call Decompressing with input callback and output buffer -5) Multi-call State Decompressing (zlib-like interface) - -Variant-5 is similar to Variant-4, but Variant-5 doesn't use callback functions. - -Decompressing steps -------------------- - -1) read LZMA properties (5 bytes): - unsigned char properties[LZMA_PROPERTIES_SIZE]; - -2) read uncompressed size (8 bytes, little-endian) +2) Multi-call State Decompressing (zlib-like interface) -3) Decode properties: +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 }; - CLzmaDecoderState state; /* it's 24-140 bytes structure, if int is 32-bit */ +You can use p = p; operator to disable compiler warnings. - if (LzmaDecodeProperties(&state.Properties, properties, LZMA_PROPERTIES_SIZE) != LZMA_RESULT_OK) - return PrintError(rs, "Incorrect stream properties"); -4) Allocate memory block for internal Structures: - - state.Probs = (CProb *)malloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb)); - if (state.Probs == 0) - return PrintError(rs, kCantAllocateMessage); - - LZMA decoder uses array of CProb variables as internal structure. - By default, CProb is unsigned_short. But you can define _LZMA_PROB32 to make - it unsigned_int. It can increase speed on some 32-bit CPUs, but memory - usage will be doubled in that case. - - -5) Main Decompressing - -You must use one of the following interfaces: - -5.1 Single-call Decompressing ------------------------------ +Single-call Decompressing +------------------------- When to use: RAM->RAM decompressing -Compile files: LzmaDecode.h, LzmaDecode.c +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 (~16 KB for default settings) + - LZMA Internal Structures: state_size (16 KB for default settings) Interface: - int res = LzmaDecode(&state, - inStream, compressedSize, &inProcessed, - outStream, outSize, &outProcessed); + 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 -5.2 Single-call Decompressing with input stream callback --------------------------------------------------------- -When to use: File->RAM or Flash->RAM decompressing. -Compile files: LzmaDecode.h, LzmaDecode.c -Compile defines: _LZMA_IN_CB Memory Requirements: - - Buffer for input stream: any size (for example, 16 KB) - - Output buffer: uncompressed size - - LZMA Internal Structures (~16 KB for default settings) + - 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) -Interface: - typedef struct _CBuffer - { - ILzmaInCallback InCallback; - FILE *File; - unsigned char Buffer[kInBufferSize]; - } CBuffer; +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) - int LzmaReadCompressed(void *object, const unsigned char **buffer, SizeT *size) +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 (;;) { - CBuffer *bo = (CBuffer *)object; - *buffer = bo->Buffer; - *size = MyReadFile(bo->File, bo->Buffer, kInBufferSize); - return LZMA_RESULT_OK; + ... + int res = LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, + const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode); + ... } - CBuffer g_InBuffer; - g_InBuffer.File = inFile; - g_InBuffer.InCallback.Read = LzmaReadCompressed; - int res = LzmaDecode(&state, - &g_InBuffer.InCallback, - outStream, outSize, &outProcessed); +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 -5.3 Multi-call decompressing with output buffer ------------------------------------------------ -When to use: RAM->File decompressing -Compile files: LzmaDecode.h, LzmaDecode.c -Compile defines: _LZMA_OUT_READ Memory Requirements: - - Input buffer: compressed size - - Buffer for output stream: any size (for example, 16 KB) - - LZMA Internal Structures (~16 KB for default settings) - - LZMA dictionary (dictionary size is encoded in stream properties) + - (dictSize * 11.5 + 6 MB) + state_size -Interface: +Lzma Encoder can use two memory allocators: +1) alloc - for small arrays. +2) allocBig - for big arrays. - state.Dictionary = (unsigned char *)malloc(state.Properties.DictionarySize); +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. - LzmaDecoderInit(&state); - do - { - LzmaDecode(&state, - inBuffer, inAvail, &inProcessed, - g_OutBuffer, outAvail, &outProcessed); - inAvail -= inProcessed; - inBuffer += inProcessed; - } - while you need more bytes - see LzmaTest.c for more details. +Single-call Compression with callbacks +-------------------------------------- +Check C/LzmaUtil/LzmaUtil.c as example, -5.4 Multi-call decompressing with input callback and output buffer ------------------------------------------------------------------- -When to use: File->File decompressing -Compile files: LzmaDecode.h, LzmaDecode.c -Compile defines: _LZMA_IN_CB, _LZMA_OUT_READ -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 (~16 KB for default settings) - - LZMA dictionary (dictionary size is encoded in stream properties) +When to use: file->file decompressing -Interface: +1) you must implement callback structures for interfaces: +ISeqInStream +ISeqOutStream +ICompressProgress +ISzAlloc - state.Dictionary = (unsigned char *)malloc(state.Properties.DictionarySize); +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 }; - LzmaDecoderInit(&state); - do - { - LzmaDecode(&state, - &bo.InCallback, - g_OutBuffer, outAvail, &outProcessed); - } - while you need more bytes + CFileSeqInStream inStream; + CFileSeqOutStream outStream; - see LzmaTest.c for more details: + inStream.funcTable.Read = MyRead; + inStream.file = inFile; + outStream.funcTable.Write = MyWrite; + outStream.file = outFile; -5.5 Multi-call State Decompressing (zlib-like interface) ------------------------------------------------------------------- -When to use: file->file decompressing -Compile files: LzmaStateDecode.h, LzmaStateDecode.c -Compile defines: -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 (~16 KB for default settings) - - LZMA dictionary (dictionary size is encoded in stream properties) +2) Create CLzmaEncHandle object; -Interface: + CLzmaEncHandle enc; - state.Dictionary = (unsigned char *)malloc(state.Properties.DictionarySize); + enc = LzmaEnc_Create(&g_Alloc); + if (enc == 0) + return SZ_ERROR_MEM; - LzmaDecoderInit(&state); - do - { - res = LzmaDecode(&state, - inBuffer, inAvail, &inProcessed, - g_OutBuffer, outAvail, &outProcessed, - finishDecoding); - inAvail -= inProcessed; - inBuffer += inProcessed; - } - while you need more bytes +3) initialize CLzmaEncProps properties; - see LzmaStateTest.c for more details: + LzmaEncProps_Init(&props); + Then you can change some properties in that structure. -6) Free all allocated blocks +4) Send LZMA properties to LZMA Encoder + res = LzmaEnc_SetProps(enc, &props); -Note ----- -LzmaDecodeSize.c is size-optimized version of LzmaDecode.c. -But compiled code of LzmaDecodeSize.c can be larger than -compiled code of LzmaDecode.c. So it's better to use -LzmaDecode.c in most cases. +5) Write encoded properties to header + Byte header[LZMA_PROPS_SIZE + 8]; + size_t headerSize = LZMA_PROPS_SIZE; + UInt64 fileSize; + int i; -EXIT codes ------------ + 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) -LZMA decoder can return one of the following codes: +6) Call encoding function: + res = LzmaEnc_Encode(enc, &outStream.funcTable, &inStream.funcTable, + NULL, &g_Alloc, &g_Alloc); -#define LZMA_RESULT_OK 0 -#define LZMA_RESULT_DATA_ERROR 1 +7) Destroy LZMA Encoder Object + LzmaEnc_Destroy(enc, &g_Alloc, &g_Alloc); -If you use callback function for input data and you return some -error code, LZMA Decoder also returns that code. +If callback function return some error code, LzmaEnc_Encode also returns that code. -LZMA Defines ------------- +Single-call RAM->RAM Compression +-------------------------------- -_LZMA_IN_CB - Use callback for input data +Single-call RAM->RAM Compression is similar to Compression with callbacks, +but you provide pointers to buffers instead of pointers to stream callbacks: -_LZMA_OUT_READ - Use read function for output data +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); -_LZMA_LOC_OPT - Enable local speed optimizations inside code. - _LZMA_LOC_OPT is only for LzmaDecodeSize.c (size-optimized version). - _LZMA_LOC_OPT doesn't affect LzmaDecode.c (speed-optimized version) - and LzmaStateDecode.c +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_PROB32 - It can increase speed on some 32-bit CPUs, - but memory usage 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_SYSTEM_SIZE_T - Define it if you want to use system's size_t. - You can use it to enable 64-bit sizes supporting +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. -By default, LZMA Encoder contains all Match Finders. -But for compressing it's enough to have just one of them. -So for reducing size of compressing code you can define: - #define COMPRESS_MF_BT - #define COMPRESS_MF_BT4 -and it will use only bt4 match finder. +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 |