diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2017-05-07 15:53:50 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2017-05-07 15:53:50 +0000 |
commit | e2ee645667b471ed0171632bf0a5eb8ed9ae686c (patch) | |
tree | 28ee7e44cf26bac7727594aa85a7d9a7d13f9d27 | |
parent | Releasing debian version 1.8-5. (diff) | |
download | lzlib-e2ee645667b471ed0171632bf0a5eb8ed9ae686c.tar.xz lzlib-e2ee645667b471ed0171632bf0a5eb8ed9ae686c.zip |
Merging upstream version 1.9.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
-rw-r--r-- | COPYING | 345 | ||||
-rw-r--r-- | COPYING.GPL | 338 | ||||
-rw-r--r-- | ChangeLog | 13 | ||||
-rw-r--r-- | INSTALL | 2 | ||||
-rw-r--r-- | Makefile.in | 10 | ||||
-rw-r--r-- | NEWS | 20 | ||||
-rw-r--r-- | README | 14 | ||||
-rw-r--r-- | bbexample.c | 2 | ||||
-rw-r--r-- | carg_parser.c | 9 | ||||
-rw-r--r-- | carg_parser.h | 2 | ||||
-rw-r--r-- | cbuffer.c | 32 | ||||
-rwxr-xr-x | configure | 21 | ||||
-rw-r--r-- | decoder.c | 120 | ||||
-rw-r--r-- | decoder.h | 206 | ||||
-rw-r--r-- | doc/lzlib.info | 48 | ||||
-rw-r--r-- | doc/lzlib.texi | 24 | ||||
-rw-r--r-- | doc/minilzip.1 | 6 | ||||
-rw-r--r-- | encoder.c | 133 | ||||
-rw-r--r-- | encoder.h | 120 | ||||
-rw-r--r-- | encoder_base.c | 51 | ||||
-rw-r--r-- | encoder_base.h | 247 | ||||
-rw-r--r-- | fast_encoder.c | 84 | ||||
-rw-r--r-- | fast_encoder.h | 38 | ||||
-rw-r--r-- | lzcheck.c | 2 | ||||
-rw-r--r-- | lzip.h | 38 | ||||
-rw-r--r-- | lzlib.c | 46 | ||||
-rw-r--r-- | lzlib.h | 34 | ||||
-rw-r--r-- | main.c | 87 | ||||
-rwxr-xr-x | testsuite/check.sh | 271 | ||||
-rw-r--r-- | testsuite/test.txt.lz | bin | 7376 -> 7376 bytes |
30 files changed, 1187 insertions, 1176 deletions
@@ -1,338 +1,17 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 + Lzlib - Compression library for the lzip format + Copyright (C) Antonio Diaz Diaz. - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. + This library is free software. Redistribution and use in source and + binary forms, with or without modification, are permitted provided + that the following conditions are met: - Preamble + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, + 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) <year> <name of author> - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - <signature of Ty Coon>, 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. diff --git a/COPYING.GPL b/COPYING.GPL new file mode 100644 index 0000000..4ad17ae --- /dev/null +++ b/COPYING.GPL @@ -0,0 +1,338 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) <year> <name of author> + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. @@ -1,3 +1,12 @@ +2017-04-11 Antonio Diaz Diaz <antonio@gnu.org> + + * Version 1.9 released. + * Compression time of option '-0' has been reduced by 3%. + * Compression time of options -1 to -9 has been reduced by 1%. + * Decompression time has been reduced by 3%. + * main.c: Continue testing if any input file is a terminal. + * License of the library changed to "2-clause BSD". + 2016-05-17 Antonio Diaz Diaz <antonio@gnu.org> * Version 1.8 released. @@ -20,7 +29,7 @@ 2014-08-27 Antonio Diaz Diaz <antonio@gnu.org> * Version 1.6 released. - * Compression ratio of option -9 has been slightly increased. + * Compression ratio of option '-9' has been slightly increased. * configure: Added new option '--disable-static'. * configure: Added new option '--disable-ldconfig'. * Makefile.in: Ignore errors from ldconfig. @@ -165,7 +174,7 @@ * Version 0.1 released. -Copyright (C) 2009-2016 Antonio Diaz Diaz. +Copyright (C) 2009-2017 Antonio Diaz Diaz. This file is a collection of facts, and thus it is not copyrightable, but just in case, you have unlimited permission to copy, distribute and @@ -62,7 +62,7 @@ After running 'configure', you can run 'make' and 'make install' as explained above. -Copyright (C) 2009-2016 Antonio Diaz Diaz. +Copyright (C) 2009-2017 Antonio Diaz Diaz. This file is free documentation: you have unlimited permission to copy, distribute and modify it. diff --git a/Makefile.in b/Makefile.in index 02a1870..c493f5e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -15,7 +15,8 @@ objs = carg_parser.o main.o .PHONY : all install install-bin install-info install-man \ install-strip install-compress install-strip-compress \ install-bin-strip install-info-compress install-man-compress \ - install-as-lzip uninstall uninstall-bin uninstall-info uninstall-man \ + install-as-lzip \ + uninstall uninstall-bin uninstall-info uninstall-man \ doc info man check dist clean distclean all : $(progname_static) $(progname_shared) @@ -155,6 +156,7 @@ dist : doc tar -Hustar --owner=root --group=root -cvf $(DISTNAME).tar \ $(DISTNAME)/AUTHORS \ $(DISTNAME)/COPYING \ + $(DISTNAME)/COPYING.GPL \ $(DISTNAME)/ChangeLog \ $(DISTNAME)/INSTALL \ $(DISTNAME)/Makefile.in \ @@ -164,13 +166,13 @@ dist : doc $(DISTNAME)/doc/$(progname).1 \ $(DISTNAME)/doc/$(pkgname).info \ $(DISTNAME)/doc/$(pkgname).texi \ + $(DISTNAME)/*.h \ + $(DISTNAME)/*.c \ $(DISTNAME)/testsuite/check.sh \ $(DISTNAME)/testsuite/test.txt \ $(DISTNAME)/testsuite/test2.txt \ $(DISTNAME)/testsuite/test.txt.lz \ - $(DISTNAME)/testsuite/test_sync.lz \ - $(DISTNAME)/*.h \ - $(DISTNAME)/*.c + $(DISTNAME)/testsuite/test_sync.lz rm -f $(DISTNAME) lzip -v -9 $(DISTNAME).tar @@ -1,16 +1,12 @@ -Changes in version 1.8: +Changes in version 1.9: -The test of the value remaining in the range decoder has been removed. -(After extensive testing it has been found useless to detect corruption -in the decompressed data. Eliminating it reduces the number of false -positives for corruption and makes error detection more accurate). +Compression time of option '-0' has been reduced by 3%. -The option "-a, --trailing-error", which makes minilzip exit with error -status 2 if any remaining input is detected after decompressing the last -member, has been added. +Compression time of options '-1' to '-9' has been reduced by 1%. -When decompressing with minilzip, the file specified with the '--output' -option is now deleted if the input is a terminal. +Decompression time has been reduced by 3%. -A harmless check failure on Windows, caused by the failed comparison of -a message in text mode, has been fixed. +In test mode, minilzip now continues checking the rest of the files if +any input file is a terminal. + +The license of the library has been changed to "2-clause BSD". @@ -16,11 +16,11 @@ availability: merging of damaged copies of a file. * The lzip format is as simple as possible (but not simpler). The - lzip manual provides the code of a simple decompressor along with a - detailed explanation of how it works, so that with the only help of - the lzip manual it would be possible for a digital archaeologist to - extract the data from a lzip file long after quantum computers - eventually render LZMA obsolete. + lzip manual provides the source code of a simple decompressor along + with a detailed explanation of how it works, so that with the only + help of the lzip manual it would be possible for a digital + archaeologist to extract the data from a lzip file long after + quantum computers eventually render LZMA obsolete. * Additionally the lzip reference implementation is copylefted, which guarantees that it will remain free forever. @@ -42,7 +42,7 @@ traditional zlib interface. Compression/decompression is done when the read function is called. This means the value returned by the position functions will not be updated -until a read call, even if a lot of data is written. If you want the +until a read call, even if a lot of data are written. If you want the data to be compressed in advance, just call the read function with a size equal to 0. @@ -87,7 +87,7 @@ range encoding), Igor Pavlov (for putting all the above together in LZMA), and Julian Seward (for bzip2's CLI). -Copyright (C) 2009-2016 Antonio Diaz Diaz. +Copyright (C) 2009-2017 Antonio Diaz Diaz. This file is free documentation: you have unlimited permission to copy, distribute and modify it. diff --git a/bbexample.c b/bbexample.c index 6b1352b..ab9a6e0 100644 --- a/bbexample.c +++ b/bbexample.c @@ -1,5 +1,5 @@ /* Buffer to buffer example - Test program for the lzlib library - Copyright (C) 2010-2016 Antonio Diaz Diaz. + Copyright (C) 2010-2017 Antonio Diaz Diaz. This program is free software: you have unlimited permission to copy, distribute and modify it. diff --git a/carg_parser.c b/carg_parser.c index 3d4e89f..6850643 100644 --- a/carg_parser.c +++ b/carg_parser.c @@ -1,5 +1,5 @@ /* Arg_parser - POSIX/GNU command line argument parser. (C version) - Copyright (C) 2006-2016 Antonio Diaz Diaz. + Copyright (C) 2006-2017 Antonio Diaz Diaz. This library is free software. Redistribution and use in source and binary forms, with or without modification, are permitted provided @@ -94,7 +94,7 @@ static char parse_long_option( struct Arg_parser * const ap, else if( index < 0 ) index = i; /* First nonexact match found */ else if( options[index].code != options[i].code || options[index].has_arg != options[i].has_arg ) - ambig = 1; /* Second or later nonexact match found */ + ambig = 1; /* Second or later nonexact match found */ } if( ambig && !exact ) @@ -230,7 +230,9 @@ char ap_init( struct Arg_parser * const ap, } else { - if( !in_order ) + if( in_order ) + { if( !push_back_record( ap, 0, argv[argind++] ) ) return 0; } + else { void * tmp = ap_resize_buffer( non_options, ( non_options_size + 1 ) * sizeof *non_options ); @@ -238,7 +240,6 @@ char ap_init( struct Arg_parser * const ap, non_options = (const char **)tmp; non_options[non_options_size++] = argv[argind++]; } - else if( !push_back_record( ap, 0, argv[argind++] ) ) return 0; } } if( ap->error ) free_data( ap ); diff --git a/carg_parser.h b/carg_parser.h index e918942..c4ce31d 100644 --- a/carg_parser.h +++ b/carg_parser.h @@ -1,5 +1,5 @@ /* Arg_parser - POSIX/GNU command line argument parser. (C version) - Copyright (C) 2006-2016 Antonio Diaz Diaz. + Copyright (C) 2006-2017 Antonio Diaz Diaz. This library is free software. Redistribution and use in source and binary forms, with or without modification, are permitted provided @@ -1,28 +1,20 @@ /* Lzlib - Compression library for the lzip format - Copyright (C) 2009-2016 Antonio Diaz Diaz. + Copyright (C) 2009-2017 Antonio Diaz Diaz. - This library is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. + This library is free software. Redistribution and use in source and + binary forms, with or without modification, are permitted provided + that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this library. If not, see <http://www.gnu.org/licenses/>. - - As a special exception, you may use this file as part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this - file, or you compile this file and link it with other files to - produce an executable, this file does not by itself cause the - resulting executable to be covered by the GNU General Public - License. This exception does not however invalidate any other - reasons why the executable file might be covered by the GNU General - Public License. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ struct Circular_buffer @@ -1,12 +1,12 @@ #! /bin/sh # configure script for Lzlib - Compression library for the lzip format -# Copyright (C) 2009-2016 Antonio Diaz Diaz. +# Copyright (C) 2009-2017 Antonio Diaz Diaz. # # This configure script is free software: you have unlimited permission # to copy, distribute and modify it. pkgname=lzlib -pkgversion=1.8 +pkgversion=1.9 soversion=1 progname=minilzip progname_static=${progname} @@ -34,11 +34,11 @@ CFLAGS='-Wall -W -O2' LDFLAGS= # checking whether we are using GNU C. -if /bin/sh -c "${CC} --version" > /dev/null 2>&1 ; then true -else +/bin/sh -c "${CC} --version" > /dev/null 2>&1 || + { CC=cc - CFLAGS='-W -O2' -fi + CFLAGS=-O2 + } # Loop over all args args= @@ -60,9 +60,12 @@ while [ $# != 0 ] ; do # Process the options case ${option} in --help | -h) - echo "Usage: configure [options]" + echo "Usage: $0 [OPTION]... [VAR=VALUE]..." + echo + echo "To assign makefile variables (e.g., CC, CFLAGS...), specify them as" + echo "arguments to configure in the form VAR=VALUE." echo - echo "Options: [defaults in brackets]" + echo "Options and variables: [defaults in brackets]" echo " -h, --help display this help and exit" echo " -V, --version output version information and exit" echo " --srcdir=DIR find the sources in DIR [. or ..]" @@ -191,7 +194,7 @@ echo "LDFLAGS = ${LDFLAGS}" rm -f Makefile cat > Makefile << EOF # Makefile for Lzlib - Compression library for the lzip format -# Copyright (C) 2009-2016 Antonio Diaz Diaz. +# Copyright (C) 2009-2017 Antonio Diaz Diaz. # This file was generated automatically by configure. Don't edit. # # This Makefile is free software: you have unlimited permission @@ -1,41 +1,35 @@ /* Lzlib - Compression library for the lzip format - Copyright (C) 2009-2016 Antonio Diaz Diaz. + Copyright (C) 2009-2017 Antonio Diaz Diaz. - This library is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. + This library is free software. Redistribution and use in source and + binary forms, with or without modification, are permitted provided + that the following conditions are met: - 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 General Public License for more details. + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. - You should have received a copy of the GNU General Public License - along with this library. If not, see <http://www.gnu.org/licenses/>. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. - As a special exception, you may use this file as part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this - file, or you compile this file and link it with other files to - produce an executable, this file does not by itself cause the - resulting executable to be covered by the GNU General Public - License. This exception does not however invalidate any other - reasons why the executable file might be covered by the GNU General - Public License. + 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. */ -static bool LZd_verify_trailer( struct LZ_decoder * const d ) +static int LZd_try_verify_trailer( struct LZ_decoder * const d ) { File_trailer trailer; - int size = Rd_read_data( d->rdec, trailer, Ft_size ); - - if( size < Ft_size ) - return false; + if( Rd_available_bytes( d->rdec ) < Ft_size && !d->rdec->at_stream_end ) + return 0; + d->verify_trailer_pending = false; + d->member_finished = true; - return ( Ft_get_data_crc( trailer ) == LZd_crc( d ) && - Ft_get_data_size( trailer ) == LZd_data_position( d ) && - Ft_get_member_size( trailer ) == d->rdec->member_position ); + if( Rd_read_data( d->rdec, trailer, Ft_size ) == Ft_size && + Ft_get_data_crc( trailer ) == LZd_crc( d ) && + Ft_get_data_size( trailer ) == LZd_data_position( d ) && + Ft_get_member_size( trailer ) == d->rdec->member_position ) return 0; + return 3; } @@ -46,24 +40,17 @@ static int LZd_decode_member( struct LZ_decoder * const d ) { struct Range_decoder * const rdec = d->rdec; State * const state = &d->state; -/* unsigned long long old_mpos = d->rdec->member_position; */ + /* unsigned old_mpos = d->rdec->member_position; */ if( d->member_finished ) return 0; if( !Rd_try_reload( rdec, false ) ) { if( !rdec->at_stream_end ) return 0; else return 2; } - if( d->verify_trailer_pending ) - { - if( Rd_available_bytes( rdec ) < Ft_size && !rdec->at_stream_end ) - return 0; - d->verify_trailer_pending = false; - d->member_finished = true; - if( LZd_verify_trailer( d ) ) return 0; else return 3; - } + if( d->verify_trailer_pending ) return LZd_try_verify_trailer( d ); while( !Rd_finished( rdec ) ) { const int pos_state = LZd_data_position( d ) & pos_state_mask; -/* const unsigned long long mpos = d->rdec->member_position; + /* const unsigned mpos = d->rdec->member_position; if( mpos - old_mpos > rd_min_available_bytes ) return 5; old_mpos = mpos; */ if( !Rd_enough_available_bytes( rdec ) ) /* check unexpected eof */ @@ -71,19 +58,16 @@ static int LZd_decode_member( struct LZ_decoder * const d ) if( !LZd_enough_free_bytes( d ) ) return 0; if( Rd_decode_bit( rdec, &d->bm_match[*state][pos_state] ) == 0 ) /* 1st bit */ { - const uint8_t prev_byte = LZd_peek_prev( d ); + Bit_model * const bm = d->bm_literal[get_lit_state(LZd_peek_prev( d ))]; if( St_is_char( *state ) ) { *state -= ( *state < 4 ) ? *state : 3; - LZd_put_byte( d, Rd_decode_tree( rdec, - d->bm_literal[get_lit_state(prev_byte)], 8 ) ); + LZd_put_byte( d, Rd_decode_tree8( rdec, bm ) ); } else { *state -= ( *state < 10 ) ? 3 : 6; - LZd_put_byte( d, Rd_decode_matched( rdec, - d->bm_literal[get_lit_state(prev_byte)], - LZd_peek( d, d->rep0 ) ) ); + LZd_put_byte( d, Rd_decode_matched( rdec, bm, LZd_peek( d, d->rep0 ) ) ); } } else /* match or repeated match */ @@ -91,7 +75,13 @@ static int LZd_decode_member( struct LZ_decoder * const d ) int len; if( Rd_decode_bit( rdec, &d->bm_rep[*state] ) != 0 ) /* 2nd bit */ { - if( Rd_decode_bit( rdec, &d->bm_rep0[*state] ) != 0 ) /* 3rd bit */ + if( Rd_decode_bit( rdec, &d->bm_rep0[*state] ) == 0 ) /* 3rd bit */ + { + if( Rd_decode_bit( rdec, &d->bm_len[*state][pos_state] ) == 0 ) /* 4th bit */ + { *state = St_set_short_rep( *state ); + LZd_put_byte( d, LZd_peek( d, d->rep0 ) ); continue; } + } + else { unsigned distance; if( Rd_decode_bit( rdec, &d->bm_rep1[*state] ) == 0 ) /* 4th bit */ @@ -107,43 +97,34 @@ static int LZd_decode_member( struct LZ_decoder * const d ) d->rep1 = d->rep0; d->rep0 = distance; } - else - { - if( Rd_decode_bit( rdec, &d->bm_len[*state][pos_state] ) == 0 ) /* 4th bit */ - { *state = St_set_short_rep( *state ); - LZd_put_byte( d, LZd_peek( d, d->rep0 ) ); continue; } - } *state = St_set_rep( *state ); len = min_match_len + Rd_decode_len( rdec, &d->rep_len_model, pos_state ); } else /* match */ { - const unsigned rep0_saved = d->rep0; - int dis_slot; + unsigned distance; len = min_match_len + Rd_decode_len( rdec, &d->match_len_model, pos_state ); - dis_slot = Rd_decode_tree6( rdec, d->bm_dis_slot[get_len_state(len)] ); - if( dis_slot < start_dis_model ) d->rep0 = dis_slot; - else + distance = Rd_decode_tree6( rdec, d->bm_dis_slot[get_len_state(len)] ); + if( distance >= start_dis_model ) { + const unsigned dis_slot = distance; const int direct_bits = ( dis_slot >> 1 ) - 1; - d->rep0 = ( 2 | ( dis_slot & 1 ) ) << direct_bits; + distance = ( 2 | ( dis_slot & 1 ) ) << direct_bits; if( dis_slot < end_dis_model ) - d->rep0 += Rd_decode_tree_reversed( rdec, - d->bm_dis + d->rep0 - dis_slot - 1, direct_bits ); + distance += Rd_decode_tree_reversed( rdec, + d->bm_dis + ( distance - dis_slot ), direct_bits ); else { - d->rep0 += Rd_decode( rdec, direct_bits - dis_align_bits ) << dis_align_bits; - d->rep0 += Rd_decode_tree_reversed4( rdec, d->bm_align ); - if( d->rep0 == 0xFFFFFFFFU ) /* marker found */ + distance += + Rd_decode( rdec, direct_bits - dis_align_bits ) << dis_align_bits; + distance += Rd_decode_tree_reversed4( rdec, d->bm_align ); + if( distance == 0xFFFFFFFFU ) /* marker found */ { - d->rep0 = rep0_saved; Rd_normalize( rdec ); if( len == min_match_len ) /* End Of Stream marker */ { - if( Rd_available_bytes( rdec ) < Ft_size && !rdec->at_stream_end ) - { d->verify_trailer_pending = true; return 0; } - d->member_finished = true; - if( LZd_verify_trailer( d ) ) return 0; else return 3; + d->verify_trailer_pending = true; + return LZd_try_verify_trailer( d ); } if( len == min_match_len + 1 ) /* Sync Flush marker */ { @@ -154,11 +135,10 @@ static int LZd_decode_member( struct LZ_decoder * const d ) } } } - d->rep3 = d->rep2; d->rep2 = d->rep1; d->rep1 = rep0_saved; + d->rep3 = d->rep2; d->rep2 = d->rep1; d->rep1 = d->rep0; d->rep0 = distance; *state = St_set_match( *state ); if( d->rep0 >= d->dictionary_size || - ( d->rep0 >= d->cb.put && !d->pos_wrapped ) ) - return 1; + ( d->rep0 >= d->cb.put && !d->pos_wrapped ) ) return 1; } LZd_copy_block( d, d->rep0, len ); } @@ -1,28 +1,20 @@ /* Lzlib - Compression library for the lzip format - Copyright (C) 2009-2016 Antonio Diaz Diaz. + Copyright (C) 2009-2017 Antonio Diaz Diaz. - This library is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. + This library is free software. Redistribution and use in source and + binary forms, with or without modification, are permitted provided + that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this library. If not, see <http://www.gnu.org/licenses/>. - - As a special exception, you may use this file as part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this - file, or you compile this file and link it with other files to - produce an executable, this file does not by itself cause the - resulting executable to be covered by the GNU General Public - License. This exception does not however invalidate any other - reasons why the executable file might be covered by the GNU General - Public License. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ enum { rd_min_available_bytes = 8 }; @@ -84,7 +76,7 @@ static inline void Rd_reset( struct Range_decoder * const rdec ) number of bytes skipped. Returns true if it finds a valid header. */ static bool Rd_find_header( struct Range_decoder * const rdec, - int * const skippedp ) + unsigned * const skippedp ) { *skippedp = 0; while( rdec->cb.get != rdec->cb.put ) @@ -158,34 +150,30 @@ static bool Rd_try_reload( struct Range_decoder * const rdec, const bool force ) static inline void Rd_normalize( struct Range_decoder * const rdec ) { if( rdec->range <= 0x00FFFFFFU ) - { - rdec->range <<= 8; - rdec->code = (rdec->code << 8) | Rd_get_byte( rdec ); - } + { rdec->range <<= 8; rdec->code = (rdec->code << 8) | Rd_get_byte( rdec ); } } -static inline int Rd_decode( struct Range_decoder * const rdec, - const int num_bits ) +static inline unsigned Rd_decode( struct Range_decoder * const rdec, + const int num_bits ) { - int symbol = 0; + unsigned symbol = 0; int i; for( i = num_bits; i > 0; --i ) { - uint32_t mask; + bool bit; Rd_normalize( rdec ); rdec->range >>= 1; /* symbol <<= 1; */ /* if( rdec->code >= rdec->range ) { rdec->code -= rdec->range; symbol |= 1; } */ - mask = 0U - (rdec->code < rdec->range); - rdec->code -= rdec->range; - rdec->code += rdec->range & mask; - symbol = (symbol << 1) + (mask + 1); + bit = ( rdec->code >= rdec->range ); + symbol = ( symbol << 1 ) + bit; + rdec->code -= rdec->range & ( 0U - bit ); } return symbol; } -static inline int Rd_decode_bit( struct Range_decoder * const rdec, - Bit_model * const probability ) +static inline unsigned Rd_decode_bit( struct Range_decoder * const rdec, + Bit_model * const probability ) { uint32_t bound; Rd_normalize( rdec ); @@ -205,20 +193,20 @@ static inline int Rd_decode_bit( struct Range_decoder * const rdec, } } -static inline int Rd_decode_tree( struct Range_decoder * const rdec, - Bit_model bm[], const int num_bits ) +static inline unsigned Rd_decode_tree3( struct Range_decoder * const rdec, + Bit_model bm[] ) { - int symbol = 1; - int i; - for( i = num_bits; i > 0; --i ) - symbol = ( symbol << 1 ) | Rd_decode_bit( rdec, &bm[symbol] ); - return symbol - (1 << num_bits); + unsigned symbol = 1; + symbol = ( symbol << 1 ) | Rd_decode_bit( rdec, &bm[symbol] ); + symbol = ( symbol << 1 ) | Rd_decode_bit( rdec, &bm[symbol] ); + symbol = ( symbol << 1 ) | Rd_decode_bit( rdec, &bm[symbol] ); + return symbol & 7; } -static inline int Rd_decode_tree6( struct Range_decoder * const rdec, - Bit_model bm[] ) +static inline unsigned Rd_decode_tree6( struct Range_decoder * const rdec, + Bit_model bm[] ) { - int symbol = 1; + unsigned symbol = 1; symbol = ( symbol << 1 ) | Rd_decode_bit( rdec, &bm[symbol] ); symbol = ( symbol << 1 ) | Rd_decode_bit( rdec, &bm[symbol] ); symbol = ( symbol << 1 ) | Rd_decode_bit( rdec, &bm[symbol] ); @@ -228,69 +216,69 @@ static inline int Rd_decode_tree6( struct Range_decoder * const rdec, return symbol & 0x3F; } -static inline int Rd_decode_tree_reversed( struct Range_decoder * const rdec, - Bit_model bm[], const int num_bits ) +static inline unsigned Rd_decode_tree8( struct Range_decoder * const rdec, + Bit_model bm[] ) { - int model = 1; - int symbol = 0; + unsigned symbol = 1; + int i; + for( i = 0; i < 8; ++i ) + symbol = ( symbol << 1 ) | Rd_decode_bit( rdec, &bm[symbol] ); + return symbol & 0xFF; + } + +static inline unsigned +Rd_decode_tree_reversed( struct Range_decoder * const rdec, + Bit_model bm[], const int num_bits ) + { + unsigned model = 1; + unsigned symbol = 0; int i; for( i = 0; i < num_bits; ++i ) { - const bool bit = Rd_decode_bit( rdec, &bm[model] ); - model <<= 1; - if( bit ) { ++model; symbol |= (1 << i); } + const unsigned bit = Rd_decode_bit( rdec, &bm[model] ); + model = ( model << 1 ) + bit; + symbol |= ( bit << i ); } return symbol; } -static inline int Rd_decode_tree_reversed4( struct Range_decoder * const rdec, - Bit_model bm[] ) +static inline unsigned +Rd_decode_tree_reversed4( struct Range_decoder * const rdec, Bit_model bm[] ) { - int model = 1; - int symbol = Rd_decode_bit( rdec, &bm[model] ); - int bit; - model = (model << 1) + symbol; + unsigned symbol = Rd_decode_bit( rdec, &bm[1] ); + unsigned model = 2 + symbol; + unsigned bit = Rd_decode_bit( rdec, &bm[model] ); + model = ( model << 1 ) + bit; symbol |= ( bit << 1 ); bit = Rd_decode_bit( rdec, &bm[model] ); - model = (model << 1) + bit; symbol |= (bit << 1); - bit = Rd_decode_bit( rdec, &bm[model] ); - model = (model << 1) + bit; symbol |= (bit << 2); - if( Rd_decode_bit( rdec, &bm[model] ) ) symbol |= 8; + model = ( model << 1 ) + bit; symbol |= ( bit << 2 ); + symbol |= ( Rd_decode_bit( rdec, &bm[model] ) << 3 ); return symbol; } -static inline int Rd_decode_matched( struct Range_decoder * const rdec, - Bit_model bm[], int match_byte ) +static inline unsigned Rd_decode_matched( struct Range_decoder * const rdec, + Bit_model bm[], unsigned match_byte ) { - Bit_model * const bm1 = bm + 0x100; - int symbol = 1; - while( symbol < 0x100 ) + unsigned symbol = 1; + unsigned mask = 0x100; + while( true ) { - int match_bit, bit; - match_byte <<= 1; - match_bit = match_byte & 0x100; - bit = Rd_decode_bit( rdec, &bm1[match_bit+symbol] ); - symbol = ( symbol << 1 ) | bit; - if( match_bit != bit << 8 ) - { - while( symbol < 0x100 ) - symbol = ( symbol << 1 ) | Rd_decode_bit( rdec, &bm[symbol] ); - break; - } + const unsigned match_bit = ( match_byte <<= 1 ) & mask; + const unsigned bit = Rd_decode_bit( rdec, &bm[symbol+match_bit+mask] ); + symbol = ( symbol << 1 ) + bit; + if( symbol > 0xFF ) return symbol & 0xFF; + mask &= ~(match_bit ^ (bit << 8)); /* if( match_bit != bit ) mask = 0; */ } - return symbol & 0xFF; } -static inline int Rd_decode_len( struct Range_decoder * const rdec, - struct Len_model * const lm, - const int pos_state ) +static inline unsigned Rd_decode_len( struct Range_decoder * const rdec, + struct Len_model * const lm, + const int pos_state ) { if( Rd_decode_bit( rdec, &lm->choice1 ) == 0 ) - return Rd_decode_tree( rdec, lm->bm_low[pos_state], len_low_bits ); + return Rd_decode_tree3( rdec, lm->bm_low[pos_state] ); if( Rd_decode_bit( rdec, &lm->choice2 ) == 0 ) - return len_low_symbols + - Rd_decode_tree( rdec, lm->bm_mid[pos_state], len_mid_bits ); - return len_low_symbols + len_mid_symbols + - Rd_decode_tree( rdec, lm->bm_high, len_high_bits ); + return len_low_symbols + Rd_decode_tree3( rdec, lm->bm_mid[pos_state] ); + return len_low_symbols + len_mid_symbols + Rd_decode_tree8( rdec, lm->bm_high ); } @@ -320,7 +308,7 @@ struct LZ_decoder Bit_model bm_rep2[states]; Bit_model bm_len[states][pos_states]; Bit_model bm_dis_slot[len_states][1<<dis_slot_bits]; - Bit_model bm_dis[modeled_distances-end_dis_model]; + Bit_model bm_dis[modeled_distances-end_dis_model+1]; Bit_model bm_align[dis_align_size]; struct Len_model match_len_model; @@ -332,15 +320,16 @@ static inline bool LZd_enough_free_bytes( const struct LZ_decoder * const d ) static inline uint8_t LZd_peek_prev( const struct LZ_decoder * const d ) { - const unsigned i = ( ( d->cb.put > 0 ) ? d->cb.put : d->cb.buffer_size ) - 1; - return d->cb.buffer[i]; + if( d->cb.put > 0 ) return d->cb.buffer[d->cb.put-1]; + if( d->pos_wrapped ) return d->cb.buffer[d->cb.buffer_size-1]; + return 0; /* prev_byte of first byte */ } static inline uint8_t LZd_peek( const struct LZ_decoder * const d, const unsigned distance ) { - unsigned i = d->cb.put - distance - 1; - if( d->cb.put <= distance ) i += d->cb.buffer_size; + const unsigned i = ( ( d->cb.put > distance ) ? 0 : d->cb.buffer_size ) + + d->cb.put - distance - 1; return d->cb.buffer[i]; } @@ -355,18 +344,28 @@ static inline void LZd_put_byte( struct LZ_decoder * const d, const uint8_t b ) static inline void LZd_copy_block( struct LZ_decoder * const d, const unsigned distance, unsigned len ) { - unsigned i = d->cb.put - distance - 1; - bool fast; - if( d->cb.put <= distance ) - { i += d->cb.buffer_size; - fast = ( len <= d->cb.buffer_size - i && len <= i - d->cb.put ); } + unsigned lpos = d->cb.put, i = lpos - distance - 1; + bool fast, fast2; + if( lpos > distance ) + { + fast = ( len < d->cb.buffer_size - lpos ); + fast2 = ( fast && len <= lpos - i ); + } else - fast = ( len < d->cb.buffer_size - d->cb.put && len <= d->cb.put - i ); - if( fast ) /* no wrap, no overlap */ { - CRC32_update_buf( &d->crc, d->cb.buffer + i, len ); - memcpy( d->cb.buffer + d->cb.put, d->cb.buffer + i, len ); - d->cb.put += len; + i += d->cb.buffer_size; + fast = ( len < d->cb.buffer_size - i ); /* (i == pos) may happen */ + fast2 = ( fast && len <= i - lpos ); + } + if( fast ) /* no wrap */ + { + const unsigned tlen = len; + if( fast2 ) /* no wrap, no overlap */ + memcpy( d->cb.buffer + lpos, d->cb.buffer + i, len ); + else + for( ; len > 0; --len ) d->cb.buffer[lpos++] = d->cb.buffer[i++]; + CRC32_update_buf( &d->crc, d->cb.buffer + d->cb.put, tlen ); + d->cb.put += tlen; } else for( ; len > 0; --len ) { @@ -402,11 +401,10 @@ static inline bool LZd_init( struct LZ_decoder * const d, Bm_array_init( d->bm_rep2, states ); Bm_array_init( d->bm_len[0], states * pos_states ); Bm_array_init( d->bm_dis_slot[0], len_states * (1 << dis_slot_bits) ); - Bm_array_init( d->bm_dis, modeled_distances - end_dis_model ); + Bm_array_init( d->bm_dis, modeled_distances - end_dis_model + 1 ); Bm_array_init( d->bm_align, dis_align_size ); Lm_init( &d->match_len_model ); Lm_init( &d->rep_len_model ); - d->cb.buffer[d->cb.buffer_size-1] = 0; /* prev_byte of first byte */ return true; } diff --git a/doc/lzlib.info b/doc/lzlib.info index a9f47b3..a2a8c68 100644 --- a/doc/lzlib.info +++ b/doc/lzlib.info @@ -11,7 +11,7 @@ File: lzlib.info, Node: Top, Next: Introduction, Up: (dir) Lzlib Manual ************ -This manual is for Lzlib (version 1.8, 17 May 2016). +This manual is for Lzlib (version 1.9, 11 April 2017). * Menu: @@ -29,7 +29,7 @@ This manual is for Lzlib (version 1.8, 17 May 2016). * Concept index:: Index of concepts - Copyright (C) 2009-2016 Antonio Diaz Diaz. + Copyright (C) 2009-2017 Antonio Diaz Diaz. This manual is free documentation: you have unlimited permission to copy, distribute and modify it. @@ -57,11 +57,11 @@ availability: (lziprecover)Data safety. * The lzip format is as simple as possible (but not simpler). The - lzip manual provides the code of a simple decompressor along with - a detailed explanation of how it works, so that with the only help - of the lzip manual it would be possible for a digital - archaeologist to extract the data from a lzip file long after - quantum computers eventually render LZMA obsolete. + lzip manual provides the source code of a simple decompressor + along with a detailed explanation of how it works, so that with + the only help of the lzip manual it would be possible for a + digital archaeologist to extract the data from a lzip file long + after quantum computers eventually render LZMA obsolete. * Additionally the lzip reference implementation is copylefted, which guarantees that it will remain free forever. @@ -83,7 +83,7 @@ traditional zlib interface. Compression/decompression is done when the read function is called. This means the value returned by the position functions will not be -updated until a read call, even if a lot of data is written. If you +updated until a read call, even if a lot of data are written. If you want the data to be compressed in advance, just call the read function with a SIZE equal to 0. @@ -128,6 +128,10 @@ Markov (for the definition of Markov chains), G.N.N. Martin (for the definition of range encoding), Igor Pavlov (for putting all the above together in LZMA), and Julian Seward (for bzip2's CLI). + LANGUAGE NOTE: Uncompressed = not compressed = plain data; it may +never have been compressed. Decompressed is used to refer to data which +have undergone the process of decompression. + File: lzlib.info, Node: Library version, Next: Buffering, Prev: Introduction, Up: Top @@ -258,7 +262,7 @@ calling 'LZ_compress_errno' before using it. Frees all dynamically allocated data structures for this stream. This function discards any unprocessed input and does not flush any pending output. After a call to 'LZ_compress_close', ENCODER - can no more be used as an argument to any LZ_compress function. + can no longer be used as an argument to any LZ_compress function. -- Function: int LZ_compress_finish ( struct LZ_Encoder * const ENCODER ) @@ -375,7 +379,7 @@ verified by calling 'LZ_decompress_errno' before using it. Frees all dynamically allocated data structures for this stream. This function discards any unprocessed input and does not flush any pending output. After a call to 'LZ_decompress_close', DECODER - can no more be used as an argument to any LZ_decompress function. + can no longer be used as an argument to any LZ_decompress function. -- Function: int LZ_decompress_finish ( struct LZ_Decoder * const DECODER ) @@ -786,18 +790,18 @@ Concept index Tag Table: Node: Top220 -Node: Introduction1301 -Node: Library version5918 -Node: Buffering6563 -Node: Parameter limits7783 -Node: Compression functions8742 -Node: Decompression functions15282 -Node: Error codes21450 -Node: Error messages23425 -Node: Data format24004 -Node: Examples26569 -Node: Problems30650 -Node: Concept index31222 +Node: Introduction1303 +Node: Library version6115 +Node: Buffering6760 +Node: Parameter limits7980 +Node: Compression functions8939 +Node: Decompression functions15481 +Node: Error codes21651 +Node: Error messages23626 +Node: Data format24205 +Node: Examples26770 +Node: Problems30851 +Node: Concept index31423 End Tag Table diff --git a/doc/lzlib.texi b/doc/lzlib.texi index bc3b9fe..8b4aaaf 100644 --- a/doc/lzlib.texi +++ b/doc/lzlib.texi @@ -6,8 +6,8 @@ @finalout @c %**end of header -@set UPDATED 17 May 2016 -@set VERSION 1.8 +@set UPDATED 11 April 2017 +@set VERSION 1.9 @dircategory Data Compression @direntry @@ -50,7 +50,7 @@ This manual is for Lzlib (version @value{VERSION}, @value{UPDATED}). @end menu @sp 1 -Copyright @copyright{} 2009-2016 Antonio Diaz Diaz. +Copyright @copyright{} 2009-2017 Antonio Diaz Diaz. This manual is free documentation: you have unlimited permission to copy, distribute and modify it. @@ -83,10 +83,10 @@ including error-checked merging of damaged copies of a file. @item The lzip format is as simple as possible (but not simpler). The lzip -manual provides the code of a simple decompressor along with a detailed -explanation of how it works, so that with the only help of the lzip -manual it would be possible for a digital archaeologist to extract the -data from a lzip file long after quantum computers eventually render +manual provides the source code of a simple decompressor along with a +detailed explanation of how it works, so that with the only help of the +lzip manual it would be possible for a digital archaeologist to extract +the data from a lzip file long after quantum computers eventually render LZMA obsolete. @item @@ -111,7 +111,7 @@ traditional zlib interface. Compression/decompression is done when the read function is called. This means the value returned by the position functions will not be updated -until a read call, even if a lot of data is written. If you want the +until a read call, even if a lot of data are written. If you want the data to be compressed in advance, just call the read function with a @var{size} equal to 0. @@ -155,6 +155,10 @@ the definition of Markov chains), G.N.N. Martin (for the definition of range encoding), Igor Pavlov (for putting all the above together in LZMA), and Julian Seward (for bzip2's CLI). +LANGUAGE NOTE: Uncompressed = not compressed = plain data; it may never +have been compressed. Decompressed is used to refer to data which have +undergone the process of decompression. + @node Library version @chapter Library version @@ -293,7 +297,7 @@ for example INT64_MAX. Frees all dynamically allocated data structures for this stream. This function discards any unprocessed input and does not flush any pending output. After a call to @samp{LZ_compress_close}, @var{encoder} can no -more be used as an argument to any LZ_compress function. +longer be used as an argument to any LZ_compress function. @end deftypefun @@ -427,7 +431,7 @@ pointer must not be used and should be freed with Frees all dynamically allocated data structures for this stream. This function discards any unprocessed input and does not flush any pending output. After a call to @samp{LZ_decompress_close}, @var{decoder} can no -more be used as an argument to any LZ_decompress function. +longer be used as an argument to any LZ_decompress function. @end deftypefun diff --git a/doc/minilzip.1 b/doc/minilzip.1 index b5ebf78..3fefa02 100644 --- a/doc/minilzip.1 +++ b/doc/minilzip.1 @@ -1,5 +1,5 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.46.1. -.TH MINILZIP "1" "May 2016" "minilzip 1.8" "User Commands" +.TH MINILZIP "1" "April 2017" "minilzip 1.9" "User Commands" .SH NAME minilzip \- reduces the size of files .SH SYNOPSIS @@ -87,8 +87,8 @@ Report bugs to lzip\-bug@nongnu.org .br Lzlib home page: http://www.nongnu.org/lzip/lzlib.html .SH COPYRIGHT -Copyright \(co 2016 Antonio Diaz Diaz. -Using lzlib 1.8 +Copyright \(co 2017 Antonio Diaz Diaz. +Using lzlib 1.9 License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl.html> .br This is free software: you are free to change and redistribute it. @@ -1,28 +1,20 @@ /* Lzlib - Compression library for the lzip format - Copyright (C) 2009-2016 Antonio Diaz Diaz. + Copyright (C) 2009-2017 Antonio Diaz Diaz. - This library is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. + This library is free software. Redistribution and use in source and + binary forms, with or without modification, are permitted provided + that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this library. If not, see <http://www.gnu.org/licenses/>. - - As a special exception, you may use this file as part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this - file, or you compile this file and link it with other files to - produce an executable, this file does not by itself cause the - resulting executable to be covered by the GNU General Public - License. This exception does not however invalidate any other - reasons why the executable file might be covered by the GNU General - Public License. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ static int LZe_get_match_pairs( struct LZ_encoder * const e, struct Pair * pairs ) @@ -37,7 +29,7 @@ static int LZe_get_match_pairs( struct LZ_encoder * const e, struct Pair * pairs const int min_pos = ( e->eb.mb.pos > e->eb.mb.dictionary_size ) ? e->eb.mb.pos - e->eb.mb.dictionary_size : 0; const uint8_t * const data = Mb_ptr_to_current_pos( &e->eb.mb ); - int count, key2, key3, key4, newpos; + int count, key2, key3, key4, newpos1; unsigned tmp; int len_limit = e->match_len_limit; @@ -85,16 +77,16 @@ static int LZe_get_match_pairs( struct LZ_encoder * const e, struct Pair * pairs e->eb.mb.prev_positions[key2] = pos1; e->eb.mb.prev_positions[key3] = pos1; - newpos = e->eb.mb.prev_positions[key4]; + newpos1 = e->eb.mb.prev_positions[key4]; e->eb.mb.prev_positions[key4] = pos1; for( count = e->cycles; ; ) { int delta; - if( newpos <= min_pos || --count < 0 ) { *ptr0 = *ptr1 = 0; break; } + if( newpos1 <= min_pos || --count < 0 ) { *ptr0 = *ptr1 = 0; break; } if( e->been_flushed ) len = 0; - delta = pos1 - newpos; + delta = pos1 - newpos1; newptr = e->eb.mb.pos_array + ( ( e->eb.mb.cyclic_pos - delta + ( (e->eb.mb.cyclic_pos >= delta) ? 0 : e->eb.mb.dictionary_size + 1 ) ) << 1 ); @@ -116,16 +108,16 @@ static int LZe_get_match_pairs( struct LZ_encoder * const e, struct Pair * pairs } if( data[len-delta] < data[len] ) { - *ptr0 = newpos; + *ptr0 = newpos1; ptr0 = newptr + 1; - newpos = *ptr0; + newpos1 = *ptr0; len0 = len; if( len1 < len ) len = len1; } else { - *ptr1 = newpos; + *ptr1 = newpos1; ptr1 = newptr; - newpos = *ptr1; + newpos1 = *ptr1; len1 = len; if( len0 < len ) len = len0; } } @@ -141,7 +133,7 @@ static void LZe_update_distance_prices( struct LZ_encoder * const e ) const int dis_slot = dis_slots[dis]; const int direct_bits = ( dis_slot >> 1 ) - 1; const int base = ( 2 | ( dis_slot & 1 ) ) << direct_bits; - const int price = price_symbol_reversed( e->eb.bm_dis + base - dis_slot - 1, + const int price = price_symbol_reversed( e->eb.bm_dis + ( base - dis_slot ), dis - base, direct_bits ); for( len_state = 0; len_state < len_states; ++len_state ) e->dis_prices[len_state][dis] = price; @@ -154,9 +146,9 @@ static void LZe_update_distance_prices( struct LZ_encoder * const e ) const Bit_model * const bmds = e->eb.bm_dis_slot[len_state]; int slot = 0; for( ; slot < end_dis_model; ++slot ) - dsp[slot] = price_symbol( bmds, slot, dis_slot_bits ); + dsp[slot] = price_symbol6( bmds, slot ); for( ; slot < e->num_dis_slots; ++slot ) - dsp[slot] = price_symbol( bmds, slot, dis_slot_bits ) + + dsp[slot] = price_symbol6( bmds, slot ) + (((( slot >> 1 ) - 1 ) - dis_align_bits ) << price_shift_bits ); for( dis = 0; dis < start_dis_model; ++dis ) @@ -169,16 +161,16 @@ static void LZe_update_distance_prices( struct LZ_encoder * const e ) /* Returns the number of bytes advanced (ahead). trials[0]..trials[ahead-1] contain the steps to encode. - ( trials[0].dis == -1 ) means literal. + ( trials[0].dis4 == -1 ) means literal. A match/rep longer or equal than match_len_limit finishes the sequence. */ static int LZe_sequence_optimizer( struct LZ_encoder * const e, const int reps[num_rep_distances], const State state ) { - int main_len, num_pairs, i, rep, cur = 0, num_trials, len; + int main_len, num_pairs, i, rep, num_trials, len; + int rep_index = 0, cur = 0; int replens[num_rep_distances]; - int rep_index = 0; if( e->pending_num_pairs > 0 ) /* from previous call */ { @@ -191,13 +183,13 @@ static int LZe_sequence_optimizer( struct LZ_encoder * const e, for( i = 0; i < num_rep_distances; ++i ) { - replens[i] = Mb_true_match_len( &e->eb.mb, 0, reps[i] + 1, max_match_len ); + replens[i] = Mb_true_match_len( &e->eb.mb, 0, reps[i] + 1 ); if( replens[i] > replens[rep_index] ) rep_index = i; } if( replens[rep_index] >= e->match_len_limit ) { e->trials[0].price = replens[rep_index]; - e->trials[0].dis = rep_index; + e->trials[0].dis4 = rep_index; if( !LZe_move_and_update( e, replens[rep_index] ) ) return 0; return replens[rep_index]; } @@ -205,7 +197,7 @@ static int LZe_sequence_optimizer( struct LZ_encoder * const e, if( main_len >= e->match_len_limit ) { e->trials[0].price = main_len; - e->trials[0].dis = e->pairs[num_pairs-1].dis + num_rep_distances; + e->trials[0].dis4 = e->pairs[num_pairs-1].dis + num_rep_distances; if( !LZe_move_and_update( e, main_len ) ) return 0; return main_len; } @@ -223,7 +215,7 @@ static int LZe_sequence_optimizer( struct LZ_encoder * const e, e->trials[1].price += LZeb_price_literal( &e->eb, prev_byte, cur_byte ); else e->trials[1].price += LZeb_price_matched( &e->eb, prev_byte, cur_byte, match_byte ); - e->trials[1].dis = -1; /* literal */ + e->trials[1].dis4 = -1; /* literal */ if( match_byte == cur_byte ) Tr_update( &e->trials[1], rep_match_price + @@ -234,7 +226,7 @@ static int LZe_sequence_optimizer( struct LZ_encoder * const e, if( num_trials < min_match_len ) { e->trials[0].price = 1; - e->trials[0].dis = e->trials[1].dis; + e->trials[0].dis4 = e->trials[1].dis4; if( !Mb_move_pos( &e->eb.mb ) ) return 0; return 1; } @@ -259,7 +251,7 @@ static int LZe_sequence_optimizer( struct LZ_encoder * const e, if( main_len > replens[0] ) { const int normal_match_price = match_price + price0( e->eb.bm_rep[state] ); - i = 0, len = max( replens[0] + 1, min_match_len ); + int i = 0, len = max( replens[0] + 1, min_match_len ); while( len > e->pairs[i].len ) ++i; while( true ) { @@ -300,7 +292,7 @@ static int LZe_sequence_optimizer( struct LZ_encoder * const e, /* give final values to current trial */ cur_trial = &e->trials[cur]; { - int dis = cur_trial->dis; + const int dis4 = cur_trial->dis4; int prev_index = cur_trial->prev_index; const int prev_index2 = cur_trial->prev_index2; @@ -309,32 +301,24 @@ static int LZe_sequence_optimizer( struct LZ_encoder * const e, cur_state = e->trials[prev_index].state; if( prev_index + 1 == cur ) /* len == 1 */ { - if( dis == 0 ) cur_state = St_set_short_rep( cur_state ); + if( dis4 == 0 ) cur_state = St_set_short_rep( cur_state ); else cur_state = St_set_char( cur_state ); /* literal */ } - else if( dis < num_rep_distances ) cur_state = St_set_rep( cur_state ); + else if( dis4 < num_rep_distances ) cur_state = St_set_rep( cur_state ); else cur_state = St_set_match( cur_state ); } - else if( prev_index2 == dual_step_trial ) /* dis == 0 */ + else { - --prev_index; - cur_state = e->trials[prev_index].state; - cur_state = St_set_char( cur_state ); - cur_state = St_set_rep( cur_state ); - } - else /* if( prev_index2 >= 0 ) */ - { - prev_index = prev_index2; - cur_state = e->trials[prev_index].state; - if( dis < num_rep_distances ) cur_state = St_set_rep( cur_state ); - else cur_state = St_set_match( cur_state ); - cur_state = St_set_char( cur_state ); - cur_state = St_set_rep( cur_state ); + if( prev_index2 == dual_step_trial ) /* dis4 == 0 (rep0) */ + --prev_index; + else /* prev_index2 >= 0 */ + prev_index = prev_index2; + cur_state = 8; /* St_set_char_rep(); */ } cur_trial->state = cur_state; for( i = 0; i < num_rep_distances; ++i ) cur_trial->reps[i] = e->trials[prev_index].reps[i]; - mtf_reps( dis, cur_trial->reps ); + mtf_reps( dis4, cur_trial->reps ); /* literal is ignored */ } pos_state = Mb_data_position( &e->eb.mb ) & pos_state_mask; @@ -357,7 +341,7 @@ static int LZe_sequence_optimizer( struct LZ_encoder * const e, match_price = cur_trial->price + price1( e->eb.bm_match[cur_state][pos_state] ); rep_match_price = match_price + price1( e->eb.bm_rep[cur_state] ); - if( match_byte == cur_byte && next_trial->dis != 0 && + if( match_byte == cur_byte && next_trial->dis4 != 0 && next_trial->prev_index2 == single_step_trial ) { const int price = rep_match_price + @@ -365,7 +349,7 @@ static int LZe_sequence_optimizer( struct LZ_encoder * const e, if( price <= next_trial->price ) { next_trial->price = price; - next_trial->dis = 0; + next_trial->dis4 = 0; /* rep0 */ next_trial->prev_index = cur; } } @@ -382,16 +366,16 @@ static int LZe_sequence_optimizer( struct LZ_encoder * const e, const uint8_t * const data = Mb_ptr_to_current_pos( &e->eb.mb ); const int dis = cur_trial->reps[0] + 1; const int limit = min( e->match_len_limit + 1, triable_bytes ); - len = 1; + int len = 1; while( len < limit && data[len-dis] == data[len] ) ++len; if( --len >= min_match_len ) { const int pos_state2 = ( pos_state + 1 ) & pos_state_mask; const State state2 = St_set_char( cur_state ); const int price = next_price + - price1( e->eb.bm_match[state2][pos_state2] ) + - price1( e->eb.bm_rep[state2] ) + - LZe_price_rep0_len( e, len, state2, pos_state2 ); + price1( e->eb.bm_match[state2][pos_state2] ) + + price1( e->eb.bm_rep[state2] ) + + LZe_price_rep0_len( e, len, state2, pos_state2 ); while( num_trials < cur + 1 + len ) e->trials[++num_trials].price = infinite_price; Tr_update2( &e->trials[cur+1+len], price, cur + 1 ); @@ -402,8 +386,8 @@ static int LZe_sequence_optimizer( struct LZ_encoder * const e, for( rep = 0; rep < num_rep_distances; ++rep ) { const uint8_t * const data = Mb_ptr_to_current_pos( &e->eb.mb ); - int price; const int dis = cur_trial->reps[rep] + 1; + int price; if( data[0-dis] != data[0] || data[1-dis] != data[1] ) continue; for( len = min_match_len; len < len_limit; ++len ) @@ -459,7 +443,6 @@ static int LZe_sequence_optimizer( struct LZ_encoder * const e, for( len = start_len; ; ++len ) { int price = normal_match_price + LZe_price_pair( e, dis, len, pos_state ); - Tr_update( &e->trials[cur+len], price, dis + num_rep_distances, cur ); /* try match + literal + rep0 */ @@ -508,10 +491,7 @@ static bool LZe_encode_member( struct LZ_encoder * const e ) if( e->eb.member_finished ) return true; if( Re_member_position( &e->eb.renc ) >= e->eb.member_size_limit ) - { - if( LZeb_full_flush( &e->eb ) ) e->eb.member_finished = true; - return true; - } + { LZeb_try_full_flush( &e->eb ); return true; } if( Mb_data_position( &e->eb.mb ) == 0 && !Mb_data_finished( &e->eb.mb ) ) /* encode first byte */ @@ -548,7 +528,6 @@ static bool LZe_encode_member( struct LZ_encoder * const e ) } ahead = LZe_sequence_optimizer( e, e->eb.reps, *state ); - if( ahead <= 0 ) return false; /* can't happen */ e->price_counter -= ahead; for( i = 0; ahead > 0; ) @@ -556,7 +535,7 @@ static bool LZe_encode_member( struct LZ_encoder * const e ) const int pos_state = ( Mb_data_position( &e->eb.mb ) - ahead ) & pos_state_mask; const int len = e->trials[i].price; - const int dis = e->trials[i].dis; + int dis = e->trials[i].dis4; bool bit = ( dis < 0 ); Re_encode_bit( &e->eb.renc, &e->eb.bm_match[*state][pos_state], !bit ); @@ -602,9 +581,9 @@ static bool LZe_encode_member( struct LZ_encoder * const e ) } else /* match */ { - LZeb_encode_pair( &e->eb, dis - num_rep_distances, len, pos_state ); - if( get_slot( dis - num_rep_distances ) >= end_dis_model ) - --e->align_price_counter; + dis -= num_rep_distances; + LZeb_encode_pair( &e->eb, dis, len, pos_state ); + if( dis >= modeled_distances ) --e->align_price_counter; --e->dis_price_counter; Lp_decrement_counter( &e->match_len_prices, pos_state ); *state = St_set_match( *state ); @@ -614,11 +593,11 @@ static bool LZe_encode_member( struct LZ_encoder * const e ) if( Re_member_position( &e->eb.renc ) >= e->eb.member_size_limit ) { if( !Mb_dec_pos( &e->eb.mb, ahead ) ) return false; - if( LZeb_full_flush( &e->eb ) ) e->eb.member_finished = true; + LZeb_try_full_flush( &e->eb ); return true; } } } - if( LZeb_full_flush( &e->eb ) ) e->eb.member_finished = true; + LZeb_try_full_flush( &e->eb ); return true; } @@ -1,28 +1,20 @@ /* Lzlib - Compression library for the lzip format - Copyright (C) 2009-2016 Antonio Diaz Diaz. + Copyright (C) 2009-2017 Antonio Diaz Diaz. - This library is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. + This library is free software. Redistribution and use in source and + binary forms, with or without modification, are permitted provided + that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this library. If not, see <http://www.gnu.org/licenses/>. - - As a special exception, you may use this file as part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this - file, or you compile this file and link it with other files to - produce an executable, this file does not by itself cause the - resulting executable to be covered by the GNU General Public - License. This exception does not however invalidate any other - reasons why the executable file might be covered by the GNU General - Public License. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ struct Len_prices @@ -31,7 +23,7 @@ struct Len_prices int len_symbols; int count; int prices[pos_states][max_len_symbols]; - int counters[pos_states]; + int counters[pos_states]; /* may decrement below 0 */ }; static inline void Lp_update_low_mid_prices( struct Len_prices * const lp, @@ -40,14 +32,13 @@ static inline void Lp_update_low_mid_prices( struct Len_prices * const lp, int * const pps = lp->prices[pos_state]; int tmp = price0( lp->lm->choice1 ); int len = 0; - lp->counters[pos_state] = lp->count; for( ; len < len_low_symbols && len < lp->len_symbols; ++len ) - pps[len] = tmp + price_symbol( lp->lm->bm_low[pos_state], len, len_low_bits ); + pps[len] = tmp + price_symbol3( lp->lm->bm_low[pos_state], len ); if( len >= lp->len_symbols ) return; tmp = price1( lp->lm->choice1 ) + price0( lp->lm->choice2 ); for( ; len < len_low_symbols + len_mid_symbols && len < lp->len_symbols; ++len ) pps[len] = tmp + - price_symbol( lp->lm->bm_mid[pos_state], len - len_low_symbols, len_mid_bits ); + price_symbol3( lp->lm->bm_mid[pos_state], len - len_low_symbols ); } static inline void Lp_update_high_prices( struct Len_prices * const lp ) @@ -58,7 +49,7 @@ static inline void Lp_update_high_prices( struct Len_prices * const lp ) /* using 4 slots per value makes "Lp_price" faster */ lp->prices[3][len] = lp->prices[2][len] = lp->prices[1][len] = lp->prices[0][len] = tmp + - price_symbol( lp->lm->bm_high, len - len_low_symbols - len_mid_symbols, len_high_bits ); + price_symbol8( lp->lm->bm_high, len - len_low_symbols - len_mid_symbols ); } static inline void Lp_reset( struct Len_prices * const lp ) @@ -84,14 +75,15 @@ static inline void Lp_update_prices( struct Len_prices * const lp ) bool high_pending = false; for( pos_state = 0; pos_state < pos_states; ++pos_state ) if( lp->counters[pos_state] <= 0 ) - { Lp_update_low_mid_prices( lp, pos_state ); high_pending = true; } + { lp->counters[pos_state] = lp->count; + Lp_update_low_mid_prices( lp, pos_state ); high_pending = true; } if( high_pending && lp->len_symbols > len_low_symbols + len_mid_symbols ) Lp_update_high_prices( lp ); } static inline int Lp_price( const struct Len_prices * const lp, - const int symbol, const int pos_state ) - { return lp->prices[pos_state][symbol - min_match_len]; } + const int len, const int pos_state ) + { return lp->prices[pos_state][len - min_match_len]; } struct Pair /* distance-length pair */ @@ -109,7 +101,7 @@ struct Trial { State state; int price; /* dual use var; cumulative price, match length */ - int dis; /* rep index or match distance. (-1 for literal) */ + int dis4; /* -1 for literal, or rep, or match distance + 4 */ int prev_index; /* index of prev trial in trials[] */ int prev_index2; /* -2 trial is single step */ /* -1 literal + rep0 */ @@ -118,34 +110,28 @@ struct Trial }; static inline void Tr_update( struct Trial * const trial, const int pr, - const int distance, const int p_i ) + const int distance4, const int p_i ) { if( pr < trial->price ) - { - trial->price = pr; trial->dis = distance; trial->prev_index = p_i; - trial->prev_index2 = single_step_trial; - } + { trial->price = pr; trial->dis4 = distance4; trial->prev_index = p_i; + trial->prev_index2 = single_step_trial; } } static inline void Tr_update2( struct Trial * const trial, const int pr, const int p_i ) { if( pr < trial->price ) - { - trial->price = pr; trial->dis = 0; trial->prev_index = p_i; - trial->prev_index2 = dual_step_trial; - } + { trial->price = pr; trial->dis4 = 0; trial->prev_index = p_i; + trial->prev_index2 = dual_step_trial; } } static inline void Tr_update3( struct Trial * const trial, const int pr, - const int distance, const int p_i, + const int distance4, const int p_i, const int p_i2 ) { if( pr < trial->price ) - { - trial->price = pr; trial->dis = distance; trial->prev_index = p_i; - trial->prev_index2 = p_i2; - } + { trial->price = pr; trial->dis4 = distance4; trial->prev_index = p_i; + trial->prev_index2 = p_i2; } } @@ -164,7 +150,7 @@ struct LZ_encoder int dis_prices[len_states][modeled_distances]; int align_prices[dis_align_size]; int num_dis_slots; - int price_counter; + int price_counter; /* counters may decrement below 0 */ int dis_price_counter; int align_price_counter; bool been_flushed; @@ -175,26 +161,25 @@ static inline bool Mb_dec_pos( struct Matchfinder_base * const mb, { if( ahead < 0 || mb->pos < ahead ) return false; mb->pos -= ahead; + if( mb->cyclic_pos < ahead ) mb->cyclic_pos += mb->dictionary_size + 1; mb->cyclic_pos -= ahead; - if( mb->cyclic_pos < 0 ) mb->cyclic_pos += mb->dictionary_size + 1; return true; } static int LZe_get_match_pairs( struct LZ_encoder * const e, struct Pair * pairs ); - /* move-to-front dis in/into reps if( dis > 0 ) */ -static inline void mtf_reps( const int dis, int reps[num_rep_distances] ) + /* move-to-front dis in/into reps; do nothing if( dis4 <= 0 ) */ +static inline void mtf_reps( const int dis4, int reps[num_rep_distances] ) { - int i; - if( dis >= num_rep_distances ) + if( dis4 >= num_rep_distances ) /* match */ { - for( i = num_rep_distances - 1; i > 0; --i ) reps[i] = reps[i-1]; - reps[0] = dis - num_rep_distances; + reps[3] = reps[2]; reps[2] = reps[1]; reps[1] = reps[0]; + reps[0] = dis4 - num_rep_distances; } - else if( dis > 0 ) + else if( dis4 > 0 ) /* repeated match */ { - const int distance = reps[dis]; - for( i = dis; i > 0; --i ) reps[i] = reps[i-1]; + const int distance = reps[dis4]; + int i; for( i = dis4; i > 0; --i ) reps[i] = reps[i-1]; reps[0] = distance; } } @@ -206,8 +191,8 @@ static inline int LZeb_price_shortrep( const struct LZ_encoder_base * const eb, } static inline int LZeb_price_rep( const struct LZ_encoder_base * const eb, - const int rep, - const State state, const int pos_state ) + const int rep, const State state, + const int pos_state ) { int price; if( rep == 0 ) return price0( eb->bm_rep0[state] ) + @@ -224,8 +209,8 @@ static inline int LZeb_price_rep( const struct LZ_encoder_base * const eb, } static inline int LZe_price_rep0_len( const struct LZ_encoder * const e, - const int len, - const State state, const int pos_state ) + const int len, const State state, + const int pos_state ) { return LZeb_price_rep( &e->eb, 0, state, pos_state ) + Lp_price( &e->rep_len_prices, len, pos_state ); @@ -249,13 +234,10 @@ static inline int LZe_read_match_distances( struct LZ_encoder * const e ) const int num_pairs = LZe_get_match_pairs( e, e->pairs ); if( num_pairs > 0 ) { - int len = e->pairs[num_pairs-1].len; + const int len = e->pairs[num_pairs-1].len; if( len == e->match_len_limit && len < max_match_len ) - { - len += Mb_true_match_len( &e->eb.mb, len, e->pairs[num_pairs-1].dis + 1, - max_match_len - len ); - e->pairs[num_pairs-1].len = len; - } + e->pairs[num_pairs-1].len = + Mb_true_match_len( &e->eb.mb, len, e->pairs[num_pairs-1].dis + 1 ); } return num_pairs; } @@ -273,7 +255,7 @@ static inline bool LZe_move_and_update( struct LZ_encoder * const e, int n ) static inline void LZe_backward( struct LZ_encoder * const e, int cur ) { - int * const dis = &e->trials[cur].dis; + int dis4 = e->trials[cur].dis4; while( cur > 0 ) { const int prev_index = e->trials[cur].prev_index; @@ -281,19 +263,19 @@ static inline void LZe_backward( struct LZ_encoder * const e, int cur ) if( e->trials[cur].prev_index2 != single_step_trial ) { - prev_trial->dis = -1; + prev_trial->dis4 = -1; /* literal */ prev_trial->prev_index = prev_index - 1; prev_trial->prev_index2 = single_step_trial; if( e->trials[cur].prev_index2 >= 0 ) { struct Trial * const prev_trial2 = &e->trials[prev_index-1]; - prev_trial2->dis = *dis; *dis = 0; + prev_trial2->dis4 = dis4; dis4 = 0; /* rep0 */ prev_trial2->prev_index = e->trials[cur].prev_index2; prev_trial2->prev_index2 = single_step_trial; } } prev_trial->price = cur - prev_index; /* len */ - cur = *dis; *dis = prev_trial->dis; prev_trial->dis = cur; + cur = dis4; dis4 = prev_trial->dis4; prev_trial->dis4 = cur; cur = prev_index; } } @@ -305,7 +287,7 @@ static inline bool LZe_init( struct LZ_encoder * const e, const int dict_size, const int len_limit, const unsigned long long member_size ) { - enum { before = max_num_trials + 1, + enum { before = max_num_trials, /* bytes to keep in buffer after pos */ after_size = max_num_trials + ( 2 * max_match_len ) + 1, dict_factor = 2, diff --git a/encoder_base.c b/encoder_base.c index ee7e0bb..be9af5d 100644 --- a/encoder_base.c +++ b/encoder_base.c @@ -1,28 +1,20 @@ /* Lzlib - Compression library for the lzip format - Copyright (C) 2009-2016 Antonio Diaz Diaz. + Copyright (C) 2009-2017 Antonio Diaz Diaz. - This library is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. + This library is free software. Redistribution and use in source and + binary forms, with or without modification, are permitted provided + that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this library. If not, see <http://www.gnu.org/licenses/>. - - As a special exception, you may use this file as part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this - file, or you compile this file and link it with other files to - produce an executable, this file does not by itself cause the - resulting executable to be covered by the GNU General Public - License. This exception does not however invalidate any other - reasons why the executable file might be covered by the GNU General - Public License. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ static bool Mb_normalize_pos( struct Matchfinder_base * const mb ) @@ -32,11 +24,11 @@ static bool Mb_normalize_pos( struct Matchfinder_base * const mb ) if( !mb->at_stream_end ) { int i; - const int offset = mb->pos - mb->dictionary_size - mb->before_size; + const int offset = mb->pos - mb->before_size - mb->dictionary_size; const int size = mb->stream_pos - offset; memmove( mb->buffer, mb->buffer + offset, size ); mb->partial_data_pos += offset; - mb->pos -= offset; + mb->pos -= offset; /* pos = before_size + dictionary_size */ mb->stream_pos -= offset; for( i = 0; i < mb->num_prev_positions; ++i ) mb->prev_positions[i] -= min( mb->prev_positions[i], offset ); @@ -82,8 +74,9 @@ static bool Mb_init( struct Matchfinder_base * const mb, mb->num_prev_positions = size; mb->pos_array_size = pos_array_factor * ( mb->dictionary_size + 1 ); size += mb->pos_array_size; - if( size * sizeof (int32_t) <= size ) mb->prev_positions = 0; - else mb->prev_positions = (int32_t *)malloc( size * sizeof (int32_t) ); + if( size * sizeof mb->prev_positions[0] <= size ) mb->prev_positions = 0; + else mb->prev_positions = + (int32_t *)malloc( size * sizeof mb->prev_positions[0] ); if( !mb->prev_positions ) { free( mb->buffer ); return false; } mb->pos_array = mb->prev_positions + mb->num_prev_positions; for( i = 0; i < mb->num_prev_positions; ++i ) mb->prev_positions[i] = 0; @@ -100,7 +93,7 @@ static void Mb_adjust_dictionary_size( struct Matchfinder_base * const mb ) mb->dictionary_size = mb->pos_limit = max( min_dictionary_size, mb->stream_pos ); size = 1 << max( 16, real_bits( mb->dictionary_size - 1 ) - 2 ); - if( mb->dictionary_size > 1 << 26 ) + if( mb->dictionary_size > 1 << 26 ) /* 64 MiB */ size >>= 1; mb->key4_mask = size - 1; size += mb->num_prev_positions23; @@ -126,7 +119,7 @@ static void Mb_reset( struct Matchfinder_base * const mb ) /* End Of Stream mark => (dis == 0xFFFFFFFFU, len == min_match_len) */ -static bool LZeb_full_flush( struct LZ_encoder_base * const eb ) +static void LZeb_try_full_flush( struct LZ_encoder_base * const eb ) { int i; const int pos_state = Mb_data_position( &eb->mb ) & pos_state_mask; @@ -134,7 +127,8 @@ static bool LZeb_full_flush( struct LZ_encoder_base * const eb ) File_trailer trailer; if( eb->member_finished || Cb_free_bytes( &eb->renc.cb ) < max_marker_size + eb->renc.ff_count + Ft_size ) - return false; + return; + eb->member_finished = true; Re_encode_bit( &eb->renc, &eb->bm_match[state][pos_state], 1 ); Re_encode_bit( &eb->renc, &eb->bm_rep[state], 0 ); LZeb_encode_pair( eb, 0xFFFFFFFFU, min_match_len, pos_state ); @@ -144,7 +138,6 @@ static bool LZeb_full_flush( struct LZ_encoder_base * const eb ) Ft_set_member_size( trailer, Re_member_position( &eb->renc ) + Ft_size ); for( i = 0; i < Ft_size; ++i ) Cb_put_byte( &eb->renc.cb, trailer[i] ); - return true; } @@ -183,7 +176,7 @@ static void LZeb_reset( struct LZ_encoder_base * const eb, Bm_array_init( eb->bm_rep2, states ); Bm_array_init( eb->bm_len[0], states * pos_states ); Bm_array_init( eb->bm_dis_slot[0], len_states * (1 << dis_slot_bits) ); - Bm_array_init( eb->bm_dis, modeled_distances - end_dis_model ); + Bm_array_init( eb->bm_dis, modeled_distances - end_dis_model + 1 ); Bm_array_init( eb->bm_align, dis_align_size ); Lm_init( &eb->match_len_model ); Lm_init( &eb->rep_len_model ); diff --git a/encoder_base.h b/encoder_base.h index 3209922..c4cfcca 100644 --- a/encoder_base.h +++ b/encoder_base.h @@ -1,28 +1,20 @@ /* Lzlib - Compression library for the lzip format - Copyright (C) 2009-2016 Antonio Diaz Diaz. + Copyright (C) 2009-2017 Antonio Diaz Diaz. - This library is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. + This library is free software. Redistribution and use in source and + binary forms, with or without modification, are permitted provided + that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this library. If not, see <http://www.gnu.org/licenses/>. - - As a special exception, you may use this file as part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this - file, or you compile this file and link it with other files to - produce an executable, this file does not by itself cause the - resulting executable to be covered by the GNU General Public - License. This exception does not however invalidate any other - reasons why the executable file might be covered by the GNU General - Public License. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ enum { price_shift_bits = 6, @@ -149,22 +141,48 @@ static inline int price0( const Bit_model probability ) static inline int price1( const Bit_model probability ) { return get_price( bit_model_total - probability ); } -static inline int price_bit( const Bit_model bm, const int bit ) - { if( bit ) return price1( bm ); else return price0( bm ); } +static inline int price_bit( const Bit_model bm, const bool bit ) + { return ( bit ? price1( bm ) : price0( bm ) ); } -static inline int price_symbol( const Bit_model bm[], int symbol, - const int num_bits ) +static inline int price_symbol3( const Bit_model bm[], int symbol ) { - int price = 0; - symbol |= ( 1 << num_bits ); - while( symbol > 1 ) - { - const int bit = symbol & 1; - symbol >>= 1; - price += price_bit( bm[symbol], bit ); - } - return price; + int price; + bool bit = symbol & 1; + symbol |= 8; symbol >>= 1; + price = price_bit( bm[symbol], bit ); + bit = symbol & 1; symbol >>= 1; price += price_bit( bm[symbol], bit ); + return price + price_bit( bm[1], symbol & 1 ); + } + + +static inline int price_symbol6( const Bit_model bm[], unsigned symbol ) + { + int price; + bool bit = symbol & 1; + symbol |= 64; symbol >>= 1; + price = price_bit( bm[symbol], bit ); + bit = symbol & 1; symbol >>= 1; price += price_bit( bm[symbol], bit ); + bit = symbol & 1; symbol >>= 1; price += price_bit( bm[symbol], bit ); + bit = symbol & 1; symbol >>= 1; price += price_bit( bm[symbol], bit ); + bit = symbol & 1; symbol >>= 1; price += price_bit( bm[symbol], bit ); + return price + price_bit( bm[1], symbol & 1 ); + } + + +static inline int price_symbol8( const Bit_model bm[], int symbol ) + { + int price; + bool bit = symbol & 1; + symbol |= 0x100; symbol >>= 1; + price = price_bit( bm[symbol], bit ); + bit = symbol & 1; symbol >>= 1; price += price_bit( bm[symbol], bit ); + bit = symbol & 1; symbol >>= 1; price += price_bit( bm[symbol], bit ); + bit = symbol & 1; symbol >>= 1; price += price_bit( bm[symbol], bit ); + bit = symbol & 1; symbol >>= 1; price += price_bit( bm[symbol], bit ); + bit = symbol & 1; symbol >>= 1; price += price_bit( bm[symbol], bit ); + bit = symbol & 1; symbol >>= 1; price += price_bit( bm[symbol], bit ); + return price + price_bit( bm[1], symbol & 1 ); } @@ -176,33 +194,29 @@ static inline int price_symbol_reversed( const Bit_model bm[], int symbol, int i; for( i = num_bits; i > 0; --i ) { - const int bit = symbol & 1; + const bool bit = symbol & 1; + symbol >>= 1; price += price_bit( bm[model], bit ); model = ( model << 1 ) | bit; - symbol >>= 1; } return price; } -static inline int price_matched( const Bit_model bm[], int symbol, - int match_byte ) +static inline int price_matched( const Bit_model bm[], unsigned symbol, + unsigned match_byte ) { int price = 0; - int mask = 0x100; + unsigned mask = 0x100; symbol |= mask; - - do { - int match_bit, bit; - match_byte <<= 1; - match_bit = match_byte & mask; - symbol <<= 1; - bit = symbol & 0x100; - price += price_bit( bm[match_bit+(symbol>>9)+mask], bit ); - mask &= ~(match_byte ^ symbol); /* if( match_bit != bit ) mask = 0; */ + while( true ) + { + const unsigned match_bit = ( match_byte <<= 1 ) & mask; + const bool bit = ( symbol <<= 1 ) & 0x100; + price += price_bit( bm[(symbol>>9)+match_bit+mask], bit ); + if( symbol >= 0x10000 ) return price; + mask &= ~(match_bit ^ symbol); /* if( match_bit != bit ) mask = 0; */ } - while( symbol < 0x10000 ); - return price; } @@ -264,10 +278,8 @@ static inline int Mb_free_bytes( const struct Matchfinder_base * const mb ) return mb->buffer_size - mb->stream_pos; } static inline bool Mb_enough_available_bytes( const struct Matchfinder_base * const mb ) - { - return ( mb->pos + mb->after_size <= mb->stream_pos || - ( Mb_flushing_or_end( mb ) && mb->pos < mb->stream_pos ) ); - } + { return ( mb->pos + mb->after_size <= mb->stream_pos || + ( Mb_flushing_or_end( mb ) && mb->pos < mb->stream_pos ) ); } static inline const uint8_t * Mb_ptr_to_current_pos( const struct Matchfinder_base * const mb ) @@ -284,13 +296,11 @@ static int Mb_write_data( struct Matchfinder_base * const mb, } static inline int Mb_true_match_len( const struct Matchfinder_base * const mb, - const int index, const int distance, - int len_limit ) + const int index, const int distance ) { - const uint8_t * const data = mb->buffer + mb->pos + index; - int i = 0; - if( index + len_limit > Mb_available_bytes( mb ) ) - len_limit = Mb_available_bytes( mb ) - index; + const uint8_t * const data = mb->buffer + mb->pos; + int i = index; + const int len_limit = min( Mb_available_bytes( mb ), max_match_len ); while( i < len_limit && data[i-distance] == data[i] ) ++i; return i; } @@ -317,9 +327,9 @@ struct Range_encoder static inline void Re_shift_low( struct Range_encoder * const renc ) { - const bool carry = ( renc->low > 0xFFFFFFFFU ); - if( carry || renc->low < 0xFF000000U ) + if( renc->low >> 24 != 0xFF ) { + const bool carry = ( renc->low > 0xFFFFFFFFU ); Cb_put_byte( &renc->cb, renc->cache + carry ); for( ; renc->ff_count > 0; --renc->ff_count ) Cb_put_byte( &renc->cb, 0xFF + carry ); @@ -384,18 +394,18 @@ static inline void Re_flush( struct Range_encoder * const renc ) static inline void Re_encode( struct Range_encoder * const renc, const int symbol, const int num_bits ) { - int i; - for( i = num_bits - 1; i >= 0; --i ) + unsigned mask; + for( mask = 1 << ( num_bits - 1 ); mask > 0; mask >>= 1 ) { renc->range >>= 1; - if( (symbol >> i) & 1 ) renc->low += renc->range; + if( symbol & mask ) renc->low += renc->range; if( renc->range <= 0x00FFFFFFU ) { renc->range <<= 8; Re_shift_low( renc ); } } } static inline void Re_encode_bit( struct Range_encoder * const renc, - Bit_model * const probability, const int bit ) + Bit_model * const probability, const bool bit ) { const uint32_t bound = ( renc->range >> bit_model_total_bits ) * *probability; if( !bit ) @@ -409,56 +419,78 @@ static inline void Re_encode_bit( struct Range_encoder * const renc, renc->range -= bound; *probability -= *probability >> bit_model_move_bits; } - if( renc->range <= 0x00FFFFFFU ) - { renc->range <<= 8; Re_shift_low( renc ); } + if( renc->range <= 0x00FFFFFFU ) { renc->range <<= 8; Re_shift_low( renc ); } + } + +static inline void Re_encode_tree3( struct Range_encoder * const renc, + Bit_model bm[], const int symbol ) + { + int model = 1; + bool bit = ( symbol >> 2 ) & 1; + Re_encode_bit( renc, &bm[model], bit ); model = ( model << 1 ) | bit; + bit = ( symbol >> 1 ) & 1; + Re_encode_bit( renc, &bm[model], bit ); model = ( model << 1 ) | bit; + Re_encode_bit( renc, &bm[model], symbol & 1 ); } -static inline void Re_encode_tree( struct Range_encoder * const renc, - Bit_model bm[], const int symbol, const int num_bits ) +static inline void Re_encode_tree6( struct Range_encoder * const renc, + Bit_model bm[], const unsigned symbol ) + { + int model = 1; + bool bit = ( symbol >> 5 ) & 1; + Re_encode_bit( renc, &bm[model], bit ); model = ( model << 1 ) | bit; + bit = ( symbol >> 4 ) & 1; + Re_encode_bit( renc, &bm[model], bit ); model = ( model << 1 ) | bit; + bit = ( symbol >> 3 ) & 1; + Re_encode_bit( renc, &bm[model], bit ); model = ( model << 1 ) | bit; + bit = ( symbol >> 2 ) & 1; + Re_encode_bit( renc, &bm[model], bit ); model = ( model << 1 ) | bit; + bit = ( symbol >> 1 ) & 1; + Re_encode_bit( renc, &bm[model], bit ); model = ( model << 1 ) | bit; + Re_encode_bit( renc, &bm[model], symbol & 1 ); + } + +static inline void Re_encode_tree8( struct Range_encoder * const renc, + Bit_model bm[], const int symbol ) { - int mask = ( 1 << ( num_bits - 1 ) ); int model = 1; int i; - for( i = num_bits; i > 0; --i, mask >>= 1 ) + for( i = 7; i >= 0; --i ) { - const int bit = ( symbol & mask ); + const bool bit = ( symbol >> i ) & 1; Re_encode_bit( renc, &bm[model], bit ); - model <<= 1; - if( bit ) model |= 1; + model = ( model << 1 ) | bit; } } static inline void Re_encode_tree_reversed( struct Range_encoder * const renc, - Bit_model bm[], int symbol, const int num_bits ) + Bit_model bm[], int symbol, const int num_bits ) { int model = 1; int i; for( i = num_bits; i > 0; --i ) { - const int bit = symbol & 1; + const bool bit = symbol & 1; + symbol >>= 1; Re_encode_bit( renc, &bm[model], bit ); model = ( model << 1 ) | bit; - symbol >>= 1; } } static inline void Re_encode_matched( struct Range_encoder * const renc, - Bit_model bm[], int symbol, - int match_byte ) + Bit_model bm[], unsigned symbol, + unsigned match_byte ) { - int mask = 0x100; + unsigned mask = 0x100; symbol |= mask; - - do { - int match_bit, bit; - match_byte <<= 1; - match_bit = match_byte & mask; - symbol <<= 1; - bit = symbol & 0x100; - Re_encode_bit( renc, &bm[match_bit+(symbol>>9)+mask], bit ); - mask &= ~(match_byte ^ symbol); /* if( match_bit != bit ) mask = 0; */ + while( true ) + { + const unsigned match_bit = ( match_byte <<= 1 ) & mask; + const bool bit = ( symbol <<= 1 ) & 0x100; + Re_encode_bit( renc, &bm[(symbol>>9)+match_bit+mask], bit ); + if( symbol >= 0x10000 ) break; + mask &= ~(match_bit ^ symbol); /* if( match_bit != bit ) mask = 0; */ } - while( symbol < 0x10000 ); } static inline void Re_encode_len( struct Range_encoder * const renc, @@ -468,17 +500,15 @@ static inline void Re_encode_len( struct Range_encoder * const renc, bool bit = ( ( symbol -= min_match_len ) >= len_low_symbols ); Re_encode_bit( renc, &lm->choice1, bit ); if( !bit ) - Re_encode_tree( renc, lm->bm_low[pos_state], symbol, len_low_bits ); + Re_encode_tree3( renc, lm->bm_low[pos_state], symbol ); else { - bit = ( symbol >= len_low_symbols + len_mid_symbols ); + bit = ( ( symbol -= len_low_symbols ) >= len_mid_symbols ); Re_encode_bit( renc, &lm->choice2, bit ); if( !bit ) - Re_encode_tree( renc, lm->bm_mid[pos_state], - symbol - len_low_symbols, len_mid_bits ); + Re_encode_tree3( renc, lm->bm_mid[pos_state], symbol ); else - Re_encode_tree( renc, lm->bm_high, - symbol - len_low_symbols - len_mid_symbols, len_high_bits ); + Re_encode_tree8( renc, lm->bm_high, symbol - len_mid_symbols ); } } @@ -500,7 +530,7 @@ struct LZ_encoder_base Bit_model bm_rep2[states]; Bit_model bm_len[states][pos_states]; Bit_model bm_dis_slot[len_states][1<<dis_slot_bits]; - Bit_model bm_dis[modeled_distances-end_dis_model]; + Bit_model bm_dis[modeled_distances-end_dis_model+1]; Bit_model bm_align[dis_align_size]; struct Len_model match_len_model; struct Len_model rep_len_model; @@ -539,23 +569,21 @@ static inline unsigned LZeb_crc( const struct LZ_encoder_base * const eb ) { return eb->crc ^ 0xFFFFFFFFU; } static inline int LZeb_price_literal( const struct LZ_encoder_base * const eb, - uint8_t prev_byte, uint8_t symbol ) - { return price_symbol( eb->bm_literal[get_lit_state(prev_byte)], symbol, 8 ); } + const uint8_t prev_byte, const uint8_t symbol ) + { return price_symbol8( eb->bm_literal[get_lit_state(prev_byte)], symbol ); } static inline int LZeb_price_matched( const struct LZ_encoder_base * const eb, - uint8_t prev_byte, uint8_t symbol, - uint8_t match_byte ) + const uint8_t prev_byte, const uint8_t symbol, const uint8_t match_byte ) { return price_matched( eb->bm_literal[get_lit_state(prev_byte)], symbol, match_byte ); } static inline void LZeb_encode_literal( struct LZ_encoder_base * const eb, - uint8_t prev_byte, uint8_t symbol ) - { Re_encode_tree( &eb->renc, - eb->bm_literal[get_lit_state(prev_byte)], symbol, 8 ); } + const uint8_t prev_byte, const uint8_t symbol ) + { Re_encode_tree8( &eb->renc, eb->bm_literal[get_lit_state(prev_byte)], + symbol ); } static inline void LZeb_encode_matched( struct LZ_encoder_base * const eb, - uint8_t prev_byte, uint8_t symbol, - uint8_t match_byte ) + const uint8_t prev_byte, const uint8_t symbol, const uint8_t match_byte ) { Re_encode_matched( &eb->renc, eb->bm_literal[get_lit_state(prev_byte)], symbol, match_byte ); } @@ -563,10 +591,9 @@ static inline void LZeb_encode_pair( struct LZ_encoder_base * const eb, const unsigned dis, const int len, const int pos_state ) { - const int dis_slot = get_slot( dis ); + const unsigned dis_slot = get_slot( dis ); Re_encode_len( &eb->renc, &eb->match_len_model, len, pos_state ); - Re_encode_tree( &eb->renc, eb->bm_dis_slot[get_len_state(len)], dis_slot, - dis_slot_bits ); + Re_encode_tree6( &eb->renc, eb->bm_dis_slot[get_len_state(len)], dis_slot ); if( dis_slot >= start_dis_model ) { @@ -575,7 +602,7 @@ static inline void LZeb_encode_pair( struct LZ_encoder_base * const eb, const unsigned direct_dis = dis - base; if( dis_slot < end_dis_model ) - Re_encode_tree_reversed( &eb->renc, eb->bm_dis + base - dis_slot - 1, + Re_encode_tree_reversed( &eb->renc, eb->bm_dis + ( base - dis_slot ), direct_dis, direct_bits ); else { diff --git a/fast_encoder.c b/fast_encoder.c index 03697cc..af81137 100644 --- a/fast_encoder.c +++ b/fast_encoder.c @@ -1,28 +1,20 @@ /* Lzlib - Compression library for the lzip format - Copyright (C) 2009-2016 Antonio Diaz Diaz. + Copyright (C) 2009-2017 Antonio Diaz Diaz. - This library is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. + This library is free software. Redistribution and use in source and + binary forms, with or without modification, are permitted provided + that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this library. If not, see <http://www.gnu.org/licenses/>. - - As a special exception, you may use this file as part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this - file, or you compile this file and link it with other files to - produce an executable, this file does not by itself cause the - resulting executable to be covered by the GNU General Public - License. This exception does not however invalidate any other - reasons why the executable file might be covered by the GNU General - Public License. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ int FLZe_longest_match_len( struct FLZ_encoder * const fe, int * const distance ) @@ -30,21 +22,22 @@ int FLZe_longest_match_len( struct FLZ_encoder * const fe, int * const distance enum { len_limit = 16 }; const uint8_t * const data = Mb_ptr_to_current_pos( &fe->eb.mb ); int32_t * ptr0 = fe->eb.mb.pos_array + fe->eb.mb.cyclic_pos; - int32_t * newptr; const int pos1 = fe->eb.mb.pos + 1; - int maxlen = 0; - int count, delta, newpos; - if( len_limit > Mb_available_bytes( &fe->eb.mb ) ) { *ptr0 = 0; return 0; } + int maxlen = 0, newpos1, count; + const int available = min( Mb_available_bytes( &fe->eb.mb ), max_match_len ); + if( available < len_limit ) { *ptr0 = 0; return 0; } fe->key4 = ( ( fe->key4 << 4 ) ^ data[3] ) & fe->eb.mb.key4_mask; - newpos = fe->eb.mb.prev_positions[fe->key4]; + newpos1 = fe->eb.mb.prev_positions[fe->key4]; fe->eb.mb.prev_positions[fe->key4] = pos1; for( count = 4; ; ) { - if( --count < 0 || newpos <= 0 ) { *ptr0 = 0; break; } - delta = pos1 - newpos; - if( delta > fe->eb.mb.dictionary_size ) { *ptr0 = 0; break; } + int32_t * newptr; + int delta; + if( newpos1 <= 0 || --count < 0 || + ( delta = pos1 - newpos1 ) > fe->eb.mb.dictionary_size ) + { *ptr0 = 0; break; } newptr = fe->eb.mb.pos_array + ( fe->eb.mb.cyclic_pos - delta + ( ( fe->eb.mb.cyclic_pos >= delta ) ? 0 : fe->eb.mb.dictionary_size + 1 ) ); @@ -52,23 +45,15 @@ int FLZe_longest_match_len( struct FLZ_encoder * const fe, int * const distance if( data[maxlen-delta] == data[maxlen] ) { int len = 0; - while( len < len_limit && data[len-delta] == data[len] ) ++len; - if( maxlen < len ) { maxlen = len; *distance = delta - 1; } + while( len < available && data[len-delta] == data[len] ) ++len; + if( maxlen < len ) + { maxlen = len; *distance = delta - 1; + if( maxlen >= len_limit ) { *ptr0 = *newptr; break; } } } - if( maxlen < len_limit ) - { - *ptr0 = newpos; - ptr0 = newptr; - newpos = *ptr0; - } - else - { - *ptr0 = *newptr; - maxlen += Mb_true_match_len( &fe->eb.mb, maxlen, *distance + 1, - max_match_len - maxlen ); - break; - } + *ptr0 = newpos1; + ptr0 = newptr; + newpos1 = *ptr0; } return maxlen; } @@ -81,10 +66,7 @@ bool FLZe_encode_member( struct FLZ_encoder * const fe ) if( fe->eb.member_finished ) return true; if( Re_member_position( &fe->eb.renc ) >= fe->eb.member_size_limit ) - { - if( LZeb_full_flush( &fe->eb ) ) fe->eb.member_finished = true; - return true; - } + { LZeb_try_full_flush( &fe->eb ); return true; } if( Mb_data_position( &fe->eb.mb ) == 0 && !Mb_data_finished( &fe->eb.mb ) ) /* encode first byte */ @@ -105,7 +87,8 @@ bool FLZe_encode_member( struct FLZ_encoder * const fe ) Re_member_position( &fe->eb.renc ) < fe->eb.member_size_limit ) { int match_distance; - int main_len, pos_state, len = 0; + int main_len, pos_state; + int len = 0; if( !Mb_enough_available_bytes( &fe->eb.mb ) || !Re_enough_free_bytes( &fe->eb.renc ) ) return true; main_len = FLZe_longest_match_len( fe, &match_distance ); @@ -113,8 +96,7 @@ bool FLZe_encode_member( struct FLZ_encoder * const fe ) for( i = 0; i < num_rep_distances; ++i ) { - const int tlen = Mb_true_match_len( &fe->eb.mb, 0, - fe->eb.reps[i] + 1, max_match_len ); + const int tlen = Mb_true_match_len( &fe->eb.mb, 0, fe->eb.reps[i] + 1 ); if( tlen > len ) { len = tlen; rep = i; } } if( len > min_match_len && len + 3 > main_len ) @@ -195,6 +177,6 @@ bool FLZe_encode_member( struct FLZ_encoder * const fe ) } } - if( LZeb_full_flush( &fe->eb ) ) fe->eb.member_finished = true; + LZeb_try_full_flush( &fe->eb ); return true; } diff --git a/fast_encoder.h b/fast_encoder.h index 9d9e1c7..c02e9cb 100644 --- a/fast_encoder.h +++ b/fast_encoder.h @@ -1,34 +1,26 @@ /* Lzlib - Compression library for the lzip format - Copyright (C) 2009-2016 Antonio Diaz Diaz. + Copyright (C) 2009-2017 Antonio Diaz Diaz. - This library is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. + This library is free software. Redistribution and use in source and + binary forms, with or without modification, are permitted provided + that the following conditions are met: - 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 General Public License for more details. + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. - You should have received a copy of the GNU General Public License - along with this library. If not, see <http://www.gnu.org/licenses/>. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. - As a special exception, you may use this file as part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this - file, or you compile this file and link it with other files to - produce an executable, this file does not by itself cause the - resulting executable to be covered by the GNU General Public - License. This exception does not however invalidate any other - reasons why the executable file might be covered by the GNU General - Public License. + 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. */ struct FLZ_encoder { struct LZ_encoder_base eb; - int key4; /* key made from latest 4 bytes */ + unsigned key4; /* key made from latest 4 bytes */ }; static inline void FLZe_reset_key4( struct FLZ_encoder * const fe ) @@ -47,12 +39,10 @@ static inline bool FLZe_update_and_move( struct FLZ_encoder * const fe, int n ) { if( Mb_available_bytes( &fe->eb.mb ) >= 4 ) { - int newpos; fe->key4 = ( ( fe->key4 << 4 ) ^ fe->eb.mb.buffer[fe->eb.mb.pos+3] ) & fe->eb.mb.key4_mask; - newpos = fe->eb.mb.prev_positions[fe->key4]; + fe->eb.mb.pos_array[fe->eb.mb.cyclic_pos] = fe->eb.mb.prev_positions[fe->key4]; fe->eb.mb.prev_positions[fe->key4] = fe->eb.mb.pos + 1; - fe->eb.mb.pos_array[fe->eb.mb.cyclic_pos] = newpos; } else fe->eb.mb.pos_array[fe->eb.mb.cyclic_pos] = 0; if( !Mb_move_pos( &fe->eb.mb ) ) return false; @@ -1,5 +1,5 @@ /* Lzcheck - Test program for the lzlib library - Copyright (C) 2009-2016 Antonio Diaz Diaz. + Copyright (C) 2009-2017 Antonio Diaz Diaz. This program is free software: you have unlimited permission to copy, distribute and modify it. @@ -1,28 +1,20 @@ /* Lzlib - Compression library for the lzip format - Copyright (C) 2009-2016 Antonio Diaz Diaz. + Copyright (C) 2009-2017 Antonio Diaz Diaz. - This library is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. + This library is free software. Redistribution and use in source and + binary forms, with or without modification, are permitted provided + that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this library. If not, see <http://www.gnu.org/licenses/>. - - As a special exception, you may use this file as part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this - file, or you compile this file and link it with other files to - produce an executable, this file does not by itself cause the - resulting executable to be covered by the GNU General Public - License. This exception does not however invalidate any other - reasons why the executable file might be covered by the GNU General - Public License. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef max @@ -179,8 +171,10 @@ static inline void CRC32_update_buf( uint32_t * const crc, const int size ) { int i; + uint32_t c = *crc; for( i = 0; i < size; ++i ) - *crc = crc32[(*crc^buffer[i])&0xFF] ^ ( *crc >> 8 ); + c = crc32[(c^buffer[i])&0xFF] ^ ( c >> 8 ); + *crc = c; } @@ -240,7 +234,7 @@ static inline bool Fh_set_dictionary_size( File_header data, const unsigned sz ) { const unsigned base_size = 1 << data[5]; const unsigned fraction = base_size / 16; - int i; + unsigned i; for( i = 7; i >= 1; --i ) if( base_size - ( i * fraction ) >= sz ) { data[5] |= ( i << 5 ); break; } @@ -1,28 +1,20 @@ /* Lzlib - Compression library for the lzip format - Copyright (C) 2009-2016 Antonio Diaz Diaz. + Copyright (C) 2009-2017 Antonio Diaz Diaz. - This library is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. + This library is free software. Redistribution and use in source and + binary forms, with or without modification, are permitted provided + that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this library. If not, see <http://www.gnu.org/licenses/>. - - As a special exception, you may use this file as part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this - file, or you compile this file and link it with other files to - produce an executable, this file does not by itself cause the - resulting executable to be covered by the GNU General Public - License. This exception does not however invalidate any other - reasons why the executable file might be covered by the GNU General - Public License. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ #include <stdbool.h> @@ -387,7 +379,7 @@ int LZ_decompress_reset( struct LZ_Decoder * const d ) int LZ_decompress_sync_to_member( struct LZ_Decoder * const d ) { - int skipped = 0; + unsigned skipped = 0; if( !verify_decoder( d ) ) return -1; if( d->lz_decoder ) { LZd_free( d->lz_decoder ); free( d->lz_decoder ); d->lz_decoder = 0; } @@ -434,7 +426,7 @@ int LZ_decompress_read( struct LZ_Decoder * const d, d->fatal = true; return -1; } - if( !Fh_verify( d->member_header ) ) + if( !Fh_verify_magic( d->member_header ) ) { /* unreading the header prevents sync_to_member from skipping a member if leading garbage is shorter than a full header; "lgLZIP\x01\x0C" */ @@ -445,6 +437,13 @@ int LZ_decompress_read( struct LZ_Decoder * const d, d->fatal = true; return -1; } + if( !Fh_verify_version( d->member_header ) || + !isvalid_ds( Fh_get_dictionary_size( d->member_header ) ) ) + { + d->lz_errno = LZ_data_error; /* bad version or bad dict size */ + d->fatal = true; + return -1; + } d->first_header = false; if( Rd_available_bytes( d->rdec ) < 5 ) { @@ -493,7 +492,8 @@ int LZ_decompress_write( struct LZ_Decoder * const d, result = Rd_write_data( d->rdec, buffer, size ); while( d->seeking ) { - int size2, skipped = 0; + int size2; + unsigned skipped = 0; if( Rd_find_header( d->rdec, &skipped ) ) d->seeking = false; d->partial_in_size += skipped; if( result >= size ) break; @@ -1,28 +1,20 @@ /* Lzlib - Compression library for the lzip format - Copyright (C) 2009-2016 Antonio Diaz Diaz. + Copyright (C) 2009-2017 Antonio Diaz Diaz. - This library is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. + This library is free software. Redistribution and use in source and + binary forms, with or without modification, are permitted provided + that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this library. If not, see <http://www.gnu.org/licenses/>. - - As a special exception, you may use this file as part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this - file, or you compile this file and link it with other files to - produce an executable, this file does not by itself cause the - resulting executable to be covered by the GNU General Public - License. This exception does not however invalidate any other - reasons why the executable file might be covered by the GNU General - Public License. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ #ifdef __cplusplus @@ -31,7 +23,7 @@ extern "C" { #define LZ_API_VERSION 1 -static const char * const LZ_version_string = "1.8"; +static const char * const LZ_version_string = "1.9"; enum LZ_Errno { LZ_ok = 0, LZ_bad_argument, LZ_mem_error, LZ_sequence_error, LZ_header_error, LZ_unexpected_eof, @@ -1,5 +1,5 @@ /* Minilzip - Test program for the lzlib library - Copyright (C) 2009-2016 Antonio Diaz Diaz. + Copyright (C) 2009-2017 Antonio Diaz Diaz. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -71,16 +71,18 @@ void cleanup_and_fail( const int retval ); void show_error( const char * const msg, const int errcode, const bool help ); +void show_file_error( const char * const filename, const char * const msg, + const int errcode ); void internal_error( const char * const msg ); int verbosity = 0; const char * const Program_name = "Minilzip"; const char * const program_name = "minilzip"; -const char * const program_year = "2016"; +const char * const program_year = "2017"; const char * invocation_name = 0; -struct { const char * from; const char * to; } const known_extensions[] = { +const struct { const char * from; const char * to; } known_extensions[] = { { ".lz", "" }, { ".tlz", ".tar" }, { 0, 0 } }; @@ -116,9 +118,9 @@ static void Pp_init( struct Pretty_print * const pp, pp->stdin_name = "(stdin)"; pp->longest_name = 0; pp->first_post = false; - stdin_name_len = strlen( pp->stdin_name ); if( verbosity <= 0 ) return; + stdin_name_len = strlen( pp->stdin_name ); for( i = 0; i < num_filenames; ++i ) { const char * const s = filenames[i]; @@ -216,9 +218,9 @@ static void show_header( const unsigned dictionary_size ) { if( verbosity >= 3 ) { + enum { factor = 1024 }; const char * const prefix[8] = { "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi" }; - enum { factor = 1024 }; const char * p = ""; const char * np = " "; unsigned num = dictionary_size, i; @@ -227,7 +229,7 @@ static void show_header( const unsigned dictionary_size ) for( i = 0; i < 8 && ( num > 9999 || ( exact && num >= factor ) ); ++i ) { num /= factor; if( num % factor != 0 ) exact = false; p = prefix[i]; np = ""; } - fprintf( stderr, "dictionary size %s%4u %sB. ", np, num, p ); + fprintf( stderr, "dictionary %s%4u %sB. ", np, num, p ); } } @@ -248,7 +250,7 @@ static unsigned long long getnum( const char * const ptr, if( !errno && tail[0] ) { - const int factor = ( tail[1] == 'i' ) ? 1024 : 1000; + const unsigned factor = ( tail[1] == 'i' ) ? 1024 : 1000; int exponent = 0; /* 0 = bad multiplier */ int i; switch( tail[0] ) @@ -288,7 +290,7 @@ static int get_dict_size( const char * const arg ) { char * tail; int dictionary_size; - const int bits = strtol( arg, &tail, 0 ); + const long bits = strtol( arg, &tail, 0 ); if( bits >= LZ_min_dictionary_bits() && bits <= LZ_max_dictionary_bits() && *tail == 0 ) return ( 1 << bits ); @@ -301,15 +303,15 @@ static int get_dict_size( const char * const arg ) static int extension_index( const char * const name ) { - int i; - for( i = 0; known_extensions[i].from; ++i ) + int eindex; + for( eindex = 0; known_extensions[eindex].from; ++eindex ) { - const char * const ext = known_extensions[i].from; + const char * const ext = known_extensions[eindex].from; const unsigned name_len = strlen( name ); const unsigned ext_len = strlen( ext ); if( name_len > ext_len && strncmp( name + name_len - ext_len, ext, ext_len ) == 0 ) - return i; + return eindex; } return -1; } @@ -330,11 +332,7 @@ static int open_instream( const char * const name, struct stat * const in_statsp { infd = open( name, O_RDONLY | O_BINARY ); if( infd < 0 ) - { - if( verbosity >= 0 ) - fprintf( stderr, "%s: Can't open input file '%s': %s\n", - program_name, name, strerror( errno ) ); - } + show_file_error( name, "Can't open input file", errno ); else { const int i = fstat( infd, in_statsp ); @@ -360,7 +358,7 @@ static int open_instream( const char * const name, struct stat * const in_statsp /* assure at least a minimum size for buffer 'buf' */ -static void * resize_buffer( void * buf, const int min_size ) +static void * resize_buffer( void * buf, const unsigned min_size ) { if( buf ) buf = realloc( buf, min_size ); else buf = malloc( min_size ); @@ -383,19 +381,19 @@ static void set_c_outname( const char * const name, const bool multifile ) } -static void set_d_outname( const char * const name, const int i ) +static void set_d_outname( const char * const name, const int eindex ) { const unsigned name_len = strlen( name ); - if( i >= 0 ) + if( eindex >= 0 ) { - const char * const from = known_extensions[i].from; + const char * const from = known_extensions[eindex].from; const unsigned from_len = strlen( from ); if( name_len > from_len ) { output_filename = resize_buffer( output_filename, name_len + - strlen( known_extensions[0].to ) + 1 ); + strlen( known_extensions[eindex].to ) + 1 ); strcpy( output_filename, name ); - strcpy( output_filename + name_len - from_len, known_extensions[i].to ); + strcpy( output_filename + name_len - from_len, known_extensions[eindex].to ); return; } } @@ -431,7 +429,8 @@ static bool open_outstream( const bool force, const bool from_stdin ) } -static bool check_tty( const int infd, const enum Mode program_mode ) +static bool check_tty( const char * const input_filename, const int infd, + const enum Mode program_mode ) { if( program_mode == m_compress && isatty( outfd ) ) { @@ -441,7 +440,8 @@ static bool check_tty( const int infd, const enum Mode program_mode ) if( ( program_mode == m_decompress || program_mode == m_test ) && isatty( infd ) ) { - show_error( "I won't read compressed data from a terminal.", 0, true ); + show_file_error( input_filename, + "I won't read compressed data from a terminal.", 0 ); return false; } return true; @@ -731,7 +731,7 @@ static int do_decompress( struct LZ_Decoder * const decoder, const int infd, ( 8.0 * member_size ) / data_size, 100.0 * ( 1.0 - ( (double)member_size / data_size ) ) ); if( verbosity >= 4 ) - fprintf( stderr, "data CRC %08X, data size %9llu, member size %8llu. ", + fprintf( stderr, "CRC %08X, decompressed %9llu, compressed %8llu. ", LZ_decompress_data_crc( decoder ), data_size, member_size ); fputs( testing ? "ok\n" : "done\n", stderr ); } @@ -749,10 +749,12 @@ static int do_decompress( struct LZ_Decoder * const decoder, const int infd, if( lz_errno == LZ_header_error ) { if( first_member ) - { Pp_show_msg( pp, "Bad magic number (file not in lzip format)." ); + { show_file_error( pp->name, + "Bad magic number (file not in lzip format).", 0 ); return 2; } else if( !ignore_trailing ) - { show_error( "Trailing data not allowed.", 0, false ); return 2; } + { show_file_error( pp->name, "Trailing data not allowed.", 0 ); + return 2; } break; } if( lz_errno == LZ_mem_error ) @@ -824,6 +826,16 @@ void show_error( const char * const msg, const int errcode, const bool help ) } +void show_file_error( const char * const filename, const char * const msg, + const int errcode ) + { + if( verbosity < 0 ) return; + fprintf( stderr, "%s: %s: %s", program_name, filename, msg ); + if( errcode > 0 ) fprintf( stderr, ": %s", strerror( errcode ) ); + fputc( '\n', stderr ); + } + + void internal_error( const char * const msg ) { if( verbosity >= 0 ) @@ -853,7 +865,6 @@ int main( const int argc, const char * const argv[] ) const unsigned long long max_volume_size = 0x4000000000000000ULL; unsigned long long member_size = max_member_size; unsigned long long volume_size = 0; - const char * input_filename = ""; const char * default_output_filename = ""; const char ** filenames = 0; int num_filenames = 0; @@ -866,8 +877,8 @@ int main( const int argc, const char * const argv[] ) bool force = false; bool ignore_trailing = true; bool keep_input_files = false; - bool stdin_used = false; bool recompress = false; + bool stdin_used = false; bool to_stdout = false; struct Pretty_print pp; @@ -955,9 +966,6 @@ int main( const int argc, const char * const argv[] ) setmode( STDOUT_FILENO, O_BINARY ); #endif - if( program_mode == m_test ) - outfd = -1; - num_filenames = max( 1, ap_arguments( &parser ) - argind ); filenames = resize_buffer( filenames, num_filenames * sizeof filenames[0] ); filenames[0] = "-"; @@ -968,6 +976,9 @@ int main( const int argc, const char * const argv[] ) if( strcmp( filenames[i], "-" ) != 0 ) filenames_given = true; } + if( program_mode == m_test ) + outfd = -1; + if( !to_stdout && program_mode != m_test && ( filenames_given || default_output_filename[0] ) ) set_signals(); @@ -977,6 +988,7 @@ int main( const int argc, const char * const argv[] ) output_filename = resize_buffer( output_filename, 1 ); for( i = 0; i < num_filenames; ++i ) { + const char * input_filename = ""; int tmp; struct stat in_stats; const struct stat * in_statsp; @@ -985,7 +997,6 @@ int main( const int argc, const char * const argv[] ) if( !filenames[i][0] || strcmp( filenames[i], "-" ) == 0 ) { if( stdin_used ) continue; else stdin_used = true; - input_filename = ""; infd = STDIN_FILENO; if( program_mode != m_test ) { @@ -1012,8 +1023,7 @@ int main( const int argc, const char * const argv[] ) } else { - const int eindex = extension_index( filenames[i] ); - input_filename = filenames[i]; + const int eindex = extension_index( input_filename = filenames[i] ); infd = open_instream( input_filename, &in_stats, program_mode, eindex, recompress, to_stdout ); if( infd < 0 ) { if( retval < 1 ) retval = 1; continue; } @@ -1035,14 +1045,15 @@ int main( const int argc, const char * const argv[] ) } } - if( !check_tty( infd, program_mode ) ) + Pp_set_name( &pp, input_filename ); + if( !check_tty( pp.name, infd, program_mode ) ) { if( retval < 1 ) retval = 1; + if( program_mode == m_test ) { close( infd ); infd = -1; continue; } cleanup_and_fail( retval ); } in_statsp = input_filename[0] ? &in_stats : 0; - Pp_set_name( &pp, input_filename ); if( program_mode == m_compress ) tmp = compress( member_size, volume_size, infd, &encoder_options, &pp, in_statsp ); diff --git a/testsuite/check.sh b/testsuite/check.sh index a78f156..037e2c9 100755 --- a/testsuite/check.sh +++ b/testsuite/check.sh @@ -1,6 +1,6 @@ #! /bin/sh # check script for Lzlib - A compression library for lzip files -# Copyright (C) 2009-2016 Antonio Diaz Diaz. +# Copyright (C) 2009-2017 Antonio Diaz Diaz. # # This script is free software: you have unlimited permission # to copy, distribute and modify it. @@ -19,12 +19,12 @@ if [ ! -f "${LZIP}" ] || [ ! -x "${LZIP}" ] ; then exit 1 fi -if [ -e "${LZIP}" ] 2> /dev/null ; then true -else +[ -e "${LZIP}" ] 2> /dev/null || + { echo "$0: a POSIX shell is required to run the tests" echo "Try bash -c \"$0 $1 $2\"" exit 1 -fi + } if [ -d tmp ] ; then rm -rf tmp ; fi mkdir tmp @@ -34,163 +34,218 @@ cat "${testdir}"/test.txt > in || framework_failure in_lz="${testdir}"/test.txt.lz test2="${testdir}"/test2.txt fail=0 +test_failed() { fail=1 ; printf " $1" ; [ -z "$2" ] || printf "($2)" ; } printf "testing lzlib-%s..." "$2" "${LZIP}" -fkqm4 in -if [ $? = 1 ] && [ ! -e in.lz ] ; then printf . ; else printf - ; fail=1 ; fi +{ [ $? = 1 ] && [ ! -e in.lz ] ; } || test_failed $LINENO "${LZIP}" -fkqm274 in -if [ $? = 1 ] && [ ! -e in.lz ] ; then printf . ; else printf - ; fail=1 ; fi -"${LZIP}" -fkqs-1 in -if [ $? = 1 ] && [ ! -e in.lz ] ; then printf . ; else printf - ; fail=1 ; fi -"${LZIP}" -fkqs0 in -if [ $? = 1 ] && [ ! -e in.lz ] ; then printf . ; else printf - ; fail=1 ; fi -"${LZIP}" -fkqs4095 in -if [ $? = 1 ] && [ ! -e in.lz ] ; then printf . ; else printf - ; fail=1 ; fi -"${LZIP}" -fkqs513MiB in -if [ $? = 1 ] && [ ! -e in.lz ] ; then printf . ; else printf - ; fail=1 ; fi +{ [ $? = 1 ] && [ ! -e in.lz ] ; } || test_failed $LINENO +for i in bad_size -1 0 4095 513MiB 1G 1T 1P 1E 1Z 1Y 10KB ; do + "${LZIP}" -fkqs $i in + { [ $? = 1 ] && [ ! -e in.lz ] ; } || test_failed $LINENO $i +done "${LZIP}" -tq in -if [ $? = 2 ] ; then printf . ; else printf - ; fail=1 ; fi +[ $? = 2 ] || test_failed $LINENO "${LZIP}" -tq < in -if [ $? = 2 ] ; then printf . ; else printf - ; fail=1 ; fi +[ $? = 2 ] || test_failed $LINENO "${LZIP}" -cdq in -if [ $? = 2 ] ; then printf . ; else printf - ; fail=1 ; fi +[ $? = 2 ] || test_failed $LINENO "${LZIP}" -cdq < in -if [ $? = 2 ] ; then printf . ; else printf - ; fail=1 ; fi -dd if="${in_lz}" bs=1 count=6 2> /dev/null | "${LZIP}" -tq -if [ $? = 2 ] ; then printf . ; else printf - ; fail=1 ; fi -dd if="${in_lz}" bs=1 count=20 2> /dev/null | "${LZIP}" -tq -if [ $? = 2 ] ; then printf . ; else printf - ; fail=1 ; fi +[ $? = 2 ] || test_failed $LINENO +# these are for code coverage +"${LZIP}" -t -- nx_file 2> /dev/null +[ $? = 1 ] || test_failed $LINENO +"${LZIP}" --help > /dev/null || test_failed $LINENO +"${LZIP}" -n1 -V > /dev/null || test_failed $LINENO +"${LZIP}" -m 2> /dev/null +[ $? = 1 ] || test_failed $LINENO +"${LZIP}" -z 2> /dev/null +[ $? = 1 ] || test_failed $LINENO +"${LZIP}" --bad_option 2> /dev/null +[ $? = 1 ] || test_failed $LINENO +"${LZIP}" --t 2> /dev/null +[ $? = 1 ] || test_failed $LINENO +"${LZIP}" --test=2 2> /dev/null +[ $? = 1 ] || test_failed $LINENO +"${LZIP}" --output= 2> /dev/null +[ $? = 1 ] || test_failed $LINENO +"${LZIP}" --output 2> /dev/null +[ $? = 1 ] || test_failed $LINENO +printf "LZIP\001-.............................." | "${LZIP}" -t 2> /dev/null +printf "LZIP\002-.............................." | "${LZIP}" -t 2> /dev/null +printf "LZIP\001+.............................." | "${LZIP}" -t 2> /dev/null printf "\ntesting decompression..." -"${LZIP}" -t "${in_lz}" -if [ $? = 0 ] ; then printf . ; else printf - ; fail=1 ; fi -"${LZIP}" -cd "${in_lz}" > copy || fail=1 -cmp in copy || fail=1 -printf . +"${LZIP}" -t "${in_lz}" || test_failed $LINENO +"${LZIP}" -cd "${in_lz}" > copy || test_failed $LINENO +cmp in copy || test_failed $LINENO -"${LZIP}" -t "${testdir}"/test_sync.lz -if [ $? = 0 ] ; then printf . ; else printf - ; fail=1 ; fi -"${LZIP}" -cd "${testdir}"/test_sync.lz > copy || fail=1 -cmp in copy || fail=1 -printf . +"${LZIP}" -t "${testdir}"/test_sync.lz || test_failed $LINENO +"${LZIP}" -cd "${testdir}"/test_sync.lz > copy || test_failed $LINENO +cmp in copy || test_failed $LINENO rm -f copy cat "${in_lz}" > copy.lz || framework_failure -"${LZIP}" -dk copy.lz || fail=1 -cmp in copy || fail=1 +"${LZIP}" -dk copy.lz || test_failed $LINENO +cmp in copy || test_failed $LINENO printf "to be overwritten" > copy || framework_failure -"${LZIP}" -dq copy.lz -if [ $? = 1 ] ; then printf . ; else printf - ; fail=1 ; fi +"${LZIP}" -d copy.lz 2> /dev/null +[ $? = 1 ] || test_failed $LINENO "${LZIP}" -df copy.lz -if [ $? = 0 ] && [ ! -e copy.lz ] && cmp in copy ; then - printf . ; else printf - ; fail=1 ; fi +{ [ $? = 0 ] && [ ! -e copy.lz ] && cmp in copy ; } || test_failed $LINENO printf "to be overwritten" > copy || framework_failure -"${LZIP}" -df -o copy < "${in_lz}" || fail=1 -cmp in copy || fail=1 -printf . +"${LZIP}" -df -o copy < "${in_lz}" || test_failed $LINENO +cmp in copy || test_failed $LINENO rm -f copy -"${LZIP}" -s16 < in > anyothername || fail=1 -"${LZIP}" -d -o copy - anyothername - < "${in_lz}" -if [ $? = 0 ] && cmp in copy && cmp in anyothername.out ; then - printf . ; else printf - ; fail=1 ; fi +"${LZIP}" -s16 < in > anyothername || test_failed $LINENO +"${LZIP}" -dv --output copy - anyothername - < "${in_lz}" 2> /dev/null +{ [ $? = 0 ] && cmp in copy && cmp in anyothername.out ; } || + test_failed $LINENO rm -f copy anyothername.out "${LZIP}" -tq in "${in_lz}" -if [ $? = 2 ] ; then printf . ; else printf - ; fail=1 ; fi -"${LZIP}" -tq foo.lz "${in_lz}" -if [ $? = 1 ] ; then printf . ; else printf - ; fail=1 ; fi +[ $? = 2 ] || test_failed $LINENO +"${LZIP}" -tq nx_file.lz "${in_lz}" +[ $? = 1 ] || test_failed $LINENO "${LZIP}" -cdq in "${in_lz}" > copy -if [ $? = 2 ] && cat copy in | cmp in - ; then printf . ; else printf - ; fail=1 ; fi -"${LZIP}" -cdq foo.lz "${in_lz}" > copy -if [ $? = 1 ] && cmp in copy ; then printf . ; else printf - ; fail=1 ; fi +{ [ $? = 2 ] && cat copy in | cmp in - ; } || test_failed $LINENO +"${LZIP}" -cdq nx_file.lz "${in_lz}" > copy +{ [ $? = 1 ] && cmp in copy ; } || test_failed $LINENO rm -f copy cat "${in_lz}" > copy.lz || framework_failure +for i in 1 2 3 4 5 6 7 ; do + printf "g" >> copy.lz || framework_failure + "${LZIP}" -atvvvv copy.lz "${in_lz}" 2> /dev/null + [ $? = 2 ] || test_failed $LINENO $i +done "${LZIP}" -dq in copy.lz -if [ $? = 2 ] && [ -e copy.lz ] && [ ! -e copy ] && [ ! -e in.out ] ; then - printf . ; else printf - ; fail=1 ; fi -"${LZIP}" -dq foo.lz copy.lz -if [ $? = 1 ] && [ ! -e copy.lz ] && [ ! -e foo ] && cmp in copy ; then - printf . ; else printf - ; fail=1 ; fi +{ [ $? = 2 ] && [ -e copy.lz ] && [ ! -e copy ] && [ ! -e in.out ] ; } || + test_failed $LINENO +"${LZIP}" -dq nx_file.lz copy.lz +{ [ $? = 1 ] && [ ! -e copy.lz ] && [ ! -e nx_file ] && cmp in copy ; } || + test_failed $LINENO cat in in > in2 || framework_failure -"${LZIP}" -s16 -o copy2 < in2 || fail=1 -"${LZIP}" -t copy2.lz || fail=1 -"${LZIP}" -cd copy2.lz > copy2 || fail=1 -cmp in2 copy2 || fail=1 -printf . +cat "${in_lz}" "${in_lz}" > in2.lz || framework_failure +"${LZIP}" -t in2.lz || test_failed $LINENO +"${LZIP}" -cd in2.lz > copy2 || test_failed $LINENO +cmp in2 copy2 || test_failed $LINENO -printf "garbage" >> copy2.lz || framework_failure +"${LZIP}" -s16 --output=copy2 < in2 || test_failed $LINENO +"${LZIP}" -t copy2.lz || test_failed $LINENO +"${LZIP}" -cd copy2.lz > copy2 || test_failed $LINENO +cmp in2 copy2 || test_failed $LINENO + +printf "\ngarbage" >> copy2.lz || framework_failure +"${LZIP}" -tvvvv copy2.lz 2> /dev/null || test_failed $LINENO rm -f copy2 "${LZIP}" -atq copy2.lz -if [ $? = 2 ] ; then printf . ; else printf - ; fail=1 ; fi +[ $? = 2 ] || test_failed $LINENO "${LZIP}" -atq < copy2.lz -if [ $? = 2 ] ; then printf . ; else printf - ; fail=1 ; fi +[ $? = 2 ] || test_failed $LINENO "${LZIP}" -adkq copy2.lz -if [ $? = 2 ] && [ ! -e copy2 ] ; then printf . ; else printf - ; fail=1 ; fi +{ [ $? = 2 ] && [ ! -e copy2 ] ; } || test_failed $LINENO "${LZIP}" -adkq -o copy2 < copy2.lz -if [ $? = 2 ] && [ ! -e copy2 ] ; then printf . ; else printf - ; fail=1 ; fi +{ [ $? = 2 ] && [ ! -e copy2 ] ; } || test_failed $LINENO printf "to be overwritten" > copy2 || framework_failure -"${LZIP}" -df copy2.lz || fail=1 -cmp in2 copy2 || fail=1 -printf . +"${LZIP}" -df copy2.lz || test_failed $LINENO +cmp in2 copy2 || test_failed $LINENO printf "\ntesting compression..." -"${LZIP}" -cfq "${in_lz}" > out # /dev/null is a tty on OS/2 -if [ $? = 1 ] ; then printf . ; else printf - ; fail=1 ; fi -"${LZIP}" -cF -s16 "${in_lz}" > out || fail=1 -"${LZIP}" -cd out | "${LZIP}" -d > copy || fail=1 -cmp in copy || fail=1 -printf . +"${LZIP}" -cf "${in_lz}" > out 2> /dev/null # /dev/null is a tty on OS/2 +[ $? = 1 ] || test_failed $LINENO +"${LZIP}" -cFvvm36 -s16 "${in_lz}" > out 2> /dev/null || test_failed $LINENO +"${LZIP}" -cd out | "${LZIP}" -d > copy || test_failed $LINENO +cmp in copy || test_failed $LINENO for i in s4Ki 0 1 2 3 4 5 6 7 8 9 ; do - "${LZIP}" -k -$i -s16 in || fail=1 - mv -f in.lz copy.lz || fail=1 - printf "garbage" >> copy.lz || fail=1 - "${LZIP}" -df copy.lz || fail=1 - cmp in copy || fail=1 + "${LZIP}" -k -$i -s16 in || test_failed $LINENO $i + mv -f in.lz copy.lz || test_failed $LINENO $i + printf "garbage" >> copy.lz || framework_failure + "${LZIP}" -df copy.lz || test_failed $LINENO $i + cmp in copy || test_failed $LINENO $i done -printf . for i in s4Ki 0 1 2 3 4 5 6 7 8 9 ; do - "${LZIP}" -c -$i -s16 in > out || fail=1 - printf "g" >> out || fail=1 - "${LZIP}" -cd out > copy || fail=1 - cmp in copy || fail=1 + "${LZIP}" -c -$i -s16 in > out || test_failed $LINENO $i + printf "g" >> out || framework_failure + "${LZIP}" -cd out > copy || test_failed $LINENO $i + cmp in copy || test_failed $LINENO $i done -printf . for i in s4Ki 0 1 2 3 4 5 6 7 8 9 ; do - "${LZIP}" -$i -s16 < in > out || fail=1 - "${LZIP}" -d < out > copy || fail=1 - cmp in copy || fail=1 + "${LZIP}" -$i -s16 < in > out || test_failed $LINENO $i + "${LZIP}" -d < out > copy || test_failed $LINENO $i + cmp in copy || test_failed $LINENO $i done -printf . for i in s4Ki 0 1 2 3 4 5 6 7 8 9 ; do - "${LZIP}" -f -$i -s16 -o out < in || fail=1 - "${LZIP}" -df -o copy < out.lz || fail=1 - cmp in copy || fail=1 + "${LZIP}" -f -$i -s16 -o out < in || test_failed $LINENO $i + "${LZIP}" -df -o copy < out.lz || test_failed $LINENO $i + cmp in copy || test_failed $LINENO $i done -printf . - -"${BBEXAMPLE}" in || fail=1 -printf . -"${BBEXAMPLE}" out || fail=1 -printf . -"${BBEXAMPLE}" ${test2} || fail=1 -printf . - -"${LZCHECK}" in || fail=1 -printf . -"${LZCHECK}" out || fail=1 -printf . -"${LZCHECK}" ${test2} || fail=1 -printf . + +cat in in in in in in in in > in8 || framework_failure +"${LZIP}" -1s12 -S100k -o out < in8 || test_failed $LINENO +"${LZIP}" -t out00001.lz out00002.lz || test_failed $LINENO +"${LZIP}" -cd out00001.lz out00002.lz | cmp in8 - || test_failed $LINENO +rm -f out00001.lz +"${LZIP}" -1ks4Ki -b100000 in8 || test_failed $LINENO +"${LZIP}" -t in8.lz || test_failed $LINENO +"${LZIP}" -cd in8.lz | cmp in8 - || test_failed $LINENO +rm -f in8 +"${LZIP}" -0 -S100k -o out < in8.lz || test_failed $LINENO +"${LZIP}" -t out00001.lz out00002.lz || test_failed $LINENO +"${LZIP}" -cd out00001.lz out00002.lz | cmp in8.lz - || test_failed $LINENO +rm -f out00001.lz out00002.lz +"${LZIP}" -0kF -b100k in8.lz || test_failed $LINENO +"${LZIP}" -t in8.lz.lz || test_failed $LINENO +"${LZIP}" -cd in8.lz.lz | cmp in8.lz - || test_failed $LINENO +rm -f in8.lz in8.lz.lz + +"${BBEXAMPLE}" in || test_failed $LINENO +"${BBEXAMPLE}" out || test_failed $LINENO +"${BBEXAMPLE}" ${test2} || test_failed $LINENO + +"${LZCHECK}" in || test_failed $LINENO +"${LZCHECK}" out || test_failed $LINENO +"${LZCHECK}" ${test2} || test_failed $LINENO + +printf "\ntesting bad input..." + +cat "${in_lz}" "${in_lz}" "${in_lz}" > in3.lz || framework_failure +if dd if=in3.lz of=trunc.lz bs=14752 count=1 2> /dev/null && + [ -e trunc.lz ] && cmp in2.lz trunc.lz > /dev/null 2>&1 ; then + for i in 6 20 14734 14753 14754 14755 14756 14757 14758 ; do + dd if=in3.lz of=trunc.lz bs=$i count=1 2> /dev/null + "${LZIP}" -t trunc.lz 2> /dev/null + [ $? = 2 ] || test_failed $LINENO $i + "${LZIP}" -tq < trunc.lz + [ $? = 2 ] || test_failed $LINENO $i + "${LZIP}" -cdq trunc.lz > out + [ $? = 2 ] || test_failed $LINENO $i + "${LZIP}" -dq < trunc.lz > out + [ $? = 2 ] || test_failed $LINENO $i + done +else + printf "\nwarning: skipping truncation test: 'dd' does not work on your system." +fi + +cat "${in_lz}" > ingin.lz || framework_failure +printf "g" >> ingin.lz || framework_failure +cat "${in_lz}" >> ingin.lz || framework_failure +"${LZIP}" -t ingin.lz || test_failed $LINENO +"${LZIP}" -cd ingin.lz > copy || test_failed $LINENO +cmp in copy || test_failed $LINENO +"${LZIP}" -t < ingin.lz || test_failed $LINENO +"${LZIP}" -d < ingin.lz > copy || test_failed $LINENO +cmp in copy || test_failed $LINENO echo if [ ${fail} = 0 ] ; then diff --git a/testsuite/test.txt.lz b/testsuite/test.txt.lz Binary files differindex 41d2e39..22cea6e 100644 --- a/testsuite/test.txt.lz +++ b/testsuite/test.txt.lz |