f3c88284b9
Decrease required version of poppler to 22.01.0. Change doc path. Revert removal of unarr as libarchive 3.6.0 is not in Fedora 36.
7785 lines
239 KiB
Diff
7785 lines
239 KiB
Diff
From d97fdcda6ea210cf00329d5887287acd33836114 Mon Sep 17 00:00:00 2001
|
||
From: Bastien Nocera <hadess@hadess.net>
|
||
Date: Wed, 12 Jan 2022 16:18:29 +0100
|
||
Subject: [PATCH 2/2] unarr: Remove obsolete unarr copy/paste
|
||
|
||
RAR support is now in libarchive.
|
||
|
||
Closes: #848, #1396
|
||
---
|
||
cut-n-paste/meson.build | 1 -
|
||
cut-n-paste/unarr/AUTHORS | 12 -
|
||
cut-n-paste/unarr/COPYING | 165 ----
|
||
cut-n-paste/unarr/common/allocator.h | 29 -
|
||
cut-n-paste/unarr/common/conv.c | 96 --
|
||
cut-n-paste/unarr/common/crc32.c | 51 -
|
||
cut-n-paste/unarr/common/stream.c | 217 -----
|
||
cut-n-paste/unarr/common/unarr-imp.h | 81 --
|
||
cut-n-paste/unarr/common/unarr.c | 110 ---
|
||
cut-n-paste/unarr/lzmasdk/7zTypes.h | 525 ----------
|
||
cut-n-paste/unarr/lzmasdk/CpuArch.c | 478 ----------
|
||
cut-n-paste/unarr/lzmasdk/CpuArch.h | 442 ---------
|
||
cut-n-paste/unarr/lzmasdk/Ppmd.h | 167 ----
|
||
cut-n-paste/unarr/lzmasdk/Ppmd7.c | 1104 ----------------------
|
||
cut-n-paste/unarr/lzmasdk/Ppmd7.h | 181 ----
|
||
cut-n-paste/unarr/lzmasdk/Ppmd7Dec.c | 297 ------
|
||
cut-n-paste/unarr/lzmasdk/Precomp.h | 10 -
|
||
cut-n-paste/unarr/lzmasdk/README.lzmasdk | 15 -
|
||
cut-n-paste/unarr/meson.build | 28 -
|
||
cut-n-paste/unarr/rar/filter-rar.c | 704 --------------
|
||
cut-n-paste/unarr/rar/huffman-rar.c | 142 ---
|
||
cut-n-paste/unarr/rar/lzss.h | 88 --
|
||
cut-n-paste/unarr/rar/parse-rar.c | 236 -----
|
||
cut-n-paste/unarr/rar/rar.c | 254 -----
|
||
cut-n-paste/unarr/rar/rar.h | 252 -----
|
||
cut-n-paste/unarr/rar/rarvm.c | 616 ------------
|
||
cut-n-paste/unarr/rar/rarvm.h | 117 ---
|
||
cut-n-paste/unarr/rar/uncompress-rar.c | 1000 --------------------
|
||
cut-n-paste/unarr/unarr.h | 103 --
|
||
po/POTFILES.skip | 1 -
|
||
30 files changed, 7522 deletions(-)
|
||
delete mode 100644 cut-n-paste/unarr/AUTHORS
|
||
delete mode 100644 cut-n-paste/unarr/COPYING
|
||
delete mode 100644 cut-n-paste/unarr/common/allocator.h
|
||
delete mode 100644 cut-n-paste/unarr/common/conv.c
|
||
delete mode 100644 cut-n-paste/unarr/common/crc32.c
|
||
delete mode 100644 cut-n-paste/unarr/common/stream.c
|
||
delete mode 100644 cut-n-paste/unarr/common/unarr-imp.h
|
||
delete mode 100644 cut-n-paste/unarr/common/unarr.c
|
||
delete mode 100644 cut-n-paste/unarr/lzmasdk/7zTypes.h
|
||
delete mode 100644 cut-n-paste/unarr/lzmasdk/CpuArch.c
|
||
delete mode 100644 cut-n-paste/unarr/lzmasdk/CpuArch.h
|
||
delete mode 100644 cut-n-paste/unarr/lzmasdk/Ppmd.h
|
||
delete mode 100644 cut-n-paste/unarr/lzmasdk/Ppmd7.c
|
||
delete mode 100644 cut-n-paste/unarr/lzmasdk/Ppmd7.h
|
||
delete mode 100644 cut-n-paste/unarr/lzmasdk/Ppmd7Dec.c
|
||
delete mode 100644 cut-n-paste/unarr/lzmasdk/Precomp.h
|
||
delete mode 100644 cut-n-paste/unarr/lzmasdk/README.lzmasdk
|
||
delete mode 100644 cut-n-paste/unarr/meson.build
|
||
delete mode 100644 cut-n-paste/unarr/rar/filter-rar.c
|
||
delete mode 100644 cut-n-paste/unarr/rar/huffman-rar.c
|
||
delete mode 100644 cut-n-paste/unarr/rar/lzss.h
|
||
delete mode 100644 cut-n-paste/unarr/rar/parse-rar.c
|
||
delete mode 100644 cut-n-paste/unarr/rar/rar.c
|
||
delete mode 100644 cut-n-paste/unarr/rar/rar.h
|
||
delete mode 100644 cut-n-paste/unarr/rar/rarvm.c
|
||
delete mode 100644 cut-n-paste/unarr/rar/rarvm.h
|
||
delete mode 100644 cut-n-paste/unarr/rar/uncompress-rar.c
|
||
delete mode 100644 cut-n-paste/unarr/unarr.h
|
||
|
||
diff --git a/cut-n-paste/meson.build b/cut-n-paste/meson.build
|
||
index 0f4dbd30..279061d2 100644
|
||
--- a/cut-n-paste/meson.build
|
||
+++ b/cut-n-paste/meson.build
|
||
@@ -3,7 +3,6 @@ cut_n_paste_inc = include_directories('.')
|
||
subdir('gimpcellrenderertoggle')
|
||
subdir('libdazzle')
|
||
subdir('libgd')
|
||
-subdir('unarr')
|
||
|
||
if not external_synctex
|
||
subdir('synctex')
|
||
diff --git a/cut-n-paste/unarr/AUTHORS b/cut-n-paste/unarr/AUTHORS
|
||
deleted file mode 100644
|
||
index 4af1be7c..00000000
|
||
--- a/cut-n-paste/unarr/AUTHORS
|
||
+++ /dev/null
|
||
@@ -1,12 +0,0 @@
|
||
-unarr contains code by:
|
||
-
|
||
-* The Unarchiver project (https://code.google.com/p/theunarchiver/)
|
||
-* Simon Bünzli (zeniko at gmail.com, http://www.zeniko.ch/#SumatraPDF)
|
||
-
|
||
-Most code is licensed under LGPLv3 (see COPYING). Exceptions are in code
|
||
-included from other projects:
|
||
-
|
||
-Files License URL
|
||
-----------------------------------------------------------------------------------
|
||
-common/crc32.c Public Domain https://gnunet.org/svn/gnunet/src/util/crypto_crc.c
|
||
-lzmasdk/*.* Public Domain http://www.7-zip.org/sdk.html
|
||
diff --git a/cut-n-paste/unarr/COPYING b/cut-n-paste/unarr/COPYING
|
||
deleted file mode 100644
|
||
index 65c5ca88..00000000
|
||
--- a/cut-n-paste/unarr/COPYING
|
||
+++ /dev/null
|
||
@@ -1,165 +0,0 @@
|
||
- GNU LESSER GENERAL PUBLIC LICENSE
|
||
- Version 3, 29 June 2007
|
||
-
|
||
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||
- Everyone is permitted to copy and distribute verbatim copies
|
||
- of this license document, but changing it is not allowed.
|
||
-
|
||
-
|
||
- This version of the GNU Lesser General Public License incorporates
|
||
-the terms and conditions of version 3 of the GNU General Public
|
||
-License, supplemented by the additional permissions listed below.
|
||
-
|
||
- 0. Additional Definitions.
|
||
-
|
||
- As used herein, "this License" refers to version 3 of the GNU Lesser
|
||
-General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||
-General Public License.
|
||
-
|
||
- "The Library" refers to a covered work governed by this License,
|
||
-other than an Application or a Combined Work as defined below.
|
||
-
|
||
- An "Application" is any work that makes use of an interface provided
|
||
-by the Library, but which is not otherwise based on the Library.
|
||
-Defining a subclass of a class defined by the Library is deemed a mode
|
||
-of using an interface provided by the Library.
|
||
-
|
||
- A "Combined Work" is a work produced by combining or linking an
|
||
-Application with the Library. The particular version of the Library
|
||
-with which the Combined Work was made is also called the "Linked
|
||
-Version".
|
||
-
|
||
- The "Minimal Corresponding Source" for a Combined Work means the
|
||
-Corresponding Source for the Combined Work, excluding any source code
|
||
-for portions of the Combined Work that, considered in isolation, are
|
||
-based on the Application, and not on the Linked Version.
|
||
-
|
||
- The "Corresponding Application Code" for a Combined Work means the
|
||
-object code and/or source code for the Application, including any data
|
||
-and utility programs needed for reproducing the Combined Work from the
|
||
-Application, but excluding the System Libraries of the Combined Work.
|
||
-
|
||
- 1. Exception to Section 3 of the GNU GPL.
|
||
-
|
||
- You may convey a covered work under sections 3 and 4 of this License
|
||
-without being bound by section 3 of the GNU GPL.
|
||
-
|
||
- 2. Conveying Modified Versions.
|
||
-
|
||
- If you modify a copy of the Library, and, in your modifications, a
|
||
-facility refers to a function or data to be supplied by an Application
|
||
-that uses the facility (other than as an argument passed when the
|
||
-facility is invoked), then you may convey a copy of the modified
|
||
-version:
|
||
-
|
||
- a) under this License, provided that you make a good faith effort to
|
||
- ensure that, in the event an Application does not supply the
|
||
- function or data, the facility still operates, and performs
|
||
- whatever part of its purpose remains meaningful, or
|
||
-
|
||
- b) under the GNU GPL, with none of the additional permissions of
|
||
- this License applicable to that copy.
|
||
-
|
||
- 3. Object Code Incorporating Material from Library Header Files.
|
||
-
|
||
- The object code form of an Application may incorporate material from
|
||
-a header file that is part of the Library. You may convey such object
|
||
-code under terms of your choice, provided that, if the incorporated
|
||
-material is not limited to numerical parameters, data structure
|
||
-layouts and accessors, or small macros, inline functions and templates
|
||
-(ten or fewer lines in length), you do both of the following:
|
||
-
|
||
- a) Give prominent notice with each copy of the object code that the
|
||
- Library is used in it and that the Library and its use are
|
||
- covered by this License.
|
||
-
|
||
- b) Accompany the object code with a copy of the GNU GPL and this license
|
||
- document.
|
||
-
|
||
- 4. Combined Works.
|
||
-
|
||
- You may convey a Combined Work under terms of your choice that,
|
||
-taken together, effectively do not restrict modification of the
|
||
-portions of the Library contained in the Combined Work and reverse
|
||
-engineering for debugging such modifications, if you also do each of
|
||
-the following:
|
||
-
|
||
- a) Give prominent notice with each copy of the Combined Work that
|
||
- the Library is used in it and that the Library and its use are
|
||
- covered by this License.
|
||
-
|
||
- b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||
- document.
|
||
-
|
||
- c) For a Combined Work that displays copyright notices during
|
||
- execution, include the copyright notice for the Library among
|
||
- these notices, as well as a reference directing the user to the
|
||
- copies of the GNU GPL and this license document.
|
||
-
|
||
- d) Do one of the following:
|
||
-
|
||
- 0) Convey the Minimal Corresponding Source under the terms of this
|
||
- License, and the Corresponding Application Code in a form
|
||
- suitable for, and under terms that permit, the user to
|
||
- recombine or relink the Application with a modified version of
|
||
- the Linked Version to produce a modified Combined Work, in the
|
||
- manner specified by section 6 of the GNU GPL for conveying
|
||
- Corresponding Source.
|
||
-
|
||
- 1) Use a suitable shared library mechanism for linking with the
|
||
- Library. A suitable mechanism is one that (a) uses at run time
|
||
- a copy of the Library already present on the user's computer
|
||
- system, and (b) will operate properly with a modified version
|
||
- of the Library that is interface-compatible with the Linked
|
||
- Version.
|
||
-
|
||
- e) Provide Installation Information, but only if you would otherwise
|
||
- be required to provide such information under section 6 of the
|
||
- GNU GPL, and only to the extent that such information is
|
||
- necessary to install and execute a modified version of the
|
||
- Combined Work produced by recombining or relinking the
|
||
- Application with a modified version of the Linked Version. (If
|
||
- you use option 4d0, the Installation Information must accompany
|
||
- the Minimal Corresponding Source and Corresponding Application
|
||
- Code. If you use option 4d1, you must provide the Installation
|
||
- Information in the manner specified by section 6 of the GNU GPL
|
||
- for conveying Corresponding Source.)
|
||
-
|
||
- 5. Combined Libraries.
|
||
-
|
||
- You may place library facilities that are a work based on the
|
||
-Library side by side in a single library together with other library
|
||
-facilities that are not Applications and are not covered by this
|
||
-License, and convey such a combined library under terms of your
|
||
-choice, if you do both of the following:
|
||
-
|
||
- a) Accompany the combined library with a copy of the same work based
|
||
- on the Library, uncombined with any other library facilities,
|
||
- conveyed under the terms of this License.
|
||
-
|
||
- b) Give prominent notice with the combined library that part of it
|
||
- is a work based on the Library, and explaining where to find the
|
||
- accompanying uncombined form of the same work.
|
||
-
|
||
- 6. Revised Versions of the GNU Lesser General Public License.
|
||
-
|
||
- The Free Software Foundation may publish revised and/or new versions
|
||
-of the GNU Lesser General Public License from time to time. Such new
|
||
-versions will be similar in spirit to the present version, but may
|
||
-differ in detail to address new problems or concerns.
|
||
-
|
||
- Each version is given a distinguishing version number. If the
|
||
-Library as you received it specifies that a certain numbered version
|
||
-of the GNU Lesser General Public License "or any later version"
|
||
-applies to it, you have the option of following the terms and
|
||
-conditions either of that published version or of any later version
|
||
-published by the Free Software Foundation. If the Library as you
|
||
-received it does not specify a version number of the GNU Lesser
|
||
-General Public License, you may choose any version of the GNU Lesser
|
||
-General Public License ever published by the Free Software Foundation.
|
||
-
|
||
- If the Library as you received it specifies that a proxy can decide
|
||
-whether future versions of the GNU Lesser General Public License shall
|
||
-apply, that proxy's public statement of acceptance of any version is
|
||
-permanent authorization for you to choose that version for the
|
||
-Library.
|
||
diff --git a/cut-n-paste/unarr/common/allocator.h b/cut-n-paste/unarr/common/allocator.h
|
||
deleted file mode 100644
|
||
index 41199c80..00000000
|
||
--- a/cut-n-paste/unarr/common/allocator.h
|
||
+++ /dev/null
|
||
@@ -1,29 +0,0 @@
|
||
-/* Copyright 2015 the unarr project authors (see AUTHORS file).
|
||
- License: LGPLv3 */
|
||
-
|
||
-#ifndef common_allocator_h
|
||
-#define common_allocator_h
|
||
-
|
||
-#ifdef USE_CUSTOM_ALLOCATOR
|
||
-
|
||
-#include <stddef.h>
|
||
-
|
||
-typedef void *(* custom_malloc_fn)(void *opaque, size_t size);
|
||
-typedef void (* custom_free_fn)(void *opaque, void *ptr);
|
||
-
|
||
-void ar_set_custom_allocator(custom_malloc_fn custom_malloc, custom_free_fn custom_free, void *opaque);
|
||
-
|
||
-#define malloc(size) ar_malloc(size)
|
||
-#define calloc(count, size) ar_calloc(count, size)
|
||
-#define free(ptr) ar_free(ptr)
|
||
-
|
||
-#define realloc(ptr, size) _use_malloc_memcpy_free_instead(ptr, size)
|
||
-#define strdup(str) _use_malloc_memcpy_instead(str)
|
||
-
|
||
-#elif !defined(NDEBUG) && defined(_MSC_VER)
|
||
-
|
||
-#include <crtdbg.h>
|
||
-
|
||
-#endif
|
||
-
|
||
-#endif
|
||
diff --git a/cut-n-paste/unarr/common/conv.c b/cut-n-paste/unarr/common/conv.c
|
||
deleted file mode 100644
|
||
index 4398539b..00000000
|
||
--- a/cut-n-paste/unarr/common/conv.c
|
||
+++ /dev/null
|
||
@@ -1,96 +0,0 @@
|
||
-/* Copyright 2015 the unarr project authors (see AUTHORS file).
|
||
- License: LGPLv3 */
|
||
-
|
||
-#include "unarr-imp.h"
|
||
-
|
||
-#include <time.h>
|
||
-
|
||
-/* data from http://en.wikipedia.org/wiki/Cp437 */
|
||
-static const wchar_t gCp437[256] = {
|
||
- 0, 0x263A, 0x263B, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022, 0x25D8, 0x25CB, 0x25D9, 0x2642, 0x2640, 0x266A, 0x266C, 0x263C,
|
||
- 0x25BA, 0x25C4, 0x2195, 0x203C, 0x00B6, 0x00A7, 0x25AC, 0x21A8, 0x2191, 0x2193, 0x2192, 0x2190, 0x221F, 0x2194, 0x25B2, 0x25BC,
|
||
- ' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/',
|
||
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?',
|
||
- '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
|
||
- 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
|
||
- '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
|
||
- 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', 0x2302,
|
||
- 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
|
||
- 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
|
||
- 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||
- 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||
- 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||
- 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||
- 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
||
- 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0,
|
||
-};
|
||
-
|
||
-size_t ar_conv_rune_to_utf8(wchar_t rune, char *out, size_t size)
|
||
-{
|
||
- if (size < 1)
|
||
- return 0;
|
||
- if (rune < 0x0080) {
|
||
- *out++ = rune & 0x7F;
|
||
- return 1;
|
||
- }
|
||
- if (rune < 0x0800 && size >= 2) {
|
||
- *out++ = 0xC0 | ((rune >> 6) & 0x1F);
|
||
- *out++ = 0x80 | (rune & 0x3F);
|
||
- return 2;
|
||
- }
|
||
- if (size >= 3) {
|
||
- if ((0xD800 <= rune && rune <= 0xDFFF) || rune >= 0x10000)
|
||
- rune = 0xFFFD;
|
||
- *out++ = 0xE0 | ((rune >> 12) & 0x0F);
|
||
- *out++ = 0x80 | ((rune >> 6) & 0x3F);
|
||
- *out++ = 0x80 | (rune & 0x3F);
|
||
- return 3;
|
||
- }
|
||
- *out++ = '?';
|
||
- return 1;
|
||
-}
|
||
-
|
||
-char *ar_conv_dos_to_utf8(const char *astr)
|
||
-{
|
||
- char *str, *out;
|
||
- const char *in;
|
||
- size_t size;
|
||
-
|
||
- size = 0;
|
||
- for (in = astr; *in; in++) {
|
||
- char buf[4];
|
||
- size += ar_conv_rune_to_utf8(gCp437[(uint8_t)*in], buf, sizeof(buf));
|
||
- }
|
||
-
|
||
- if (size == (size_t)-1)
|
||
- return NULL;
|
||
- str = malloc(size + 1);
|
||
- if (!str)
|
||
- return NULL;
|
||
-
|
||
- for (in = astr, out = str; *in; in++) {
|
||
- out += ar_conv_rune_to_utf8(gCp437[(uint8_t)*in], out, str + size - out);
|
||
- }
|
||
- *out = '\0';
|
||
-
|
||
- return str;
|
||
-}
|
||
-
|
||
-time64_t ar_conv_dosdate_to_filetime(uint32_t dosdate)
|
||
-{
|
||
- struct tm tm;
|
||
- time_t t1, t2;
|
||
-
|
||
- tm.tm_sec = (dosdate & 0x1F) * 2;
|
||
- tm.tm_min = (dosdate >> 5) & 0x3F;
|
||
- tm.tm_hour = (dosdate >> 11) & 0x1F;
|
||
- tm.tm_mday = (dosdate >> 16) & 0x1F;
|
||
- tm.tm_mon = ((dosdate >> 21) & 0x0F) - 1;
|
||
- tm.tm_year = ((dosdate >> 25) & 0x7F) + 80;
|
||
- tm.tm_isdst = -1;
|
||
-
|
||
- t1 = mktime(&tm);
|
||
- t2 = mktime(gmtime(&t1));
|
||
-
|
||
- return (time64_t)(2 * t1 - t2 + 11644473600) * 10000000;
|
||
-}
|
||
diff --git a/cut-n-paste/unarr/common/crc32.c b/cut-n-paste/unarr/common/crc32.c
|
||
deleted file mode 100644
|
||
index b482e6e3..00000000
|
||
--- a/cut-n-paste/unarr/common/crc32.c
|
||
+++ /dev/null
|
||
@@ -1,51 +0,0 @@
|
||
-/* Copyright 2015 the unarr project authors (see AUTHORS file).
|
||
- License: LGPLv3 */
|
||
-
|
||
-#include "unarr-imp.h"
|
||
-
|
||
-#ifndef HAVE_ZLIB
|
||
-
|
||
-/* code adapted from https://gnunet.org/svn/gnunet/src/util/crypto_crc.c (public domain) */
|
||
-
|
||
-static bool crc_table_ready = false;
|
||
-static uint32_t crc_table[256];
|
||
-
|
||
-uint32_t ar_crc32(uint32_t crc32, const unsigned char *data, size_t data_len)
|
||
-{
|
||
- if (!crc_table_ready) {
|
||
- uint32_t i, j;
|
||
- uint32_t h = 1;
|
||
- crc_table[0] = 0;
|
||
- for (i = 128; i; i >>= 1) {
|
||
- h = (h >> 1) ^ ((h & 1) ? 0xEDB88320 : 0);
|
||
- for (j = 0; j < 256; j += 2 * i) {
|
||
- crc_table[i + j] = crc_table[j] ^ h;
|
||
- }
|
||
- }
|
||
- crc_table_ready = true;
|
||
- }
|
||
-
|
||
- crc32 = crc32 ^ 0xFFFFFFFF;
|
||
- while (data_len-- > 0) {
|
||
- crc32 = (crc32 >> 8) ^ crc_table[(crc32 ^ *data++) & 0xFF];
|
||
- }
|
||
- return crc32 ^ 0xFFFFFFFF;
|
||
-}
|
||
-
|
||
-#else
|
||
-
|
||
-#include <zlib.h>
|
||
-
|
||
-uint32_t ar_crc32(uint32_t crc, const unsigned char *data, size_t data_len)
|
||
-{
|
||
-#if SIZE_MAX > UINT32_MAX
|
||
- while (data_len > UINT32_MAX) {
|
||
- crc = crc32(crc, data, UINT32_MAX);
|
||
- data += UINT32_MAX;
|
||
- data_len -= UINT32_MAX;
|
||
- }
|
||
-#endif
|
||
- return crc32(crc, data, (uint32_t)data_len);
|
||
-}
|
||
-
|
||
-#endif
|
||
diff --git a/cut-n-paste/unarr/common/stream.c b/cut-n-paste/unarr/common/stream.c
|
||
deleted file mode 100644
|
||
index 64fe19b3..00000000
|
||
--- a/cut-n-paste/unarr/common/stream.c
|
||
+++ /dev/null
|
||
@@ -1,217 +0,0 @@
|
||
-/* Copyright 2015 the unarr project authors (see AUTHORS file).
|
||
- License: LGPLv3 */
|
||
-
|
||
-#include "unarr-imp.h"
|
||
-
|
||
-ar_stream *ar_open_stream(void *data, ar_stream_close_fn close, ar_stream_read_fn read, ar_stream_seek_fn seek, ar_stream_tell_fn tell)
|
||
-{
|
||
- ar_stream *stream = malloc(sizeof(ar_stream));
|
||
- if (!stream) {
|
||
- close(data);
|
||
- return NULL;
|
||
- }
|
||
- stream->data = data;
|
||
- stream->close = close;
|
||
- stream->read = read;
|
||
- stream->seek = seek;
|
||
- stream->tell = tell;
|
||
- return stream;
|
||
-}
|
||
-
|
||
-void ar_close(ar_stream *stream)
|
||
-{
|
||
- if (stream)
|
||
- stream->close(stream->data);
|
||
- free(stream);
|
||
-}
|
||
-
|
||
-size_t ar_read(ar_stream *stream, void *buffer, size_t count)
|
||
-{
|
||
- return stream->read(stream->data, buffer, count);
|
||
-}
|
||
-
|
||
-bool ar_seek(ar_stream *stream, off64_t offset, int origin)
|
||
-{
|
||
- return stream->seek(stream->data, offset, origin);
|
||
-}
|
||
-
|
||
-bool ar_skip(ar_stream *stream, off64_t count)
|
||
-{
|
||
- return stream->seek(stream->data, count, SEEK_CUR);
|
||
-}
|
||
-
|
||
-off64_t ar_tell(ar_stream *stream)
|
||
-{
|
||
- return stream->tell(stream->data);
|
||
-}
|
||
-
|
||
-/***** stream based on FILE *****/
|
||
-
|
||
-static void file_close(void *data)
|
||
-{
|
||
- fclose(data);
|
||
-}
|
||
-
|
||
-static size_t file_read(void *data, void *buffer, size_t count)
|
||
-{
|
||
- return fread(buffer, 1, count, data);
|
||
-}
|
||
-
|
||
-static bool file_seek(void *data, off64_t offset, int origin)
|
||
-{
|
||
-#ifdef _MSC_VER
|
||
- return _fseeki64(data, offset, origin) == 0;
|
||
-#else
|
||
-#if _POSIX_C_SOURCE >= 200112L
|
||
- if (sizeof(off_t) == 8)
|
||
- return fseeko(data, offset, origin) == 0;
|
||
-#endif
|
||
- if (offset > INT32_MAX || offset < INT32_MIN)
|
||
- return false;
|
||
- return fseek(data, (long)offset, origin) == 0;
|
||
-#endif
|
||
-}
|
||
-
|
||
-static off64_t file_tell(void *data)
|
||
-{
|
||
-#ifdef _MSC_VER
|
||
- return _ftelli64(data);
|
||
-#elif _POSIX_C_SOURCE >= 200112L
|
||
- return ftello(data);
|
||
-#else
|
||
- return ftell(data);
|
||
-#endif
|
||
-}
|
||
-
|
||
-ar_stream *ar_open_file(const char *path)
|
||
-{
|
||
- FILE *f = path ? fopen(path, "rb") : NULL;
|
||
- if (!f)
|
||
- return NULL;
|
||
- return ar_open_stream(f, file_close, file_read, file_seek, file_tell);
|
||
-}
|
||
-
|
||
-#ifdef _WIN32
|
||
-ar_stream *ar_open_file_w(const wchar_t *path)
|
||
-{
|
||
- FILE *f = path ? _wfopen(path, L"rb") : NULL;
|
||
- if (!f)
|
||
- return NULL;
|
||
- return ar_open_stream(f, file_close, file_read, file_seek, file_tell);
|
||
-}
|
||
-#endif
|
||
-
|
||
-/***** stream based on preallocated memory *****/
|
||
-
|
||
-struct MemoryStream {
|
||
- const uint8_t *data;
|
||
- size_t length;
|
||
- size_t offset;
|
||
-};
|
||
-
|
||
-static void memory_close(void *data)
|
||
-{
|
||
- struct MemoryStream *stm = data;
|
||
- free(stm);
|
||
-}
|
||
-
|
||
-static size_t memory_read(void *data, void *buffer, size_t count)
|
||
-{
|
||
- struct MemoryStream *stm = data;
|
||
- if (count > stm->length - stm->offset)
|
||
- count = stm->length - stm->offset;
|
||
- memcpy(buffer, stm->data + stm->offset, count);
|
||
- stm->offset += count;
|
||
- return count;
|
||
-}
|
||
-
|
||
-static bool memory_seek(void *data, off64_t offset, int origin)
|
||
-{
|
||
- struct MemoryStream *stm = data;
|
||
- if (origin == SEEK_CUR)
|
||
- offset += stm->offset;
|
||
- else if (origin == SEEK_END)
|
||
- offset += stm->length;
|
||
- if (offset < 0 || offset > (off64_t)stm->length || (size_t)offset > stm->length)
|
||
- return false;
|
||
- stm->offset = (size_t)offset;
|
||
- return true;
|
||
-}
|
||
-
|
||
-static off64_t memory_tell(void *data)
|
||
-{
|
||
- struct MemoryStream *stm = data;
|
||
- return stm->offset;
|
||
-}
|
||
-
|
||
-ar_stream *ar_open_memory(const void *data, size_t datalen)
|
||
-{
|
||
- struct MemoryStream *stm = malloc(sizeof(struct MemoryStream));
|
||
- if (!stm)
|
||
- return NULL;
|
||
- stm->data = data;
|
||
- stm->length = datalen;
|
||
- stm->offset = 0;
|
||
- return ar_open_stream(stm, memory_close, memory_read, memory_seek, memory_tell);
|
||
-}
|
||
-
|
||
-#ifdef _WIN32
|
||
-/***** stream based on IStream *****/
|
||
-
|
||
-#define COBJMACROS
|
||
-#include <windows.h>
|
||
-
|
||
-static void stream_close(void *data)
|
||
-{
|
||
- IUnknown_Release((IStream *)data);
|
||
-}
|
||
-
|
||
-static size_t stream_read(void *data, void *buffer, size_t count)
|
||
-{
|
||
- size_t read = 0;
|
||
- HRESULT res;
|
||
- ULONG cbRead;
|
||
-#ifdef _WIN64
|
||
- while (count > ULONG_MAX) {
|
||
- res = IStream_Read((IStream *)data, buffer, ULONG_MAX, &cbRead);
|
||
- if (FAILED(res))
|
||
- return read;
|
||
- read += cbRead;
|
||
- buffer = (BYTE *)buffer + ULONG_MAX;
|
||
- count -= ULONG_MAX;
|
||
- }
|
||
-#endif
|
||
- res = IStream_Read((IStream *)data, buffer, (ULONG)count, &cbRead);
|
||
- if (SUCCEEDED(res))
|
||
- read += cbRead;
|
||
- return read;
|
||
-}
|
||
-
|
||
-static bool stream_seek(void *data, off64_t offset, int origin)
|
||
-{
|
||
- LARGE_INTEGER off;
|
||
- ULARGE_INTEGER n;
|
||
- HRESULT res;
|
||
- off.QuadPart = offset;
|
||
- res = IStream_Seek((IStream *)data, off, origin, &n);
|
||
- return SUCCEEDED(res);
|
||
-}
|
||
-
|
||
-static off64_t stream_tell(void *data)
|
||
-{
|
||
- LARGE_INTEGER zero = { 0 };
|
||
- ULARGE_INTEGER n = { 0 };
|
||
- IStream_Seek((IStream *)data, zero, SEEK_CUR, &n);
|
||
- return (off64_t)n.QuadPart;
|
||
-}
|
||
-
|
||
-ar_stream *ar_open_istream(IStream *stream)
|
||
-{
|
||
- LARGE_INTEGER zero = { 0 };
|
||
- HRESULT res = IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL);
|
||
- if (FAILED(res))
|
||
- return NULL;
|
||
- IUnknown_AddRef(stream);
|
||
- return ar_open_stream(stream, stream_close, stream_read, stream_seek, stream_tell);
|
||
-}
|
||
-#endif
|
||
diff --git a/cut-n-paste/unarr/common/unarr-imp.h b/cut-n-paste/unarr/common/unarr-imp.h
|
||
deleted file mode 100644
|
||
index 90ad3178..00000000
|
||
--- a/cut-n-paste/unarr/common/unarr-imp.h
|
||
+++ /dev/null
|
||
@@ -1,81 +0,0 @@
|
||
-/* Copyright 2015 the unarr project authors (see AUTHORS file).
|
||
- License: LGPLv3 */
|
||
-
|
||
-/* this is the common private/implementation API of unarr which should only be used by unarr code */
|
||
-
|
||
-#ifndef common_unarr_imp_h
|
||
-#define common_unarr_imp_h
|
||
-
|
||
-#include "../unarr.h"
|
||
-#include "allocator.h"
|
||
-
|
||
-#include <stdlib.h>
|
||
-#include <stdio.h>
|
||
-#include <stdarg.h>
|
||
-#include <string.h>
|
||
-#include <inttypes.h>
|
||
-
|
||
-/***** conv ****/
|
||
-
|
||
-size_t ar_conv_rune_to_utf8(wchar_t rune, char *out, size_t size);
|
||
-char *ar_conv_dos_to_utf8(const char *astr);
|
||
-time64_t ar_conv_dosdate_to_filetime(uint32_t dosdate);
|
||
-
|
||
-/***** crc32 *****/
|
||
-
|
||
-uint32_t ar_crc32(uint32_t crc32, const unsigned char *data, size_t data_len);
|
||
-
|
||
-/***** stream *****/
|
||
-
|
||
-typedef void (* ar_stream_close_fn)(void *data);
|
||
-typedef size_t (* ar_stream_read_fn)(void *data, void *buffer, size_t count);
|
||
-typedef bool (* ar_stream_seek_fn)(void *data, off64_t offset, int origin);
|
||
-typedef off64_t (* ar_stream_tell_fn)(void *data);
|
||
-
|
||
-struct ar_stream_s {
|
||
- ar_stream_close_fn close;
|
||
- ar_stream_read_fn read;
|
||
- ar_stream_seek_fn seek;
|
||
- ar_stream_tell_fn tell;
|
||
- void *data;
|
||
-};
|
||
-
|
||
-ar_stream *ar_open_stream(void *data, ar_stream_close_fn close, ar_stream_read_fn read, ar_stream_seek_fn seek, ar_stream_tell_fn tell);
|
||
-
|
||
-/***** unarr *****/
|
||
-
|
||
-#define warn(...) ar_log("!", __FILE__, __LINE__, __VA_ARGS__)
|
||
-#ifndef NDEBUG
|
||
-#define log(...) ar_log("-", __FILE__, __LINE__, __VA_ARGS__)
|
||
-#else
|
||
-#define log(...) ((void)0)
|
||
-#endif
|
||
-void ar_log(const char *prefix, const char *file, int line, const char *msg, ...);
|
||
-
|
||
-typedef void (* ar_archive_close_fn)(ar_archive *ar);
|
||
-typedef bool (* ar_parse_entry_fn)(ar_archive *ar, off64_t offset);
|
||
-typedef const char *(* ar_entry_get_name_fn)(ar_archive *ar);
|
||
-typedef bool (* ar_entry_uncompress_fn)(ar_archive *ar, void *buffer, size_t count);
|
||
-typedef size_t (* ar_get_global_comment_fn)(ar_archive *ar, void *buffer, size_t count);
|
||
-
|
||
-struct ar_archive_s {
|
||
- ar_archive_close_fn close;
|
||
- ar_parse_entry_fn parse_entry;
|
||
- ar_entry_get_name_fn get_name;
|
||
- ar_entry_uncompress_fn uncompress;
|
||
- ar_get_global_comment_fn get_comment;
|
||
-
|
||
- ar_stream *stream;
|
||
- bool at_eof;
|
||
- off64_t entry_offset;
|
||
- off64_t entry_offset_first;
|
||
- off64_t entry_offset_next;
|
||
- size_t entry_size_uncompressed;
|
||
- time64_t entry_filetime;
|
||
-};
|
||
-
|
||
-ar_archive *ar_open_archive(ar_stream *stream, size_t struct_size, ar_archive_close_fn close, ar_parse_entry_fn parse_entry,
|
||
- ar_entry_get_name_fn get_name, ar_entry_uncompress_fn uncompress, ar_get_global_comment_fn get_comment,
|
||
- off64_t first_entry_offset);
|
||
-
|
||
-#endif
|
||
diff --git a/cut-n-paste/unarr/common/unarr.c b/cut-n-paste/unarr/common/unarr.c
|
||
deleted file mode 100644
|
||
index 49c6d981..00000000
|
||
--- a/cut-n-paste/unarr/common/unarr.c
|
||
+++ /dev/null
|
||
@@ -1,110 +0,0 @@
|
||
-/* Copyright 2015 the unarr project authors (see AUTHORS file).
|
||
- License: LGPLv3 */
|
||
-
|
||
-#include "unarr-imp.h"
|
||
-
|
||
-ar_archive *ar_open_archive(ar_stream *stream, size_t struct_size, ar_archive_close_fn close, ar_parse_entry_fn parse_entry,
|
||
- ar_entry_get_name_fn get_name, ar_entry_uncompress_fn uncompress, ar_get_global_comment_fn get_comment,
|
||
- off64_t first_entry_offset)
|
||
-{
|
||
- ar_archive *ar = malloc(struct_size);
|
||
- if (!ar)
|
||
- return NULL;
|
||
- memset(ar, 0, struct_size);
|
||
- ar->close = close;
|
||
- ar->parse_entry = parse_entry;
|
||
- ar->get_name = get_name;
|
||
- ar->uncompress = uncompress;
|
||
- ar->get_comment = get_comment;
|
||
- ar->stream = stream;
|
||
- ar->entry_offset_first = first_entry_offset;
|
||
- ar->entry_offset_next = first_entry_offset;
|
||
- return ar;
|
||
-}
|
||
-
|
||
-void ar_close_archive(ar_archive *ar)
|
||
-{
|
||
- if (ar)
|
||
- ar->close(ar);
|
||
- free(ar);
|
||
-}
|
||
-
|
||
-bool ar_at_eof(ar_archive *ar)
|
||
-{
|
||
- return ar->at_eof;
|
||
-}
|
||
-
|
||
-bool ar_parse_entry(ar_archive *ar)
|
||
-{
|
||
- return ar->parse_entry(ar, ar->entry_offset_next);
|
||
-}
|
||
-
|
||
-bool ar_parse_entry_at(ar_archive *ar, off64_t offset)
|
||
-{
|
||
- ar->at_eof = false;
|
||
- return ar->parse_entry(ar, offset ? offset : ar->entry_offset_first);
|
||
-}
|
||
-
|
||
-bool ar_parse_entry_for(ar_archive *ar, const char *entry_name)
|
||
-{
|
||
- ar->at_eof = false;
|
||
- if (!entry_name)
|
||
- return false;
|
||
- if (!ar_parse_entry_at(ar, ar->entry_offset_first))
|
||
- return false;
|
||
- do {
|
||
- const char *name = ar_entry_get_name(ar);
|
||
- if (name && strcmp(name, entry_name) == 0)
|
||
- return true;
|
||
- } while (ar_parse_entry(ar));
|
||
- return false;
|
||
-}
|
||
-
|
||
-const char *ar_entry_get_name(ar_archive *ar)
|
||
-{
|
||
- return ar->get_name(ar);
|
||
-}
|
||
-
|
||
-off64_t ar_entry_get_offset(ar_archive *ar)
|
||
-{
|
||
- return ar->entry_offset;
|
||
-}
|
||
-
|
||
-size_t ar_entry_get_size(ar_archive *ar)
|
||
-{
|
||
- return ar->entry_size_uncompressed;
|
||
-}
|
||
-
|
||
-time64_t ar_entry_get_filetime(ar_archive *ar)
|
||
-{
|
||
- return ar->entry_filetime;
|
||
-}
|
||
-
|
||
-bool ar_entry_uncompress(ar_archive *ar, void *buffer, size_t count)
|
||
-{
|
||
- return ar->uncompress(ar, buffer, count);
|
||
-}
|
||
-
|
||
-size_t ar_get_global_comment(ar_archive *ar, void *buffer, size_t count)
|
||
-{
|
||
- if (!ar->get_comment)
|
||
- return 0;
|
||
- return ar->get_comment(ar, buffer, count);
|
||
-}
|
||
-
|
||
-__attribute__((__format__ (__printf__, 4, 0)))
|
||
-void ar_log(const char *prefix, const char *file, int line, const char *msg, ...)
|
||
-{
|
||
- va_list args;
|
||
- va_start(args, msg);
|
||
- if (prefix)
|
||
- fprintf(stderr, "%s ", prefix);
|
||
- if (strrchr(file, '/'))
|
||
- file = strrchr(file, '/') + 1;
|
||
- if (strrchr(file, '\\'))
|
||
- file = strrchr(file, '\\') + 1;
|
||
- fprintf(stderr, "%s:%d: ", file, line);
|
||
- vfprintf(stderr, msg, args);
|
||
- fprintf(stderr, "\n");
|
||
- va_end(args);
|
||
-}
|
||
diff --git a/cut-n-paste/unarr/lzmasdk/7zTypes.h b/cut-n-paste/unarr/lzmasdk/7zTypes.h
|
||
deleted file mode 100644
|
||
index fe4fde3f..00000000
|
||
--- a/cut-n-paste/unarr/lzmasdk/7zTypes.h
|
||
+++ /dev/null
|
||
@@ -1,525 +0,0 @@
|
||
-/* 7zTypes.h -- Basic types
|
||
-2021-12-25 : Igor Pavlov : Public domain */
|
||
-
|
||
-#ifndef __7Z_TYPES_H
|
||
-#define __7Z_TYPES_H
|
||
-
|
||
-#ifdef _WIN32
|
||
-/* #include <windows.h> */
|
||
-#else
|
||
-#include <errno.h>
|
||
-#endif
|
||
-
|
||
-#include <stddef.h>
|
||
-
|
||
-#ifndef EXTERN_C_BEGIN
|
||
-#ifdef __cplusplus
|
||
-#define EXTERN_C_BEGIN extern "C" {
|
||
-#define EXTERN_C_END }
|
||
-#else
|
||
-#define EXTERN_C_BEGIN
|
||
-#define EXTERN_C_END
|
||
-#endif
|
||
-#endif
|
||
-
|
||
-EXTERN_C_BEGIN
|
||
-
|
||
-#define SZ_OK 0
|
||
-
|
||
-#define SZ_ERROR_DATA 1
|
||
-#define SZ_ERROR_MEM 2
|
||
-#define SZ_ERROR_CRC 3
|
||
-#define SZ_ERROR_UNSUPPORTED 4
|
||
-#define SZ_ERROR_PARAM 5
|
||
-#define SZ_ERROR_INPUT_EOF 6
|
||
-#define SZ_ERROR_OUTPUT_EOF 7
|
||
-#define SZ_ERROR_READ 8
|
||
-#define SZ_ERROR_WRITE 9
|
||
-#define SZ_ERROR_PROGRESS 10
|
||
-#define SZ_ERROR_FAIL 11
|
||
-#define SZ_ERROR_THREAD 12
|
||
-
|
||
-#define SZ_ERROR_ARCHIVE 16
|
||
-#define SZ_ERROR_NO_ARCHIVE 17
|
||
-
|
||
-typedef int SRes;
|
||
-
|
||
-
|
||
-#ifdef _MSC_VER
|
||
- #if _MSC_VER > 1200
|
||
- #define MY_ALIGN(n) __declspec(align(n))
|
||
- #else
|
||
- #define MY_ALIGN(n)
|
||
- #endif
|
||
-#else
|
||
- #define MY_ALIGN(n) __attribute__ ((aligned(n)))
|
||
-#endif
|
||
-
|
||
-
|
||
-#ifdef _WIN32
|
||
-
|
||
-/* typedef DWORD WRes; */
|
||
-typedef unsigned WRes;
|
||
-#define MY_SRes_HRESULT_FROM_WRes(x) HRESULT_FROM_WIN32(x)
|
||
-
|
||
-// #define MY_HRES_ERROR__INTERNAL_ERROR MY_SRes_HRESULT_FROM_WRes(ERROR_INTERNAL_ERROR)
|
||
-
|
||
-#else // _WIN32
|
||
-
|
||
-// #define ENV_HAVE_LSTAT
|
||
-typedef int WRes;
|
||
-
|
||
-// (FACILITY_ERRNO = 0x800) is 7zip's FACILITY constant to represent (errno) errors in HRESULT
|
||
-#define MY__FACILITY_ERRNO 0x800
|
||
-#define MY__FACILITY_WIN32 7
|
||
-#define MY__FACILITY__WRes MY__FACILITY_ERRNO
|
||
-
|
||
-#define MY_HRESULT_FROM_errno_CONST_ERROR(x) ((HRESULT)( \
|
||
- ( (HRESULT)(x) & 0x0000FFFF) \
|
||
- | (MY__FACILITY__WRes << 16) \
|
||
- | (HRESULT)0x80000000 ))
|
||
-
|
||
-#define MY_SRes_HRESULT_FROM_WRes(x) \
|
||
- ((HRESULT)(x) <= 0 ? ((HRESULT)(x)) : MY_HRESULT_FROM_errno_CONST_ERROR(x))
|
||
-
|
||
-// we call macro HRESULT_FROM_WIN32 for system errors (WRes) that are (errno)
|
||
-#define HRESULT_FROM_WIN32(x) MY_SRes_HRESULT_FROM_WRes(x)
|
||
-
|
||
-/*
|
||
-#define ERROR_FILE_NOT_FOUND 2L
|
||
-#define ERROR_ACCESS_DENIED 5L
|
||
-#define ERROR_NO_MORE_FILES 18L
|
||
-#define ERROR_LOCK_VIOLATION 33L
|
||
-#define ERROR_FILE_EXISTS 80L
|
||
-#define ERROR_DISK_FULL 112L
|
||
-#define ERROR_NEGATIVE_SEEK 131L
|
||
-#define ERROR_ALREADY_EXISTS 183L
|
||
-#define ERROR_DIRECTORY 267L
|
||
-#define ERROR_TOO_MANY_POSTS 298L
|
||
-
|
||
-#define ERROR_INTERNAL_ERROR 1359L
|
||
-#define ERROR_INVALID_REPARSE_DATA 4392L
|
||
-#define ERROR_REPARSE_TAG_INVALID 4393L
|
||
-#define ERROR_REPARSE_TAG_MISMATCH 4394L
|
||
-*/
|
||
-
|
||
-// we use errno equivalents for some WIN32 errors:
|
||
-
|
||
-#define ERROR_INVALID_PARAMETER EINVAL
|
||
-#define ERROR_INVALID_FUNCTION EINVAL
|
||
-#define ERROR_ALREADY_EXISTS EEXIST
|
||
-#define ERROR_FILE_EXISTS EEXIST
|
||
-#define ERROR_PATH_NOT_FOUND ENOENT
|
||
-#define ERROR_FILE_NOT_FOUND ENOENT
|
||
-#define ERROR_DISK_FULL ENOSPC
|
||
-// #define ERROR_INVALID_HANDLE EBADF
|
||
-
|
||
-// we use FACILITY_WIN32 for errors that has no errno equivalent
|
||
-// Too many posts were made to a semaphore.
|
||
-#define ERROR_TOO_MANY_POSTS ((HRESULT)0x8007012AL)
|
||
-#define ERROR_INVALID_REPARSE_DATA ((HRESULT)0x80071128L)
|
||
-#define ERROR_REPARSE_TAG_INVALID ((HRESULT)0x80071129L)
|
||
-
|
||
-// if (MY__FACILITY__WRes != FACILITY_WIN32),
|
||
-// we use FACILITY_WIN32 for COM errors:
|
||
-#define E_OUTOFMEMORY ((HRESULT)0x8007000EL)
|
||
-#define E_INVALIDARG ((HRESULT)0x80070057L)
|
||
-#define MY__E_ERROR_NEGATIVE_SEEK ((HRESULT)0x80070083L)
|
||
-
|
||
-/*
|
||
-// we can use FACILITY_ERRNO for some COM errors, that have errno equivalents:
|
||
-#define E_OUTOFMEMORY MY_HRESULT_FROM_errno_CONST_ERROR(ENOMEM)
|
||
-#define E_INVALIDARG MY_HRESULT_FROM_errno_CONST_ERROR(EINVAL)
|
||
-#define MY__E_ERROR_NEGATIVE_SEEK MY_HRESULT_FROM_errno_CONST_ERROR(EINVAL)
|
||
-*/
|
||
-
|
||
-// gcc / clang : (sizeof(long) == sizeof(void*)) in 32/64 bits
|
||
-typedef long INT_PTR;
|
||
-typedef unsigned long UINT_PTR;
|
||
-
|
||
-#define TEXT(quote) quote
|
||
-
|
||
-#define FILE_ATTRIBUTE_READONLY 0x0001
|
||
-#define FILE_ATTRIBUTE_HIDDEN 0x0002
|
||
-#define FILE_ATTRIBUTE_SYSTEM 0x0004
|
||
-#define FILE_ATTRIBUTE_DIRECTORY 0x0010
|
||
-#define FILE_ATTRIBUTE_ARCHIVE 0x0020
|
||
-#define FILE_ATTRIBUTE_DEVICE 0x0040
|
||
-#define FILE_ATTRIBUTE_NORMAL 0x0080
|
||
-#define FILE_ATTRIBUTE_TEMPORARY 0x0100
|
||
-#define FILE_ATTRIBUTE_SPARSE_FILE 0x0200
|
||
-#define FILE_ATTRIBUTE_REPARSE_POINT 0x0400
|
||
-#define FILE_ATTRIBUTE_COMPRESSED 0x0800
|
||
-#define FILE_ATTRIBUTE_OFFLINE 0x1000
|
||
-#define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x2000
|
||
-#define FILE_ATTRIBUTE_ENCRYPTED 0x4000
|
||
-
|
||
-#define FILE_ATTRIBUTE_UNIX_EXTENSION 0x8000 /* trick for Unix */
|
||
-
|
||
-#endif
|
||
-
|
||
-
|
||
-#ifndef RINOK
|
||
-#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
|
||
-#endif
|
||
-
|
||
-#ifndef RINOK_WRes
|
||
-#define RINOK_WRes(x) { WRes __result__ = (x); if (__result__ != 0) return __result__; }
|
||
-#endif
|
||
-
|
||
-typedef unsigned char Byte;
|
||
-typedef short Int16;
|
||
-typedef unsigned short UInt16;
|
||
-
|
||
-#ifdef _LZMA_UINT32_IS_ULONG
|
||
-typedef long Int32;
|
||
-typedef unsigned long UInt32;
|
||
-#else
|
||
-typedef int Int32;
|
||
-typedef unsigned int UInt32;
|
||
-#endif
|
||
-
|
||
-
|
||
-#ifndef _WIN32
|
||
-
|
||
-typedef int INT;
|
||
-typedef Int32 INT32;
|
||
-typedef unsigned int UINT;
|
||
-typedef UInt32 UINT32;
|
||
-typedef INT32 LONG; // LONG, ULONG and DWORD must be 32-bit for _WIN32 compatibility
|
||
-typedef UINT32 ULONG;
|
||
-
|
||
-#undef DWORD
|
||
-typedef UINT32 DWORD;
|
||
-
|
||
-#define VOID void
|
||
-
|
||
-#define HRESULT LONG
|
||
-
|
||
-typedef void *LPVOID;
|
||
-// typedef void VOID;
|
||
-// typedef ULONG_PTR DWORD_PTR, *PDWORD_PTR;
|
||
-// gcc / clang on Unix : sizeof(long==sizeof(void*) in 32 or 64 bits)
|
||
-typedef long INT_PTR;
|
||
-typedef unsigned long UINT_PTR;
|
||
-typedef long LONG_PTR;
|
||
-typedef unsigned long DWORD_PTR;
|
||
-
|
||
-typedef size_t SIZE_T;
|
||
-
|
||
-#endif // _WIN32
|
||
-
|
||
-
|
||
-#define MY_HRES_ERROR__INTERNAL_ERROR ((HRESULT)0x8007054FL)
|
||
-
|
||
-
|
||
-#ifdef _SZ_NO_INT_64
|
||
-
|
||
-/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers.
|
||
- NOTES: Some code will work incorrectly in that case! */
|
||
-
|
||
-typedef long Int64;
|
||
-typedef unsigned long UInt64;
|
||
-
|
||
-#else
|
||
-
|
||
-#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||
-typedef __int64 Int64;
|
||
-typedef unsigned __int64 UInt64;
|
||
-#define UINT64_CONST(n) n
|
||
-#else
|
||
-typedef long long int Int64;
|
||
-typedef unsigned long long int UInt64;
|
||
-#define UINT64_CONST(n) n ## ULL
|
||
-#endif
|
||
-
|
||
-#endif
|
||
-
|
||
-#ifdef _LZMA_NO_SYSTEM_SIZE_T
|
||
-typedef UInt32 SizeT;
|
||
-#else
|
||
-typedef size_t SizeT;
|
||
-#endif
|
||
-
|
||
-typedef int BoolInt;
|
||
-/* typedef BoolInt Bool; */
|
||
-#define True 1
|
||
-#define False 0
|
||
-
|
||
-
|
||
-#ifdef _WIN32
|
||
-#define MY_STD_CALL __stdcall
|
||
-#else
|
||
-#define MY_STD_CALL
|
||
-#endif
|
||
-
|
||
-#ifdef _MSC_VER
|
||
-
|
||
-#if _MSC_VER >= 1300
|
||
-#define MY_NO_INLINE __declspec(noinline)
|
||
-#else
|
||
-#define MY_NO_INLINE
|
||
-#endif
|
||
-
|
||
-#define MY_FORCE_INLINE __forceinline
|
||
-
|
||
-#define MY_CDECL __cdecl
|
||
-#define MY_FAST_CALL __fastcall
|
||
-
|
||
-#else // _MSC_VER
|
||
-
|
||
-#if (defined(__GNUC__) && (__GNUC__ >= 4)) \
|
||
- || (defined(__clang__) && (__clang_major__ >= 4)) \
|
||
- || defined(__INTEL_COMPILER) \
|
||
- || defined(__xlC__)
|
||
-#define MY_NO_INLINE __attribute__((noinline))
|
||
-// #define MY_FORCE_INLINE __attribute__((always_inline)) inline
|
||
-#else
|
||
-#define MY_NO_INLINE
|
||
-#endif
|
||
-
|
||
-#define MY_FORCE_INLINE
|
||
-
|
||
-
|
||
-#define MY_CDECL
|
||
-
|
||
-#if defined(_M_IX86) \
|
||
- || defined(__i386__)
|
||
-// #define MY_FAST_CALL __attribute__((fastcall))
|
||
-// #define MY_FAST_CALL __attribute__((cdecl))
|
||
-#define MY_FAST_CALL
|
||
-#elif defined(MY_CPU_AMD64)
|
||
-// #define MY_FAST_CALL __attribute__((ms_abi))
|
||
-#define MY_FAST_CALL
|
||
-#else
|
||
-#define MY_FAST_CALL
|
||
-#endif
|
||
-
|
||
-#endif // _MSC_VER
|
||
-
|
||
-
|
||
-/* The following interfaces use first parameter as pointer to structure */
|
||
-
|
||
-typedef struct IByteIn IByteIn;
|
||
-struct IByteIn
|
||
-{
|
||
- Byte (*Read)(const IByteIn *p); /* reads one byte, returns 0 in case of EOF or error */
|
||
-};
|
||
-#define IByteIn_Read(p) (p)->Read(p)
|
||
-
|
||
-
|
||
-typedef struct IByteOut IByteOut;
|
||
-struct IByteOut
|
||
-{
|
||
- void (*Write)(const IByteOut *p, Byte b);
|
||
-};
|
||
-#define IByteOut_Write(p, b) (p)->Write(p, b)
|
||
-
|
||
-
|
||
-typedef struct ISeqInStream ISeqInStream;
|
||
-struct ISeqInStream
|
||
-{
|
||
- SRes (*Read)(const ISeqInStream *p, void *buf, size_t *size);
|
||
- /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
|
||
- (output(*size) < input(*size)) is allowed */
|
||
-};
|
||
-#define ISeqInStream_Read(p, buf, size) (p)->Read(p, buf, size)
|
||
-
|
||
-/* it can return SZ_ERROR_INPUT_EOF */
|
||
-SRes SeqInStream_Read(const ISeqInStream *stream, void *buf, size_t size);
|
||
-SRes SeqInStream_Read2(const ISeqInStream *stream, void *buf, size_t size, SRes errorType);
|
||
-SRes SeqInStream_ReadByte(const ISeqInStream *stream, Byte *buf);
|
||
-
|
||
-
|
||
-typedef struct ISeqOutStream ISeqOutStream;
|
||
-struct ISeqOutStream
|
||
-{
|
||
- size_t (*Write)(const ISeqOutStream *p, const void *buf, size_t size);
|
||
- /* Returns: result - the number of actually written bytes.
|
||
- (result < size) means error */
|
||
-};
|
||
-#define ISeqOutStream_Write(p, buf, size) (p)->Write(p, buf, size)
|
||
-
|
||
-typedef enum
|
||
-{
|
||
- SZ_SEEK_SET = 0,
|
||
- SZ_SEEK_CUR = 1,
|
||
- SZ_SEEK_END = 2
|
||
-} ESzSeek;
|
||
-
|
||
-
|
||
-typedef struct ISeekInStream ISeekInStream;
|
||
-struct ISeekInStream
|
||
-{
|
||
- SRes (*Read)(const ISeekInStream *p, void *buf, size_t *size); /* same as ISeqInStream::Read */
|
||
- SRes (*Seek)(const ISeekInStream *p, Int64 *pos, ESzSeek origin);
|
||
-};
|
||
-#define ISeekInStream_Read(p, buf, size) (p)->Read(p, buf, size)
|
||
-#define ISeekInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin)
|
||
-
|
||
-
|
||
-typedef struct ILookInStream ILookInStream;
|
||
-struct ILookInStream
|
||
-{
|
||
- SRes (*Look)(const ILookInStream *p, const void **buf, size_t *size);
|
||
- /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
|
||
- (output(*size) > input(*size)) is not allowed
|
||
- (output(*size) < input(*size)) is allowed */
|
||
- SRes (*Skip)(const ILookInStream *p, size_t offset);
|
||
- /* offset must be <= output(*size) of Look */
|
||
-
|
||
- SRes (*Read)(const ILookInStream *p, void *buf, size_t *size);
|
||
- /* reads directly (without buffer). It's same as ISeqInStream::Read */
|
||
- SRes (*Seek)(const ILookInStream *p, Int64 *pos, ESzSeek origin);
|
||
-};
|
||
-
|
||
-#define ILookInStream_Look(p, buf, size) (p)->Look(p, buf, size)
|
||
-#define ILookInStream_Skip(p, offset) (p)->Skip(p, offset)
|
||
-#define ILookInStream_Read(p, buf, size) (p)->Read(p, buf, size)
|
||
-#define ILookInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin)
|
||
-
|
||
-
|
||
-SRes LookInStream_LookRead(const ILookInStream *stream, void *buf, size_t *size);
|
||
-SRes LookInStream_SeekTo(const ILookInStream *stream, UInt64 offset);
|
||
-
|
||
-/* reads via ILookInStream::Read */
|
||
-SRes LookInStream_Read2(const ILookInStream *stream, void *buf, size_t size, SRes errorType);
|
||
-SRes LookInStream_Read(const ILookInStream *stream, void *buf, size_t size);
|
||
-
|
||
-
|
||
-
|
||
-typedef struct
|
||
-{
|
||
- ILookInStream vt;
|
||
- const ISeekInStream *realStream;
|
||
-
|
||
- size_t pos;
|
||
- size_t size; /* it's data size */
|
||
-
|
||
- /* the following variables must be set outside */
|
||
- Byte *buf;
|
||
- size_t bufSize;
|
||
-} CLookToRead2;
|
||
-
|
||
-void LookToRead2_CreateVTable(CLookToRead2 *p, int lookahead);
|
||
-
|
||
-#define LookToRead2_Init(p) { (p)->pos = (p)->size = 0; }
|
||
-
|
||
-
|
||
-typedef struct
|
||
-{
|
||
- ISeqInStream vt;
|
||
- const ILookInStream *realStream;
|
||
-} CSecToLook;
|
||
-
|
||
-void SecToLook_CreateVTable(CSecToLook *p);
|
||
-
|
||
-
|
||
-
|
||
-typedef struct
|
||
-{
|
||
- ISeqInStream vt;
|
||
- const ILookInStream *realStream;
|
||
-} CSecToRead;
|
||
-
|
||
-void SecToRead_CreateVTable(CSecToRead *p);
|
||
-
|
||
-
|
||
-typedef struct ICompressProgress ICompressProgress;
|
||
-
|
||
-struct ICompressProgress
|
||
-{
|
||
- SRes (*Progress)(const ICompressProgress *p, UInt64 inSize, UInt64 outSize);
|
||
- /* Returns: result. (result != SZ_OK) means break.
|
||
- Value (UInt64)(Int64)-1 for size means unknown value. */
|
||
-};
|
||
-#define ICompressProgress_Progress(p, inSize, outSize) (p)->Progress(p, inSize, outSize)
|
||
-
|
||
-
|
||
-
|
||
-typedef struct ISzAlloc ISzAlloc;
|
||
-typedef const ISzAlloc * ISzAllocPtr;
|
||
-
|
||
-struct ISzAlloc
|
||
-{
|
||
- void *(*Alloc)(ISzAllocPtr p, size_t size);
|
||
- void (*Free)(ISzAllocPtr p, void *address); /* address can be 0 */
|
||
-};
|
||
-
|
||
-#define ISzAlloc_Alloc(p, size) (p)->Alloc(p, size)
|
||
-#define ISzAlloc_Free(p, a) (p)->Free(p, a)
|
||
-
|
||
-/* deprecated */
|
||
-#define IAlloc_Alloc(p, size) ISzAlloc_Alloc(p, size)
|
||
-#define IAlloc_Free(p, a) ISzAlloc_Free(p, a)
|
||
-
|
||
-
|
||
-
|
||
-
|
||
-
|
||
-#ifndef MY_offsetof
|
||
- #ifdef offsetof
|
||
- #define MY_offsetof(type, m) offsetof(type, m)
|
||
- /*
|
||
- #define MY_offsetof(type, m) FIELD_OFFSET(type, m)
|
||
- */
|
||
- #else
|
||
- #define MY_offsetof(type, m) ((size_t)&(((type *)0)->m))
|
||
- #endif
|
||
-#endif
|
||
-
|
||
-
|
||
-
|
||
-#ifndef MY_container_of
|
||
-
|
||
-/*
|
||
-#define MY_container_of(ptr, type, m) container_of(ptr, type, m)
|
||
-#define MY_container_of(ptr, type, m) CONTAINING_RECORD(ptr, type, m)
|
||
-#define MY_container_of(ptr, type, m) ((type *)((char *)(ptr) - offsetof(type, m)))
|
||
-#define MY_container_of(ptr, type, m) (&((type *)0)->m == (ptr), ((type *)(((char *)(ptr)) - MY_offsetof(type, m))))
|
||
-*/
|
||
-
|
||
-/*
|
||
- GCC shows warning: "perhaps the 'offsetof' macro was used incorrectly"
|
||
- GCC 3.4.4 : classes with constructor
|
||
- GCC 4.8.1 : classes with non-public variable members"
|
||
-*/
|
||
-
|
||
-#define MY_container_of(ptr, type, m) ((type *)(void *)((char *)(void *)(1 ? (ptr) : &((type *)0)->m) - MY_offsetof(type, m)))
|
||
-
|
||
-#endif
|
||
-
|
||
-#define CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) ((type *)(void *)(ptr))
|
||
-
|
||
-/*
|
||
-#define CONTAINER_FROM_VTBL(ptr, type, m) CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m)
|
||
-*/
|
||
-#define CONTAINER_FROM_VTBL(ptr, type, m) MY_container_of(ptr, type, m)
|
||
-
|
||
-#define CONTAINER_FROM_VTBL_CLS(ptr, type, m) CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m)
|
||
-/*
|
||
-#define CONTAINER_FROM_VTBL_CLS(ptr, type, m) CONTAINER_FROM_VTBL(ptr, type, m)
|
||
-*/
|
||
-
|
||
-
|
||
-#define MY_memset_0_ARRAY(a) memset((a), 0, sizeof(a))
|
||
-
|
||
-#ifdef _WIN32
|
||
-
|
||
-#define CHAR_PATH_SEPARATOR '\\'
|
||
-#define WCHAR_PATH_SEPARATOR L'\\'
|
||
-#define STRING_PATH_SEPARATOR "\\"
|
||
-#define WSTRING_PATH_SEPARATOR L"\\"
|
||
-
|
||
-#else
|
||
-
|
||
-#define CHAR_PATH_SEPARATOR '/'
|
||
-#define WCHAR_PATH_SEPARATOR L'/'
|
||
-#define STRING_PATH_SEPARATOR "/"
|
||
-#define WSTRING_PATH_SEPARATOR L"/"
|
||
-
|
||
-#endif
|
||
-
|
||
-EXTERN_C_END
|
||
-
|
||
-#endif
|
||
diff --git a/cut-n-paste/unarr/lzmasdk/CpuArch.c b/cut-n-paste/unarr/lzmasdk/CpuArch.c
|
||
deleted file mode 100644
|
||
index 9bcb8fd5..00000000
|
||
--- a/cut-n-paste/unarr/lzmasdk/CpuArch.c
|
||
+++ /dev/null
|
||
@@ -1,478 +0,0 @@
|
||
-/* CpuArch.c -- CPU specific code
|
||
-2021-07-13 : Igor Pavlov : Public domain */
|
||
-
|
||
-#include "Precomp.h"
|
||
-
|
||
-#include "CpuArch.h"
|
||
-
|
||
-#ifdef MY_CPU_X86_OR_AMD64
|
||
-
|
||
-#if (defined(_MSC_VER) && !defined(MY_CPU_AMD64)) || defined(__GNUC__)
|
||
-#define USE_ASM
|
||
-#endif
|
||
-
|
||
-#if !defined(USE_ASM) && _MSC_VER >= 1500
|
||
-#include <intrin.h>
|
||
-#endif
|
||
-
|
||
-#if defined(USE_ASM) && !defined(MY_CPU_AMD64)
|
||
-static UInt32 CheckFlag(UInt32 flag)
|
||
-{
|
||
- #ifdef _MSC_VER
|
||
- __asm pushfd;
|
||
- __asm pop EAX;
|
||
- __asm mov EDX, EAX;
|
||
- __asm xor EAX, flag;
|
||
- __asm push EAX;
|
||
- __asm popfd;
|
||
- __asm pushfd;
|
||
- __asm pop EAX;
|
||
- __asm xor EAX, EDX;
|
||
- __asm push EDX;
|
||
- __asm popfd;
|
||
- __asm and flag, EAX;
|
||
- #else
|
||
- __asm__ __volatile__ (
|
||
- "pushf\n\t"
|
||
- "pop %%EAX\n\t"
|
||
- "movl %%EAX,%%EDX\n\t"
|
||
- "xorl %0,%%EAX\n\t"
|
||
- "push %%EAX\n\t"
|
||
- "popf\n\t"
|
||
- "pushf\n\t"
|
||
- "pop %%EAX\n\t"
|
||
- "xorl %%EDX,%%EAX\n\t"
|
||
- "push %%EDX\n\t"
|
||
- "popf\n\t"
|
||
- "andl %%EAX, %0\n\t":
|
||
- "=c" (flag) : "c" (flag) :
|
||
- "%eax", "%edx");
|
||
- #endif
|
||
- return flag;
|
||
-}
|
||
-#define CHECK_CPUID_IS_SUPPORTED if (CheckFlag(1 << 18) == 0 || CheckFlag(1 << 21) == 0) return False;
|
||
-#else
|
||
-#define CHECK_CPUID_IS_SUPPORTED
|
||
-#endif
|
||
-
|
||
-#ifndef USE_ASM
|
||
- #ifdef _MSC_VER
|
||
- #if _MSC_VER >= 1600
|
||
- #define MY__cpuidex __cpuidex
|
||
- #else
|
||
-
|
||
-/*
|
||
- __cpuid (function == 4) requires subfunction number in ECX.
|
||
- MSDN: The __cpuid intrinsic clears the ECX register before calling the cpuid instruction.
|
||
- __cpuid() in new MSVC clears ECX.
|
||
- __cpuid() in old MSVC (14.00) doesn't clear ECX
|
||
- We still can use __cpuid for low (function) values that don't require ECX,
|
||
- but __cpuid() in old MSVC will be incorrect for some function values: (function == 4).
|
||
- So here we use the hack for old MSVC to send (subFunction) in ECX register to cpuid instruction,
|
||
- where ECX value is first parameter for FAST_CALL / NO_INLINE function,
|
||
- So the caller of MY__cpuidex_HACK() sets ECX as subFunction, and
|
||
- old MSVC for __cpuid() doesn't change ECX and cpuid instruction gets (subFunction) value.
|
||
-
|
||
- DON'T remove MY_NO_INLINE and MY_FAST_CALL for MY__cpuidex_HACK() !!!
|
||
-*/
|
||
-
|
||
-static
|
||
-MY_NO_INLINE
|
||
-void MY_FAST_CALL MY__cpuidex_HACK(UInt32 subFunction, int *CPUInfo, UInt32 function)
|
||
-{
|
||
- UNUSED_VAR(subFunction);
|
||
- __cpuid(CPUInfo, function);
|
||
-}
|
||
-
|
||
- #define MY__cpuidex(info, func, func2) MY__cpuidex_HACK(func2, info, func)
|
||
- #pragma message("======== MY__cpuidex_HACK WAS USED ========")
|
||
- #endif
|
||
- #else
|
||
- #define MY__cpuidex(info, func, func2) __cpuid(info, func)
|
||
- #pragma message("======== (INCORRECT ?) cpuid WAS USED ========")
|
||
- #endif
|
||
-#endif
|
||
-
|
||
-
|
||
-
|
||
-
|
||
-void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
|
||
-{
|
||
- #ifdef USE_ASM
|
||
-
|
||
- #ifdef _MSC_VER
|
||
-
|
||
- UInt32 a2, b2, c2, d2;
|
||
- __asm xor EBX, EBX;
|
||
- __asm xor ECX, ECX;
|
||
- __asm xor EDX, EDX;
|
||
- __asm mov EAX, function;
|
||
- __asm cpuid;
|
||
- __asm mov a2, EAX;
|
||
- __asm mov b2, EBX;
|
||
- __asm mov c2, ECX;
|
||
- __asm mov d2, EDX;
|
||
-
|
||
- *a = a2;
|
||
- *b = b2;
|
||
- *c = c2;
|
||
- *d = d2;
|
||
-
|
||
- #else
|
||
-
|
||
- __asm__ __volatile__ (
|
||
- #if defined(MY_CPU_AMD64) && defined(__PIC__)
|
||
- "mov %%rbx, %%rdi;"
|
||
- "cpuid;"
|
||
- "xchg %%rbx, %%rdi;"
|
||
- : "=a" (*a) ,
|
||
- "=D" (*b) ,
|
||
- #elif defined(MY_CPU_X86) && defined(__PIC__)
|
||
- "mov %%ebx, %%edi;"
|
||
- "cpuid;"
|
||
- "xchgl %%ebx, %%edi;"
|
||
- : "=a" (*a) ,
|
||
- "=D" (*b) ,
|
||
- #else
|
||
- "cpuid"
|
||
- : "=a" (*a) ,
|
||
- "=b" (*b) ,
|
||
- #endif
|
||
- "=c" (*c) ,
|
||
- "=d" (*d)
|
||
- : "0" (function), "c"(0) ) ;
|
||
-
|
||
- #endif
|
||
-
|
||
- #else
|
||
-
|
||
- int CPUInfo[4];
|
||
-
|
||
- MY__cpuidex(CPUInfo, (int)function, 0);
|
||
-
|
||
- *a = (UInt32)CPUInfo[0];
|
||
- *b = (UInt32)CPUInfo[1];
|
||
- *c = (UInt32)CPUInfo[2];
|
||
- *d = (UInt32)CPUInfo[3];
|
||
-
|
||
- #endif
|
||
-}
|
||
-
|
||
-BoolInt x86cpuid_CheckAndRead(Cx86cpuid *p)
|
||
-{
|
||
- CHECK_CPUID_IS_SUPPORTED
|
||
- MyCPUID(0, &p->maxFunc, &p->vendor[0], &p->vendor[2], &p->vendor[1]);
|
||
- MyCPUID(1, &p->ver, &p->b, &p->c, &p->d);
|
||
- return True;
|
||
-}
|
||
-
|
||
-static const UInt32 kVendors[][3] =
|
||
-{
|
||
- { 0x756E6547, 0x49656E69, 0x6C65746E},
|
||
- { 0x68747541, 0x69746E65, 0x444D4163},
|
||
- { 0x746E6543, 0x48727561, 0x736C7561}
|
||
-};
|
||
-
|
||
-int x86cpuid_GetFirm(const Cx86cpuid *p)
|
||
-{
|
||
- unsigned i;
|
||
- for (i = 0; i < sizeof(kVendors) / sizeof(kVendors[i]); i++)
|
||
- {
|
||
- const UInt32 *v = kVendors[i];
|
||
- if (v[0] == p->vendor[0] &&
|
||
- v[1] == p->vendor[1] &&
|
||
- v[2] == p->vendor[2])
|
||
- return (int)i;
|
||
- }
|
||
- return -1;
|
||
-}
|
||
-
|
||
-BoolInt CPU_Is_InOrder(void)
|
||
-{
|
||
- Cx86cpuid p;
|
||
- int firm;
|
||
- UInt32 family, model;
|
||
- if (!x86cpuid_CheckAndRead(&p))
|
||
- return True;
|
||
-
|
||
- family = x86cpuid_GetFamily(p.ver);
|
||
- model = x86cpuid_GetModel(p.ver);
|
||
-
|
||
- firm = x86cpuid_GetFirm(&p);
|
||
-
|
||
- switch (firm)
|
||
- {
|
||
- case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && (
|
||
- /* In-Order Atom CPU */
|
||
- model == 0x1C /* 45 nm, N4xx, D4xx, N5xx, D5xx, 230, 330 */
|
||
- || model == 0x26 /* 45 nm, Z6xx */
|
||
- || model == 0x27 /* 32 nm, Z2460 */
|
||
- || model == 0x35 /* 32 nm, Z2760 */
|
||
- || model == 0x36 /* 32 nm, N2xxx, D2xxx */
|
||
- )));
|
||
- case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || model == 0xA)));
|
||
- case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF));
|
||
- }
|
||
- return True;
|
||
-}
|
||
-
|
||
-#if !defined(MY_CPU_AMD64) && defined(_WIN32)
|
||
-#include <Windows.h>
|
||
-static BoolInt CPU_Sys_Is_SSE_Supported(void)
|
||
-{
|
||
- OSVERSIONINFO vi;
|
||
- vi.dwOSVersionInfoSize = sizeof(vi);
|
||
- if (!GetVersionEx(&vi))
|
||
- return False;
|
||
- return (vi.dwMajorVersion >= 5);
|
||
-}
|
||
-#define CHECK_SYS_SSE_SUPPORT if (!CPU_Sys_Is_SSE_Supported()) return False;
|
||
-#else
|
||
-#define CHECK_SYS_SSE_SUPPORT
|
||
-#endif
|
||
-
|
||
-
|
||
-static UInt32 X86_CPUID_ECX_Get_Flags(void)
|
||
-{
|
||
- Cx86cpuid p;
|
||
- CHECK_SYS_SSE_SUPPORT
|
||
- if (!x86cpuid_CheckAndRead(&p))
|
||
- return 0;
|
||
- return p.c;
|
||
-}
|
||
-
|
||
-BoolInt CPU_IsSupported_AES(void)
|
||
-{
|
||
- return (X86_CPUID_ECX_Get_Flags() >> 25) & 1;
|
||
-}
|
||
-
|
||
-BoolInt CPU_IsSupported_SSSE3(void)
|
||
-{
|
||
- return (X86_CPUID_ECX_Get_Flags() >> 9) & 1;
|
||
-}
|
||
-
|
||
-BoolInt CPU_IsSupported_SSE41(void)
|
||
-{
|
||
- return (X86_CPUID_ECX_Get_Flags() >> 19) & 1;
|
||
-}
|
||
-
|
||
-BoolInt CPU_IsSupported_SHA(void)
|
||
-{
|
||
- Cx86cpuid p;
|
||
- CHECK_SYS_SSE_SUPPORT
|
||
- if (!x86cpuid_CheckAndRead(&p))
|
||
- return False;
|
||
-
|
||
- if (p.maxFunc < 7)
|
||
- return False;
|
||
- {
|
||
- UInt32 d[4] = { 0 };
|
||
- MyCPUID(7, &d[0], &d[1], &d[2], &d[3]);
|
||
- return (d[1] >> 29) & 1;
|
||
- }
|
||
-}
|
||
-
|
||
-// #include <stdio.h>
|
||
-
|
||
-#ifdef _WIN32
|
||
-#include <Windows.h>
|
||
-#endif
|
||
-
|
||
-BoolInt CPU_IsSupported_AVX2(void)
|
||
-{
|
||
- Cx86cpuid p;
|
||
- CHECK_SYS_SSE_SUPPORT
|
||
-
|
||
- #ifdef _WIN32
|
||
- #define MY__PF_XSAVE_ENABLED 17
|
||
- if (!IsProcessorFeaturePresent(MY__PF_XSAVE_ENABLED))
|
||
- return False;
|
||
- #endif
|
||
-
|
||
- if (!x86cpuid_CheckAndRead(&p))
|
||
- return False;
|
||
- if (p.maxFunc < 7)
|
||
- return False;
|
||
- {
|
||
- UInt32 d[4] = { 0 };
|
||
- MyCPUID(7, &d[0], &d[1], &d[2], &d[3]);
|
||
- // printf("\ncpuid(7): ebx=%8x ecx=%8x\n", d[1], d[2]);
|
||
- return 1
|
||
- & (d[1] >> 5); // avx2
|
||
- }
|
||
-}
|
||
-
|
||
-BoolInt CPU_IsSupported_VAES_AVX2(void)
|
||
-{
|
||
- Cx86cpuid p;
|
||
- CHECK_SYS_SSE_SUPPORT
|
||
-
|
||
- #ifdef _WIN32
|
||
- #define MY__PF_XSAVE_ENABLED 17
|
||
- if (!IsProcessorFeaturePresent(MY__PF_XSAVE_ENABLED))
|
||
- return False;
|
||
- #endif
|
||
-
|
||
- if (!x86cpuid_CheckAndRead(&p))
|
||
- return False;
|
||
- if (p.maxFunc < 7)
|
||
- return False;
|
||
- {
|
||
- UInt32 d[4] = { 0 };
|
||
- MyCPUID(7, &d[0], &d[1], &d[2], &d[3]);
|
||
- // printf("\ncpuid(7): ebx=%8x ecx=%8x\n", d[1], d[2]);
|
||
- return 1
|
||
- & (d[1] >> 5) // avx2
|
||
- // & (d[1] >> 31) // avx512vl
|
||
- & (d[2] >> 9); // vaes // VEX-256/EVEX
|
||
- }
|
||
-}
|
||
-
|
||
-BoolInt CPU_IsSupported_PageGB(void)
|
||
-{
|
||
- Cx86cpuid cpuid;
|
||
- if (!x86cpuid_CheckAndRead(&cpuid))
|
||
- return False;
|
||
- {
|
||
- UInt32 d[4] = { 0 };
|
||
- MyCPUID(0x80000000, &d[0], &d[1], &d[2], &d[3]);
|
||
- if (d[0] < 0x80000001)
|
||
- return False;
|
||
- }
|
||
- {
|
||
- UInt32 d[4] = { 0 };
|
||
- MyCPUID(0x80000001, &d[0], &d[1], &d[2], &d[3]);
|
||
- return (d[3] >> 26) & 1;
|
||
- }
|
||
-}
|
||
-
|
||
-
|
||
-#elif defined(MY_CPU_ARM_OR_ARM64)
|
||
-
|
||
-#ifdef _WIN32
|
||
-
|
||
-#include <Windows.h>
|
||
-
|
||
-BoolInt CPU_IsSupported_CRC32(void) { return IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE) ? 1 : 0; }
|
||
-BoolInt CPU_IsSupported_CRYPTO(void) { return IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) ? 1 : 0; }
|
||
-BoolInt CPU_IsSupported_NEON(void) { return IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE) ? 1 : 0; }
|
||
-
|
||
-#else
|
||
-
|
||
-#if defined(__APPLE__)
|
||
-
|
||
-/*
|
||
-#include <stdio.h>
|
||
-#include <string.h>
|
||
-static void Print_sysctlbyname(const char *name)
|
||
-{
|
||
- size_t bufSize = 256;
|
||
- char buf[256];
|
||
- int res = sysctlbyname(name, &buf, &bufSize, NULL, 0);
|
||
- {
|
||
- int i;
|
||
- printf("\nres = %d : %s : '%s' : bufSize = %d, numeric", res, name, buf, (unsigned)bufSize);
|
||
- for (i = 0; i < 20; i++)
|
||
- printf(" %2x", (unsigned)(Byte)buf[i]);
|
||
-
|
||
- }
|
||
-}
|
||
-*/
|
||
-
|
||
-static BoolInt My_sysctlbyname_Get_BoolInt(const char *name)
|
||
-{
|
||
- UInt32 val = 0;
|
||
- if (My_sysctlbyname_Get_UInt32(name, &val) == 0 && val == 1)
|
||
- return 1;
|
||
- return 0;
|
||
-}
|
||
-
|
||
- /*
|
||
- Print_sysctlbyname("hw.pagesize");
|
||
- Print_sysctlbyname("machdep.cpu.brand_string");
|
||
- */
|
||
-
|
||
-BoolInt CPU_IsSupported_CRC32(void)
|
||
-{
|
||
- return My_sysctlbyname_Get_BoolInt("hw.optional.armv8_crc32");
|
||
-}
|
||
-
|
||
-BoolInt CPU_IsSupported_NEON(void)
|
||
-{
|
||
- return My_sysctlbyname_Get_BoolInt("hw.optional.neon");
|
||
-}
|
||
-
|
||
-#ifdef MY_CPU_ARM64
|
||
-#define APPLE_CRYPTO_SUPPORT_VAL 1
|
||
-#else
|
||
-#define APPLE_CRYPTO_SUPPORT_VAL 0
|
||
-#endif
|
||
-
|
||
-BoolInt CPU_IsSupported_SHA1(void) { return APPLE_CRYPTO_SUPPORT_VAL; }
|
||
-BoolInt CPU_IsSupported_SHA2(void) { return APPLE_CRYPTO_SUPPORT_VAL; }
|
||
-BoolInt CPU_IsSupported_AES (void) { return APPLE_CRYPTO_SUPPORT_VAL; }
|
||
-
|
||
-
|
||
-#else // __APPLE__
|
||
-
|
||
-#include <sys/auxv.h>
|
||
-
|
||
-#define USE_HWCAP
|
||
-
|
||
-#ifdef USE_HWCAP
|
||
-
|
||
-#include <asm/hwcap.h>
|
||
-
|
||
- #define MY_HWCAP_CHECK_FUNC_2(name1, name2) \
|
||
- BoolInt CPU_IsSupported_ ## name1() { return (getauxval(AT_HWCAP) & (HWCAP_ ## name2)) ? 1 : 0; }
|
||
-
|
||
-#ifdef MY_CPU_ARM64
|
||
- #define MY_HWCAP_CHECK_FUNC(name) \
|
||
- MY_HWCAP_CHECK_FUNC_2(name, name)
|
||
- MY_HWCAP_CHECK_FUNC_2(NEON, ASIMD)
|
||
-// MY_HWCAP_CHECK_FUNC (ASIMD)
|
||
-#elif defined(MY_CPU_ARM)
|
||
- #define MY_HWCAP_CHECK_FUNC(name) \
|
||
- BoolInt CPU_IsSupported_ ## name() { return (getauxval(AT_HWCAP2) & (HWCAP2_ ## name)) ? 1 : 0; }
|
||
- MY_HWCAP_CHECK_FUNC_2(NEON, NEON)
|
||
-#endif
|
||
-
|
||
-#else // USE_HWCAP
|
||
-
|
||
- #define MY_HWCAP_CHECK_FUNC(name) \
|
||
- BoolInt CPU_IsSupported_ ## name() { return 0; }
|
||
- MY_HWCAP_CHECK_FUNC(NEON)
|
||
-
|
||
-#endif // USE_HWCAP
|
||
-
|
||
-MY_HWCAP_CHECK_FUNC (CRC32)
|
||
-MY_HWCAP_CHECK_FUNC (SHA1)
|
||
-MY_HWCAP_CHECK_FUNC (SHA2)
|
||
-MY_HWCAP_CHECK_FUNC (AES)
|
||
-
|
||
-#endif // __APPLE__
|
||
-#endif // _WIN32
|
||
-
|
||
-#endif // MY_CPU_ARM_OR_ARM64
|
||
-
|
||
-
|
||
-
|
||
-#ifdef __APPLE__
|
||
-
|
||
-#include <sys/sysctl.h>
|
||
-
|
||
-int My_sysctlbyname_Get(const char *name, void *buf, size_t *bufSize)
|
||
-{
|
||
- return sysctlbyname(name, buf, bufSize, NULL, 0);
|
||
-}
|
||
-
|
||
-int My_sysctlbyname_Get_UInt32(const char *name, UInt32 *val)
|
||
-{
|
||
- size_t bufSize = sizeof(*val);
|
||
- int res = My_sysctlbyname_Get(name, val, &bufSize);
|
||
- if (res == 0 && bufSize != sizeof(*val))
|
||
- return EFAULT;
|
||
- return res;
|
||
-}
|
||
-
|
||
-#endif
|
||
diff --git a/cut-n-paste/unarr/lzmasdk/CpuArch.h b/cut-n-paste/unarr/lzmasdk/CpuArch.h
|
||
deleted file mode 100644
|
||
index 529d3a50..00000000
|
||
--- a/cut-n-paste/unarr/lzmasdk/CpuArch.h
|
||
+++ /dev/null
|
||
@@ -1,442 +0,0 @@
|
||
-/* CpuArch.h -- CPU specific code
|
||
-2021-07-13 : Igor Pavlov : Public domain */
|
||
-
|
||
-#ifndef __CPU_ARCH_H
|
||
-#define __CPU_ARCH_H
|
||
-
|
||
-#include "7zTypes.h"
|
||
-
|
||
-EXTERN_C_BEGIN
|
||
-
|
||
-/*
|
||
-MY_CPU_LE means that CPU is LITTLE ENDIAN.
|
||
-MY_CPU_BE means that CPU is BIG ENDIAN.
|
||
-If MY_CPU_LE and MY_CPU_BE are not defined, we don't know about ENDIANNESS of platform.
|
||
-
|
||
-MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses.
|
||
-
|
||
-MY_CPU_64BIT means that processor can work with 64-bit registers.
|
||
- MY_CPU_64BIT can be used to select fast code branch
|
||
- MY_CPU_64BIT doesn't mean that (sizeof(void *) == 8)
|
||
-*/
|
||
-
|
||
-#if defined(_M_X64) \
|
||
- || defined(_M_AMD64) \
|
||
- || defined(__x86_64__) \
|
||
- || defined(__AMD64__) \
|
||
- || defined(__amd64__)
|
||
- #define MY_CPU_AMD64
|
||
- #ifdef __ILP32__
|
||
- #define MY_CPU_NAME "x32"
|
||
- #define MY_CPU_SIZEOF_POINTER 4
|
||
- #else
|
||
- #define MY_CPU_NAME "x64"
|
||
- #define MY_CPU_SIZEOF_POINTER 8
|
||
- #endif
|
||
- #define MY_CPU_64BIT
|
||
-#endif
|
||
-
|
||
-
|
||
-#if defined(_M_IX86) \
|
||
- || defined(__i386__)
|
||
- #define MY_CPU_X86
|
||
- #define MY_CPU_NAME "x86"
|
||
- /* #define MY_CPU_32BIT */
|
||
- #define MY_CPU_SIZEOF_POINTER 4
|
||
-#endif
|
||
-
|
||
-
|
||
-#if defined(_M_ARM64) \
|
||
- || defined(__AARCH64EL__) \
|
||
- || defined(__AARCH64EB__) \
|
||
- || defined(__aarch64__)
|
||
- #define MY_CPU_ARM64
|
||
- #define MY_CPU_NAME "arm64"
|
||
- #define MY_CPU_64BIT
|
||
-#endif
|
||
-
|
||
-
|
||
-#if defined(_M_ARM) \
|
||
- || defined(_M_ARM_NT) \
|
||
- || defined(_M_ARMT) \
|
||
- || defined(__arm__) \
|
||
- || defined(__thumb__) \
|
||
- || defined(__ARMEL__) \
|
||
- || defined(__ARMEB__) \
|
||
- || defined(__THUMBEL__) \
|
||
- || defined(__THUMBEB__)
|
||
- #define MY_CPU_ARM
|
||
-
|
||
- #if defined(__thumb__) || defined(__THUMBEL__) || defined(_M_ARMT)
|
||
- #define MY_CPU_NAME "armt"
|
||
- #else
|
||
- #define MY_CPU_NAME "arm"
|
||
- #endif
|
||
- /* #define MY_CPU_32BIT */
|
||
- #define MY_CPU_SIZEOF_POINTER 4
|
||
-#endif
|
||
-
|
||
-
|
||
-#if defined(_M_IA64) \
|
||
- || defined(__ia64__)
|
||
- #define MY_CPU_IA64
|
||
- #define MY_CPU_NAME "ia64"
|
||
- #define MY_CPU_64BIT
|
||
-#endif
|
||
-
|
||
-
|
||
-#if defined(__mips64) \
|
||
- || defined(__mips64__) \
|
||
- || (defined(__mips) && (__mips == 64 || __mips == 4 || __mips == 3))
|
||
- #define MY_CPU_NAME "mips64"
|
||
- #define MY_CPU_64BIT
|
||
-#elif defined(__mips__)
|
||
- #define MY_CPU_NAME "mips"
|
||
- /* #define MY_CPU_32BIT */
|
||
-#endif
|
||
-
|
||
-
|
||
-#if defined(__ppc64__) \
|
||
- || defined(__powerpc64__) \
|
||
- || defined(__ppc__) \
|
||
- || defined(__powerpc__) \
|
||
- || defined(__PPC__) \
|
||
- || defined(_POWER)
|
||
-
|
||
-#if defined(__ppc64__) \
|
||
- || defined(__powerpc64__) \
|
||
- || defined(_LP64) \
|
||
- || defined(__64BIT__)
|
||
- #ifdef __ILP32__
|
||
- #define MY_CPU_NAME "ppc64-32"
|
||
- #define MY_CPU_SIZEOF_POINTER 4
|
||
- #else
|
||
- #define MY_CPU_NAME "ppc64"
|
||
- #define MY_CPU_SIZEOF_POINTER 8
|
||
- #endif
|
||
- #define MY_CPU_64BIT
|
||
-#else
|
||
- #define MY_CPU_NAME "ppc"
|
||
- #define MY_CPU_SIZEOF_POINTER 4
|
||
- /* #define MY_CPU_32BIT */
|
||
-#endif
|
||
-#endif
|
||
-
|
||
-
|
||
-#if defined(__sparc64__)
|
||
- #define MY_CPU_NAME "sparc64"
|
||
- #define MY_CPU_64BIT
|
||
-#elif defined(__sparc__)
|
||
- #define MY_CPU_NAME "sparc"
|
||
- /* #define MY_CPU_32BIT */
|
||
-#endif
|
||
-
|
||
-
|
||
-#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64)
|
||
-#define MY_CPU_X86_OR_AMD64
|
||
-#endif
|
||
-
|
||
-#if defined(MY_CPU_ARM) || defined(MY_CPU_ARM64)
|
||
-#define MY_CPU_ARM_OR_ARM64
|
||
-#endif
|
||
-
|
||
-
|
||
-#ifdef _WIN32
|
||
-
|
||
- #ifdef MY_CPU_ARM
|
||
- #define MY_CPU_ARM_LE
|
||
- #endif
|
||
-
|
||
- #ifdef MY_CPU_ARM64
|
||
- #define MY_CPU_ARM64_LE
|
||
- #endif
|
||
-
|
||
- #ifdef _M_IA64
|
||
- #define MY_CPU_IA64_LE
|
||
- #endif
|
||
-
|
||
-#endif
|
||
-
|
||
-
|
||
-#if defined(MY_CPU_X86_OR_AMD64) \
|
||
- || defined(MY_CPU_ARM_LE) \
|
||
- || defined(MY_CPU_ARM64_LE) \
|
||
- || defined(MY_CPU_IA64_LE) \
|
||
- || defined(__LITTLE_ENDIAN__) \
|
||
- || defined(__ARMEL__) \
|
||
- || defined(__THUMBEL__) \
|
||
- || defined(__AARCH64EL__) \
|
||
- || defined(__MIPSEL__) \
|
||
- || defined(__MIPSEL) \
|
||
- || defined(_MIPSEL) \
|
||
- || defined(__BFIN__) \
|
||
- || (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
|
||
- #define MY_CPU_LE
|
||
-#endif
|
||
-
|
||
-#if defined(__BIG_ENDIAN__) \
|
||
- || defined(__ARMEB__) \
|
||
- || defined(__THUMBEB__) \
|
||
- || defined(__AARCH64EB__) \
|
||
- || defined(__MIPSEB__) \
|
||
- || defined(__MIPSEB) \
|
||
- || defined(_MIPSEB) \
|
||
- || defined(__m68k__) \
|
||
- || defined(__s390__) \
|
||
- || defined(__s390x__) \
|
||
- || defined(__zarch__) \
|
||
- || (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
|
||
- #define MY_CPU_BE
|
||
-#endif
|
||
-
|
||
-
|
||
-#if defined(MY_CPU_LE) && defined(MY_CPU_BE)
|
||
- #error Stop_Compiling_Bad_Endian
|
||
-#endif
|
||
-
|
||
-
|
||
-#if defined(MY_CPU_32BIT) && defined(MY_CPU_64BIT)
|
||
- #error Stop_Compiling_Bad_32_64_BIT
|
||
-#endif
|
||
-
|
||
-#ifdef __SIZEOF_POINTER__
|
||
- #ifdef MY_CPU_SIZEOF_POINTER
|
||
- #if MY_CPU_SIZEOF_POINTER != __SIZEOF_POINTER__
|
||
- #error Stop_Compiling_Bad_MY_CPU_PTR_SIZE
|
||
- #endif
|
||
- #else
|
||
- #define MY_CPU_SIZEOF_POINTER __SIZEOF_POINTER__
|
||
- #endif
|
||
-#endif
|
||
-
|
||
-#if defined(MY_CPU_SIZEOF_POINTER) && (MY_CPU_SIZEOF_POINTER == 4)
|
||
-#if defined (_LP64)
|
||
- #error Stop_Compiling_Bad_MY_CPU_PTR_SIZE
|
||
-#endif
|
||
-#endif
|
||
-
|
||
-#ifdef _MSC_VER
|
||
- #if _MSC_VER >= 1300
|
||
- #define MY_CPU_pragma_pack_push_1 __pragma(pack(push, 1))
|
||
- #define MY_CPU_pragma_pop __pragma(pack(pop))
|
||
- #else
|
||
- #define MY_CPU_pragma_pack_push_1
|
||
- #define MY_CPU_pragma_pop
|
||
- #endif
|
||
-#else
|
||
- #ifdef __xlC__
|
||
- #define MY_CPU_pragma_pack_push_1 _Pragma("pack(1)")
|
||
- #define MY_CPU_pragma_pop _Pragma("pack()")
|
||
- #else
|
||
- #define MY_CPU_pragma_pack_push_1 _Pragma("pack(push, 1)")
|
||
- #define MY_CPU_pragma_pop _Pragma("pack(pop)")
|
||
- #endif
|
||
-#endif
|
||
-
|
||
-
|
||
-#ifndef MY_CPU_NAME
|
||
- #ifdef MY_CPU_LE
|
||
- #define MY_CPU_NAME "LE"
|
||
- #elif defined(MY_CPU_BE)
|
||
- #define MY_CPU_NAME "BE"
|
||
- #else
|
||
- /*
|
||
- #define MY_CPU_NAME ""
|
||
- */
|
||
- #endif
|
||
-#endif
|
||
-
|
||
-
|
||
-
|
||
-
|
||
-
|
||
-#ifdef MY_CPU_LE
|
||
- #if defined(MY_CPU_X86_OR_AMD64) \
|
||
- || defined(MY_CPU_ARM64)
|
||
- #define MY_CPU_LE_UNALIGN
|
||
- #define MY_CPU_LE_UNALIGN_64
|
||
- #elif defined(__ARM_FEATURE_UNALIGNED)
|
||
- /* gcc9 for 32-bit arm can use LDRD instruction that requires 32-bit alignment.
|
||
- So we can't use unaligned 64-bit operations. */
|
||
- #define MY_CPU_LE_UNALIGN
|
||
- #endif
|
||
-#endif
|
||
-
|
||
-
|
||
-#ifdef MY_CPU_LE_UNALIGN
|
||
-
|
||
-#define GetUi16(p) (*(const UInt16 *)(const void *)(p))
|
||
-#define GetUi32(p) (*(const UInt32 *)(const void *)(p))
|
||
-#ifdef MY_CPU_LE_UNALIGN_64
|
||
-#define GetUi64(p) (*(const UInt64 *)(const void *)(p))
|
||
-#endif
|
||
-
|
||
-#define SetUi16(p, v) { *(UInt16 *)(void *)(p) = (v); }
|
||
-#define SetUi32(p, v) { *(UInt32 *)(void *)(p) = (v); }
|
||
-#ifdef MY_CPU_LE_UNALIGN_64
|
||
-#define SetUi64(p, v) { *(UInt64 *)(void *)(p) = (v); }
|
||
-#endif
|
||
-
|
||
-#else
|
||
-
|
||
-#define GetUi16(p) ( (UInt16) ( \
|
||
- ((const Byte *)(p))[0] | \
|
||
- ((UInt16)((const Byte *)(p))[1] << 8) ))
|
||
-
|
||
-#define GetUi32(p) ( \
|
||
- ((const Byte *)(p))[0] | \
|
||
- ((UInt32)((const Byte *)(p))[1] << 8) | \
|
||
- ((UInt32)((const Byte *)(p))[2] << 16) | \
|
||
- ((UInt32)((const Byte *)(p))[3] << 24))
|
||
-
|
||
-#define SetUi16(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
|
||
- _ppp_[0] = (Byte)_vvv_; \
|
||
- _ppp_[1] = (Byte)(_vvv_ >> 8); }
|
||
-
|
||
-#define SetUi32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
|
||
- _ppp_[0] = (Byte)_vvv_; \
|
||
- _ppp_[1] = (Byte)(_vvv_ >> 8); \
|
||
- _ppp_[2] = (Byte)(_vvv_ >> 16); \
|
||
- _ppp_[3] = (Byte)(_vvv_ >> 24); }
|
||
-
|
||
-#endif
|
||
-
|
||
-
|
||
-#ifndef MY_CPU_LE_UNALIGN_64
|
||
-
|
||
-#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32))
|
||
-
|
||
-#define SetUi64(p, v) { Byte *_ppp2_ = (Byte *)(p); UInt64 _vvv2_ = (v); \
|
||
- SetUi32(_ppp2_ , (UInt32)_vvv2_); \
|
||
- SetUi32(_ppp2_ + 4, (UInt32)(_vvv2_ >> 32)); }
|
||
-
|
||
-#endif
|
||
-
|
||
-
|
||
-
|
||
-
|
||
-#ifdef __has_builtin
|
||
- #define MY__has_builtin(x) __has_builtin(x)
|
||
-#else
|
||
- #define MY__has_builtin(x) 0
|
||
-#endif
|
||
-
|
||
-#if defined(MY_CPU_LE_UNALIGN) && /* defined(_WIN64) && */ defined(_MSC_VER) && (_MSC_VER >= 1300)
|
||
-
|
||
-/* Note: we use bswap instruction, that is unsupported in 386 cpu */
|
||
-
|
||
-#include <stdlib.h>
|
||
-
|
||
-#pragma intrinsic(_byteswap_ushort)
|
||
-#pragma intrinsic(_byteswap_ulong)
|
||
-#pragma intrinsic(_byteswap_uint64)
|
||
-
|
||
-/* #define GetBe16(p) _byteswap_ushort(*(const UInt16 *)(const Byte *)(p)) */
|
||
-#define GetBe32(p) _byteswap_ulong (*(const UInt32 *)(const void *)(p))
|
||
-#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const void *)(p))
|
||
-
|
||
-#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = _byteswap_ulong(v)
|
||
-
|
||
-#elif defined(MY_CPU_LE_UNALIGN) && ( \
|
||
- (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) \
|
||
- || (defined(__clang__) && MY__has_builtin(__builtin_bswap16)) )
|
||
-
|
||
-/* #define GetBe16(p) __builtin_bswap16(*(const UInt16 *)(const void *)(p)) */
|
||
-#define GetBe32(p) __builtin_bswap32(*(const UInt32 *)(const void *)(p))
|
||
-#define GetBe64(p) __builtin_bswap64(*(const UInt64 *)(const void *)(p))
|
||
-
|
||
-#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = __builtin_bswap32(v)
|
||
-
|
||
-#else
|
||
-
|
||
-#define GetBe32(p) ( \
|
||
- ((UInt32)((const Byte *)(p))[0] << 24) | \
|
||
- ((UInt32)((const Byte *)(p))[1] << 16) | \
|
||
- ((UInt32)((const Byte *)(p))[2] << 8) | \
|
||
- ((const Byte *)(p))[3] )
|
||
-
|
||
-#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4))
|
||
-
|
||
-#define SetBe32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
|
||
- _ppp_[0] = (Byte)(_vvv_ >> 24); \
|
||
- _ppp_[1] = (Byte)(_vvv_ >> 16); \
|
||
- _ppp_[2] = (Byte)(_vvv_ >> 8); \
|
||
- _ppp_[3] = (Byte)_vvv_; }
|
||
-
|
||
-#endif
|
||
-
|
||
-
|
||
-#ifndef GetBe16
|
||
-
|
||
-#define GetBe16(p) ( (UInt16) ( \
|
||
- ((UInt16)((const Byte *)(p))[0] << 8) | \
|
||
- ((const Byte *)(p))[1] ))
|
||
-
|
||
-#endif
|
||
-
|
||
-
|
||
-
|
||
-#ifdef MY_CPU_X86_OR_AMD64
|
||
-
|
||
-typedef struct
|
||
-{
|
||
- UInt32 maxFunc;
|
||
- UInt32 vendor[3];
|
||
- UInt32 ver;
|
||
- UInt32 b;
|
||
- UInt32 c;
|
||
- UInt32 d;
|
||
-} Cx86cpuid;
|
||
-
|
||
-enum
|
||
-{
|
||
- CPU_FIRM_INTEL,
|
||
- CPU_FIRM_AMD,
|
||
- CPU_FIRM_VIA
|
||
-};
|
||
-
|
||
-void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d);
|
||
-
|
||
-BoolInt x86cpuid_CheckAndRead(Cx86cpuid *p);
|
||
-int x86cpuid_GetFirm(const Cx86cpuid *p);
|
||
-
|
||
-#define x86cpuid_GetFamily(ver) (((ver >> 16) & 0xFF0) | ((ver >> 8) & 0xF))
|
||
-#define x86cpuid_GetModel(ver) (((ver >> 12) & 0xF0) | ((ver >> 4) & 0xF))
|
||
-#define x86cpuid_GetStepping(ver) (ver & 0xF)
|
||
-
|
||
-BoolInt CPU_Is_InOrder(void);
|
||
-
|
||
-BoolInt CPU_IsSupported_AES(void);
|
||
-BoolInt CPU_IsSupported_AVX2(void);
|
||
-BoolInt CPU_IsSupported_VAES_AVX2(void);
|
||
-BoolInt CPU_IsSupported_SSSE3(void);
|
||
-BoolInt CPU_IsSupported_SSE41(void);
|
||
-BoolInt CPU_IsSupported_SHA(void);
|
||
-BoolInt CPU_IsSupported_PageGB(void);
|
||
-
|
||
-#elif defined(MY_CPU_ARM_OR_ARM64)
|
||
-
|
||
-BoolInt CPU_IsSupported_CRC32(void);
|
||
-BoolInt CPU_IsSupported_NEON(void);
|
||
-
|
||
-#if defined(_WIN32)
|
||
-BoolInt CPU_IsSupported_CRYPTO(void);
|
||
-#define CPU_IsSupported_SHA1 CPU_IsSupported_CRYPTO
|
||
-#define CPU_IsSupported_SHA2 CPU_IsSupported_CRYPTO
|
||
-#define CPU_IsSupported_AES CPU_IsSupported_CRYPTO
|
||
-#else
|
||
-BoolInt CPU_IsSupported_SHA1(void);
|
||
-BoolInt CPU_IsSupported_SHA2(void);
|
||
-BoolInt CPU_IsSupported_AES(void);
|
||
-#endif
|
||
-
|
||
-#endif
|
||
-
|
||
-#if defined(__APPLE__)
|
||
-int My_sysctlbyname_Get(const char *name, void *buf, size_t *bufSize);
|
||
-int My_sysctlbyname_Get_UInt32(const char *name, UInt32 *val);
|
||
-#endif
|
||
-
|
||
-EXTERN_C_END
|
||
-
|
||
-#endif
|
||
diff --git a/cut-n-paste/unarr/lzmasdk/Ppmd.h b/cut-n-paste/unarr/lzmasdk/Ppmd.h
|
||
deleted file mode 100644
|
||
index b1987920..00000000
|
||
--- a/cut-n-paste/unarr/lzmasdk/Ppmd.h
|
||
+++ /dev/null
|
||
@@ -1,167 +0,0 @@
|
||
-/* Ppmd.h -- PPMD codec common code
|
||
-2021-04-13 : Igor Pavlov : Public domain
|
||
-This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
|
||
-
|
||
-#ifndef __PPMD_H
|
||
-#define __PPMD_H
|
||
-
|
||
-#include "CpuArch.h"
|
||
-
|
||
-EXTERN_C_BEGIN
|
||
-
|
||
-#if defined(MY_CPU_SIZEOF_POINTER) && (MY_CPU_SIZEOF_POINTER == 4)
|
||
-/*
|
||
- PPMD code always uses 32-bit internal fields in PPMD structures to store internal references in main block.
|
||
- if (PPMD_32BIT is defined), the PPMD code stores internal pointers to 32-bit reference fields.
|
||
- if (PPMD_32BIT is NOT defined), the PPMD code stores internal UInt32 offsets to reference fields.
|
||
- if (pointer size is 64-bit), then (PPMD_32BIT) mode is not allowed,
|
||
- if (pointer size is 32-bit), then (PPMD_32BIT) mode is optional,
|
||
- and it's allowed to disable PPMD_32BIT mode even if pointer is 32-bit.
|
||
- PPMD code works slightly faster in (PPMD_32BIT) mode.
|
||
-*/
|
||
- #define PPMD_32BIT
|
||
-#endif
|
||
-
|
||
-#define PPMD_INT_BITS 7
|
||
-#define PPMD_PERIOD_BITS 7
|
||
-#define PPMD_BIN_SCALE (1 << (PPMD_INT_BITS + PPMD_PERIOD_BITS))
|
||
-
|
||
-#define PPMD_GET_MEAN_SPEC(summ, shift, round) (((summ) + (1 << ((shift) - (round)))) >> (shift))
|
||
-#define PPMD_GET_MEAN(summ) PPMD_GET_MEAN_SPEC((summ), PPMD_PERIOD_BITS, 2)
|
||
-#define PPMD_UPDATE_PROB_0(prob) ((prob) + (1 << PPMD_INT_BITS) - PPMD_GET_MEAN(prob))
|
||
-#define PPMD_UPDATE_PROB_1(prob) ((prob) - PPMD_GET_MEAN(prob))
|
||
-
|
||
-#define PPMD_N1 4
|
||
-#define PPMD_N2 4
|
||
-#define PPMD_N3 4
|
||
-#define PPMD_N4 ((128 + 3 - 1 * PPMD_N1 - 2 * PPMD_N2 - 3 * PPMD_N3) / 4)
|
||
-#define PPMD_NUM_INDEXES (PPMD_N1 + PPMD_N2 + PPMD_N3 + PPMD_N4)
|
||
-
|
||
-MY_CPU_pragma_pack_push_1
|
||
-/* Most compilers works OK here even without #pragma pack(push, 1), but some GCC compilers need it. */
|
||
-
|
||
-/* SEE-contexts for PPM-contexts with masked symbols */
|
||
-typedef struct
|
||
-{
|
||
- UInt16 Summ; /* Freq */
|
||
- Byte Shift; /* Speed of Freq change; low Shift is for fast change */
|
||
- Byte Count; /* Count to next change of Shift */
|
||
-} CPpmd_See;
|
||
-
|
||
-#define Ppmd_See_Update(p) if ((p)->Shift < PPMD_PERIOD_BITS && --(p)->Count == 0) \
|
||
- { (p)->Summ = (UInt16)((p)->Summ << 1); (p)->Count = (Byte)(3 << (p)->Shift++); }
|
||
-
|
||
-
|
||
-typedef struct
|
||
-{
|
||
- Byte Symbol;
|
||
- Byte Freq;
|
||
- UInt16 Successor_0;
|
||
- UInt16 Successor_1;
|
||
-} CPpmd_State;
|
||
-
|
||
-typedef struct CPpmd_State2_
|
||
-{
|
||
- Byte Symbol;
|
||
- Byte Freq;
|
||
-} CPpmd_State2;
|
||
-
|
||
-typedef struct CPpmd_State4_
|
||
-{
|
||
- UInt16 Successor_0;
|
||
- UInt16 Successor_1;
|
||
-} CPpmd_State4;
|
||
-
|
||
-MY_CPU_pragma_pop
|
||
-
|
||
-/*
|
||
- PPMD code can write full CPpmd_State structure data to CPpmd*_Context
|
||
- at (byte offset = 2) instead of some fields of original CPpmd*_Context structure.
|
||
-
|
||
- If we use pointers to different types, but that point to shared
|
||
- memory space, we can have aliasing problem (strict aliasing).
|
||
-
|
||
- XLC compiler in -O2 mode can change the order of memory write instructions
|
||
- in relation to read instructions, if we have use pointers to different types.
|
||
-
|
||
- To solve that aliasing problem we use combined CPpmd*_Context structure
|
||
- with unions that contain the fields from both structures:
|
||
- the original CPpmd*_Context and CPpmd_State.
|
||
- So we can access the fields from both structures via one pointer,
|
||
- and the compiler doesn't change the order of write instructions
|
||
- in relation to read instructions.
|
||
-
|
||
- If we don't use memory write instructions to shared memory in
|
||
- some local code, and we use only reading instructions (read only),
|
||
- then probably it's safe to use pointers to different types for reading.
|
||
-*/
|
||
-
|
||
-
|
||
-
|
||
-#ifdef PPMD_32BIT
|
||
-
|
||
- #define Ppmd_Ref_Type(type) type *
|
||
- #define Ppmd_GetRef(p, ptr) (ptr)
|
||
- #define Ppmd_GetPtr(p, ptr) (ptr)
|
||
- #define Ppmd_GetPtr_Type(p, ptr, note_type) (ptr)
|
||
-
|
||
-#else
|
||
-
|
||
- #define Ppmd_Ref_Type(type) UInt32
|
||
- #define Ppmd_GetRef(p, ptr) ((UInt32)((Byte *)(ptr) - (p)->Base))
|
||
- #define Ppmd_GetPtr(p, offs) ((void *)((p)->Base + (offs)))
|
||
- #define Ppmd_GetPtr_Type(p, offs, type) ((type *)Ppmd_GetPtr(p, offs))
|
||
-
|
||
-#endif // PPMD_32BIT
|
||
-
|
||
-
|
||
-typedef Ppmd_Ref_Type(CPpmd_State) CPpmd_State_Ref;
|
||
-typedef Ppmd_Ref_Type(void) CPpmd_Void_Ref;
|
||
-typedef Ppmd_Ref_Type(Byte) CPpmd_Byte_Ref;
|
||
-
|
||
-
|
||
-/*
|
||
-#ifdef MY_CPU_LE_UNALIGN
|
||
-// the unaligned 32-bit access latency can be too large, if the data is not in L1 cache.
|
||
-#define Ppmd_GET_SUCCESSOR(p) ((CPpmd_Void_Ref)*(const UInt32 *)(const void *)&(p)->Successor_0)
|
||
-#define Ppmd_SET_SUCCESSOR(p, v) *(UInt32 *)(void *)(void *)&(p)->Successor_0 = (UInt32)(v)
|
||
-
|
||
-#else
|
||
-*/
|
||
-
|
||
-/*
|
||
- We can write 16-bit halves to 32-bit (Successor) field in any selected order.
|
||
- But the native order is more consistent way.
|
||
- So we use the native order, if LE/BE order can be detected here at compile time.
|
||
-*/
|
||
-
|
||
-#ifdef MY_CPU_BE
|
||
-
|
||
- #define Ppmd_GET_SUCCESSOR(p) \
|
||
- ( (CPpmd_Void_Ref) (((UInt32)(p)->Successor_0 << 16) | (p)->Successor_1) )
|
||
-
|
||
- #define Ppmd_SET_SUCCESSOR(p, v) { \
|
||
- (p)->Successor_0 = (UInt16)(((UInt32)(v) >> 16) /* & 0xFFFF */); \
|
||
- (p)->Successor_1 = (UInt16)((UInt32)(v) /* & 0xFFFF */); }
|
||
-
|
||
-#else
|
||
-
|
||
- #define Ppmd_GET_SUCCESSOR(p) \
|
||
- ( (CPpmd_Void_Ref) ((p)->Successor_0 | ((UInt32)(p)->Successor_1 << 16)) )
|
||
-
|
||
- #define Ppmd_SET_SUCCESSOR(p, v) { \
|
||
- (p)->Successor_0 = (UInt16)((UInt32)(v) /* & 0xFFFF */); \
|
||
- (p)->Successor_1 = (UInt16)(((UInt32)(v) >> 16) /* & 0xFFFF */); }
|
||
-
|
||
-#endif
|
||
-
|
||
-// #endif
|
||
-
|
||
-
|
||
-#define PPMD_SetAllBitsIn256Bytes(p) \
|
||
- { size_t z; for (z = 0; z < 256 / sizeof(p[0]); z += 8) { \
|
||
- p[z+7] = p[z+6] = p[z+5] = p[z+4] = p[z+3] = p[z+2] = p[z+1] = p[z+0] = ~(size_t)0; }}
|
||
-
|
||
-EXTERN_C_END
|
||
-
|
||
-#endif
|
||
diff --git a/cut-n-paste/unarr/lzmasdk/Ppmd7.c b/cut-n-paste/unarr/lzmasdk/Ppmd7.c
|
||
deleted file mode 100644
|
||
index cf401cb3..00000000
|
||
--- a/cut-n-paste/unarr/lzmasdk/Ppmd7.c
|
||
+++ /dev/null
|
||
@@ -1,1104 +0,0 @@
|
||
-/* Ppmd7.c -- PPMdH codec
|
||
-2021-04-13 : Igor Pavlov : Public domain
|
||
-This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
|
||
-
|
||
-#include "Precomp.h"
|
||
-
|
||
-#include <string.h>
|
||
-
|
||
-#include "Ppmd7.h"
|
||
-
|
||
-/* define PPMD7_ORDER_0_SUPPPORT to suport order-0 mode, unsupported by orignal PPMd var.H. code */
|
||
-// #define PPMD7_ORDER_0_SUPPPORT
|
||
-
|
||
-MY_ALIGN(16)
|
||
-static const Byte PPMD7_kExpEscape[16] = { 25, 14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 };
|
||
-MY_ALIGN(16)
|
||
-static const UInt16 kInitBinEsc[] = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051};
|
||
-
|
||
-#define MAX_FREQ 124
|
||
-#define UNIT_SIZE 12
|
||
-
|
||
-#define U2B(nu) ((UInt32)(nu) * UNIT_SIZE)
|
||
-#define U2I(nu) (p->Units2Indx[(size_t)(nu) - 1])
|
||
-#define I2U(indx) ((unsigned)p->Indx2Units[indx])
|
||
-#define I2U_UInt16(indx) ((UInt16)p->Indx2Units[indx])
|
||
-
|
||
-#define REF(ptr) Ppmd_GetRef(p, ptr)
|
||
-
|
||
-#define STATS_REF(ptr) ((CPpmd_State_Ref)REF(ptr))
|
||
-
|
||
-#define CTX(ref) ((CPpmd7_Context *)Ppmd7_GetContext(p, ref))
|
||
-#define STATS(ctx) Ppmd7_GetStats(p, ctx)
|
||
-#define ONE_STATE(ctx) Ppmd7Context_OneState(ctx)
|
||
-#define SUFFIX(ctx) CTX((ctx)->Suffix)
|
||
-
|
||
-typedef CPpmd7_Context * CTX_PTR;
|
||
-
|
||
-struct CPpmd7_Node_;
|
||
-
|
||
-typedef Ppmd_Ref_Type(struct CPpmd7_Node_) CPpmd7_Node_Ref;
|
||
-
|
||
-typedef struct CPpmd7_Node_
|
||
-{
|
||
- UInt16 Stamp; /* must be at offset 0 as CPpmd7_Context::NumStats. Stamp=0 means free */
|
||
- UInt16 NU;
|
||
- CPpmd7_Node_Ref Next; /* must be at offset >= 4 */
|
||
- CPpmd7_Node_Ref Prev;
|
||
-} CPpmd7_Node;
|
||
-
|
||
-#define NODE(r) Ppmd_GetPtr_Type(p, r, CPpmd7_Node)
|
||
-
|
||
-void Ppmd7_Construct(CPpmd7 *p)
|
||
-{
|
||
- unsigned i, k, m;
|
||
-
|
||
- p->Base = NULL;
|
||
-
|
||
- for (i = 0, k = 0; i < PPMD_NUM_INDEXES; i++)
|
||
- {
|
||
- unsigned step = (i >= 12 ? 4 : (i >> 2) + 1);
|
||
- do { p->Units2Indx[k++] = (Byte)i; } while (--step);
|
||
- p->Indx2Units[i] = (Byte)k;
|
||
- }
|
||
-
|
||
- p->NS2BSIndx[0] = (0 << 1);
|
||
- p->NS2BSIndx[1] = (1 << 1);
|
||
- memset(p->NS2BSIndx + 2, (2 << 1), 9);
|
||
- memset(p->NS2BSIndx + 11, (3 << 1), 256 - 11);
|
||
-
|
||
- for (i = 0; i < 3; i++)
|
||
- p->NS2Indx[i] = (Byte)i;
|
||
-
|
||
- for (m = i, k = 1; i < 256; i++)
|
||
- {
|
||
- p->NS2Indx[i] = (Byte)m;
|
||
- if (--k == 0)
|
||
- k = (++m) - 2;
|
||
- }
|
||
-
|
||
- memcpy(p->ExpEscape, PPMD7_kExpEscape, 16);
|
||
-}
|
||
-
|
||
-
|
||
-void Ppmd7_Free(CPpmd7 *p, ISzAllocPtr alloc)
|
||
-{
|
||
- ISzAlloc_Free(alloc, p->Base);
|
||
- p->Size = 0;
|
||
- p->Base = NULL;
|
||
-}
|
||
-
|
||
-
|
||
-BoolInt Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAllocPtr alloc)
|
||
-{
|
||
- if (!p->Base || p->Size != size)
|
||
- {
|
||
- Ppmd7_Free(p, alloc);
|
||
- p->AlignOffset = (4 - size) & 3;
|
||
- if ((p->Base = (Byte *)ISzAlloc_Alloc(alloc, p->AlignOffset + size)) == NULL)
|
||
- return False;
|
||
- p->Size = size;
|
||
- }
|
||
- return True;
|
||
-}
|
||
-
|
||
-
|
||
-
|
||
-// ---------- Internal Memory Allocator ----------
|
||
-
|
||
-/* We can use CPpmd7_Node in list of free units (as in Ppmd8)
|
||
- But we still need one additional list walk pass in GlueFreeBlocks().
|
||
- So we use simple CPpmd_Void_Ref instead of CPpmd7_Node in InsertNode() / RemoveNode()
|
||
-*/
|
||
-
|
||
-#define EMPTY_NODE 0
|
||
-
|
||
-
|
||
-static void InsertNode(CPpmd7 *p, void *node, unsigned indx)
|
||
-{
|
||
- *((CPpmd_Void_Ref *)node) = p->FreeList[indx];
|
||
- // ((CPpmd7_Node *)node)->Next = (CPpmd7_Node_Ref)p->FreeList[indx];
|
||
-
|
||
- p->FreeList[indx] = REF(node);
|
||
-
|
||
-}
|
||
-
|
||
-
|
||
-static void *RemoveNode(CPpmd7 *p, unsigned indx)
|
||
-{
|
||
- CPpmd_Void_Ref *node = (CPpmd_Void_Ref *)Ppmd7_GetPtr(p, p->FreeList[indx]);
|
||
- p->FreeList[indx] = *node;
|
||
- // CPpmd7_Node *node = NODE((CPpmd7_Node_Ref)p->FreeList[indx]);
|
||
- // p->FreeList[indx] = node->Next;
|
||
- return node;
|
||
-}
|
||
-
|
||
-
|
||
-static void SplitBlock(CPpmd7 *p, void *ptr, unsigned oldIndx, unsigned newIndx)
|
||
-{
|
||
- unsigned i, nu = I2U(oldIndx) - I2U(newIndx);
|
||
- ptr = (Byte *)ptr + U2B(I2U(newIndx));
|
||
- if (I2U(i = U2I(nu)) != nu)
|
||
- {
|
||
- unsigned k = I2U(--i);
|
||
- InsertNode(p, ((Byte *)ptr) + U2B(k), nu - k - 1);
|
||
- }
|
||
- InsertNode(p, ptr, i);
|
||
-}
|
||
-
|
||
-
|
||
-/* we use CPpmd7_Node_Union union to solve XLC -O2 strict pointer aliasing problem */
|
||
-
|
||
-typedef union _CPpmd7_Node_Union
|
||
-{
|
||
- CPpmd7_Node Node;
|
||
- CPpmd7_Node_Ref NextRef;
|
||
-} CPpmd7_Node_Union;
|
||
-
|
||
-/* Original PPmdH (Ppmd7) code uses doubly linked list in GlueFreeBlocks()
|
||
- we use single linked list similar to Ppmd8 code */
|
||
-
|
||
-
|
||
-static void GlueFreeBlocks(CPpmd7 *p)
|
||
-{
|
||
- /*
|
||
- we use first UInt16 field of 12-bytes UNITs as record type stamp
|
||
- CPpmd_State { Byte Symbol; Byte Freq; : Freq != 0
|
||
- CPpmd7_Context { UInt16 NumStats; : NumStats != 0
|
||
- CPpmd7_Node { UInt16 Stamp : Stamp == 0 for free record
|
||
- : Stamp == 1 for head record and guard
|
||
- Last 12-bytes UNIT in array is always contains 12-bytes order-0 CPpmd7_Context record.
|
||
- */
|
||
- CPpmd7_Node_Ref head, n = 0;
|
||
-
|
||
- p->GlueCount = 255;
|
||
-
|
||
-
|
||
- /* we set guard NODE at LoUnit */
|
||
- if (p->LoUnit != p->HiUnit)
|
||
- ((CPpmd7_Node *)(void *)p->LoUnit)->Stamp = 1;
|
||
-
|
||
- {
|
||
- /* Create list of free blocks.
|
||
- We still need one additional list walk pass before Glue. */
|
||
- unsigned i;
|
||
- for (i = 0; i < PPMD_NUM_INDEXES; i++)
|
||
- {
|
||
- const UInt16 nu = I2U_UInt16(i);
|
||
- CPpmd7_Node_Ref next = (CPpmd7_Node_Ref)p->FreeList[i];
|
||
- p->FreeList[i] = 0;
|
||
- while (next != 0)
|
||
- {
|
||
- /* Don't change the order of the following commands: */
|
||
- CPpmd7_Node_Union *un = (CPpmd7_Node_Union *)NODE(next);
|
||
- const CPpmd7_Node_Ref tmp = next;
|
||
- next = un->NextRef;
|
||
- un->Node.Stamp = EMPTY_NODE;
|
||
- un->Node.NU = nu;
|
||
- un->Node.Next = n;
|
||
- n = tmp;
|
||
- }
|
||
- }
|
||
- }
|
||
-
|
||
- head = n;
|
||
- /* Glue and Fill must walk the list in same direction */
|
||
- {
|
||
- /* Glue free blocks */
|
||
- CPpmd7_Node_Ref *prev = &head;
|
||
- while (n)
|
||
- {
|
||
- CPpmd7_Node *node = NODE(n);
|
||
- UInt32 nu = node->NU;
|
||
- n = node->Next;
|
||
- if (nu == 0)
|
||
- {
|
||
- *prev = n;
|
||
- continue;
|
||
- }
|
||
- prev = &node->Next;
|
||
- for (;;)
|
||
- {
|
||
- CPpmd7_Node *node2 = node + nu;
|
||
- nu += node2->NU;
|
||
- if (node2->Stamp != EMPTY_NODE || nu >= 0x10000)
|
||
- break;
|
||
- node->NU = (UInt16)nu;
|
||
- node2->NU = 0;
|
||
- }
|
||
- }
|
||
- }
|
||
-
|
||
- /* Fill lists of free blocks */
|
||
- for (n = head; n != 0;)
|
||
- {
|
||
- CPpmd7_Node *node = NODE(n);
|
||
- UInt32 nu = node->NU;
|
||
- unsigned i;
|
||
- n = node->Next;
|
||
- if (nu == 0)
|
||
- continue;
|
||
- for (; nu > 128; nu -= 128, node += 128)
|
||
- InsertNode(p, node, PPMD_NUM_INDEXES - 1);
|
||
- if (I2U(i = U2I(nu)) != nu)
|
||
- {
|
||
- unsigned k = I2U(--i);
|
||
- InsertNode(p, node + k, (unsigned)nu - k - 1);
|
||
- }
|
||
- InsertNode(p, node, i);
|
||
- }
|
||
-}
|
||
-
|
||
-
|
||
-MY_NO_INLINE
|
||
-static void *AllocUnitsRare(CPpmd7 *p, unsigned indx)
|
||
-{
|
||
- unsigned i;
|
||
-
|
||
- if (p->GlueCount == 0)
|
||
- {
|
||
- GlueFreeBlocks(p);
|
||
- if (p->FreeList[indx] != 0)
|
||
- return RemoveNode(p, indx);
|
||
- }
|
||
-
|
||
- i = indx;
|
||
-
|
||
- do
|
||
- {
|
||
- if (++i == PPMD_NUM_INDEXES)
|
||
- {
|
||
- UInt32 numBytes = U2B(I2U(indx));
|
||
- Byte *us = p->UnitsStart;
|
||
- p->GlueCount--;
|
||
- return ((UInt32)(us - p->Text) > numBytes) ? (p->UnitsStart = us - numBytes) : NULL;
|
||
- }
|
||
- }
|
||
- while (p->FreeList[i] == 0);
|
||
-
|
||
- {
|
||
- void *block = RemoveNode(p, i);
|
||
- SplitBlock(p, block, i, indx);
|
||
- return block;
|
||
- }
|
||
-}
|
||
-
|
||
-
|
||
-static void *AllocUnits(CPpmd7 *p, unsigned indx)
|
||
-{
|
||
- if (p->FreeList[indx] != 0)
|
||
- return RemoveNode(p, indx);
|
||
- {
|
||
- UInt32 numBytes = U2B(I2U(indx));
|
||
- Byte *lo = p->LoUnit;
|
||
- if ((UInt32)(p->HiUnit - lo) >= numBytes)
|
||
- {
|
||
- p->LoUnit = lo + numBytes;
|
||
- return lo;
|
||
- }
|
||
- }
|
||
- return AllocUnitsRare(p, indx);
|
||
-}
|
||
-
|
||
-
|
||
-#define MyMem12Cpy(dest, src, num) \
|
||
- { UInt32 *d = (UInt32 *)dest; const UInt32 *z = (const UInt32 *)src; UInt32 n = num; \
|
||
- do { d[0] = z[0]; d[1] = z[1]; d[2] = z[2]; z += 3; d += 3; } while (--n); }
|
||
-
|
||
-
|
||
-/*
|
||
-static void *ShrinkUnits(CPpmd7 *p, void *oldPtr, unsigned oldNU, unsigned newNU)
|
||
-{
|
||
- unsigned i0 = U2I(oldNU);
|
||
- unsigned i1 = U2I(newNU);
|
||
- if (i0 == i1)
|
||
- return oldPtr;
|
||
- if (p->FreeList[i1] != 0)
|
||
- {
|
||
- void *ptr = RemoveNode(p, i1);
|
||
- MyMem12Cpy(ptr, oldPtr, newNU);
|
||
- InsertNode(p, oldPtr, i0);
|
||
- return ptr;
|
||
- }
|
||
- SplitBlock(p, oldPtr, i0, i1);
|
||
- return oldPtr;
|
||
-}
|
||
-*/
|
||
-
|
||
-
|
||
-#define SUCCESSOR(p) Ppmd_GET_SUCCESSOR(p)
|
||
-static void SetSuccessor(CPpmd_State *p, CPpmd_Void_Ref v)
|
||
-{
|
||
- Ppmd_SET_SUCCESSOR(p, v);
|
||
-}
|
||
-
|
||
-
|
||
-
|
||
-MY_NO_INLINE
|
||
-static
|
||
-void RestartModel(CPpmd7 *p)
|
||
-{
|
||
- unsigned i, k;
|
||
-
|
||
- memset(p->FreeList, 0, sizeof(p->FreeList));
|
||
-
|
||
- p->Text = p->Base + p->AlignOffset;
|
||
- p->HiUnit = p->Text + p->Size;
|
||
- p->LoUnit = p->UnitsStart = p->HiUnit - p->Size / 8 / UNIT_SIZE * 7 * UNIT_SIZE;
|
||
- p->GlueCount = 0;
|
||
-
|
||
- p->OrderFall = p->MaxOrder;
|
||
- p->RunLength = p->InitRL = -(Int32)((p->MaxOrder < 12) ? p->MaxOrder : 12) - 1;
|
||
- p->PrevSuccess = 0;
|
||
-
|
||
- {
|
||
- CPpmd7_Context *mc = (CTX_PTR)(void *)(p->HiUnit -= UNIT_SIZE); /* AllocContext(p); */
|
||
- CPpmd_State *s = (CPpmd_State *)p->LoUnit; /* AllocUnits(p, PPMD_NUM_INDEXES - 1); */
|
||
-
|
||
- p->LoUnit += U2B(256 / 2);
|
||
- p->MaxContext = p->MinContext = mc;
|
||
- p->FoundState = s;
|
||
-
|
||
- mc->NumStats = 256;
|
||
- mc->Union2.SummFreq = 256 + 1;
|
||
- mc->Union4.Stats = REF(s);
|
||
- mc->Suffix = 0;
|
||
-
|
||
- for (i = 0; i < 256; i++, s++)
|
||
- {
|
||
- s->Symbol = (Byte)i;
|
||
- s->Freq = 1;
|
||
- SetSuccessor(s, 0);
|
||
- }
|
||
-
|
||
- #ifdef PPMD7_ORDER_0_SUPPPORT
|
||
- if (p->MaxOrder == 0)
|
||
- {
|
||
- CPpmd_Void_Ref r = REF(mc);
|
||
- s = p->FoundState;
|
||
- for (i = 0; i < 256; i++, s++)
|
||
- SetSuccessor(s, r);
|
||
- return;
|
||
- }
|
||
- #endif
|
||
- }
|
||
-
|
||
- for (i = 0; i < 128; i++)
|
||
-
|
||
-
|
||
-
|
||
- for (k = 0; k < 8; k++)
|
||
- {
|
||
- unsigned m;
|
||
- UInt16 *dest = p->BinSumm[i] + k;
|
||
- UInt16 val = (UInt16)(PPMD_BIN_SCALE - kInitBinEsc[k] / (i + 2));
|
||
- for (m = 0; m < 64; m += 8)
|
||
- dest[m] = val;
|
||
- }
|
||
-
|
||
-
|
||
- for (i = 0; i < 25; i++)
|
||
- {
|
||
-
|
||
- CPpmd_See *s = p->See[i];
|
||
-
|
||
-
|
||
-
|
||
- unsigned summ = ((5 * i + 10) << (PPMD_PERIOD_BITS - 4));
|
||
- for (k = 0; k < 16; k++, s++)
|
||
- {
|
||
- s->Summ = (UInt16)summ;
|
||
- s->Shift = (PPMD_PERIOD_BITS - 4);
|
||
- s->Count = 4;
|
||
- }
|
||
- }
|
||
-
|
||
- p->DummySee.Summ = 0; /* unused */
|
||
- p->DummySee.Shift = PPMD_PERIOD_BITS;
|
||
- p->DummySee.Count = 64; /* unused */
|
||
-}
|
||
-
|
||
-
|
||
-void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder)
|
||
-{
|
||
- p->MaxOrder = maxOrder;
|
||
-
|
||
- RestartModel(p);
|
||
-}
|
||
-
|
||
-
|
||
-
|
||
-/*
|
||
- CreateSuccessors()
|
||
- It's called when (FoundState->Successor) is RAW-Successor,
|
||
- that is the link to position in Raw text.
|
||
- So we create Context records and write the links to
|
||
- FoundState->Successor and to identical RAW-Successors in suffix
|
||
- contexts of MinContex.
|
||
-
|
||
- The function returns:
|
||
- if (OrderFall == 0) then MinContext is already at MAX order,
|
||
- { return pointer to new or existing context of same MAX order }
|
||
- else
|
||
- { return pointer to new real context that will be (Order+1) in comparison with MinContext
|
||
-
|
||
- also it can return pointer to real context of same order,
|
||
-*/
|
||
-
|
||
-MY_NO_INLINE
|
||
-static CTX_PTR CreateSuccessors(CPpmd7 *p)
|
||
-{
|
||
- CTX_PTR c = p->MinContext;
|
||
- CPpmd_Byte_Ref upBranch = (CPpmd_Byte_Ref)SUCCESSOR(p->FoundState);
|
||
- Byte newSym, newFreq;
|
||
- unsigned numPs = 0;
|
||
- CPpmd_State *ps[PPMD7_MAX_ORDER];
|
||
-
|
||
- if (p->OrderFall != 0)
|
||
- ps[numPs++] = p->FoundState;
|
||
-
|
||
- while (c->Suffix)
|
||
- {
|
||
- CPpmd_Void_Ref successor;
|
||
- CPpmd_State *s;
|
||
- c = SUFFIX(c);
|
||
-
|
||
-
|
||
- if (c->NumStats != 1)
|
||
- {
|
||
- Byte sym = p->FoundState->Symbol;
|
||
- for (s = STATS(c); s->Symbol != sym; s++);
|
||
-
|
||
- }
|
||
- else
|
||
- {
|
||
- s = ONE_STATE(c);
|
||
-
|
||
- }
|
||
- successor = SUCCESSOR(s);
|
||
- if (successor != upBranch)
|
||
- {
|
||
- // (c) is real record Context here,
|
||
- c = CTX(successor);
|
||
- if (numPs == 0)
|
||
- {
|
||
- // (c) is real record MAX Order Context here,
|
||
- // So we don't need to create any new contexts.
|
||
- return c;
|
||
- }
|
||
- break;
|
||
- }
|
||
- ps[numPs++] = s;
|
||
- }
|
||
-
|
||
- // All created contexts will have single-symbol with new RAW-Successor
|
||
- // All new RAW-Successors will point to next position in RAW text
|
||
- // after FoundState->Successor
|
||
-
|
||
- newSym = *(const Byte *)Ppmd7_GetPtr(p, upBranch);
|
||
- upBranch++;
|
||
-
|
||
-
|
||
- if (c->NumStats == 1)
|
||
- newFreq = ONE_STATE(c)->Freq;
|
||
- else
|
||
- {
|
||
- UInt32 cf, s0;
|
||
- CPpmd_State *s;
|
||
- for (s = STATS(c); s->Symbol != newSym; s++);
|
||
- cf = (UInt32)s->Freq - 1;
|
||
- s0 = (UInt32)c->Union2.SummFreq - c->NumStats - cf;
|
||
- /*
|
||
- cf - is frequency of symbol that will be Successor in new context records.
|
||
- s0 - is commulative frequency sum of another symbols from parent context.
|
||
- max(newFreq)= (s->Freq + 1), when (s0 == 1)
|
||
- we have requirement (Ppmd7Context_OneState()->Freq <= 128) in BinSumm[]
|
||
- so (s->Freq < 128) - is requirement for multi-symbol contexts
|
||
- */
|
||
- newFreq = (Byte)(1 + ((2 * cf <= s0) ? (5 * cf > s0) : (2 * cf + s0 - 1) / (2 * s0) + 1));
|
||
- }
|
||
-
|
||
- // Create new single-symbol contexts from low order to high order in loop
|
||
-
|
||
- do
|
||
- {
|
||
- CTX_PTR c1;
|
||
- /* = AllocContext(p); */
|
||
- if (p->HiUnit != p->LoUnit)
|
||
- c1 = (CTX_PTR)(void *)(p->HiUnit -= UNIT_SIZE);
|
||
- else if (p->FreeList[0] != 0)
|
||
- c1 = (CTX_PTR)RemoveNode(p, 0);
|
||
- else
|
||
- {
|
||
- c1 = (CTX_PTR)AllocUnitsRare(p, 0);
|
||
- if (!c1)
|
||
- return NULL;
|
||
- }
|
||
-
|
||
- c1->NumStats = 1;
|
||
- ONE_STATE(c1)->Symbol = newSym;
|
||
- ONE_STATE(c1)->Freq = newFreq;
|
||
- SetSuccessor(ONE_STATE(c1), upBranch);
|
||
- c1->Suffix = REF(c);
|
||
- SetSuccessor(ps[--numPs], REF(c1));
|
||
- c = c1;
|
||
- }
|
||
- while (numPs != 0);
|
||
-
|
||
- return c;
|
||
-}
|
||
-
|
||
-
|
||
-
|
||
-#define SwapStates(s) \
|
||
- { CPpmd_State tmp = s[0]; s[0] = s[-1]; s[-1] = tmp; }
|
||
-
|
||
-
|
||
-void Ppmd7_UpdateModel(CPpmd7 *p);
|
||
-MY_NO_INLINE
|
||
-void Ppmd7_UpdateModel(CPpmd7 *p)
|
||
-{
|
||
- CPpmd_Void_Ref maxSuccessor, minSuccessor;
|
||
- CTX_PTR c, mc;
|
||
- unsigned s0, ns;
|
||
-
|
||
-
|
||
-
|
||
- if (p->FoundState->Freq < MAX_FREQ / 4 && p->MinContext->Suffix != 0)
|
||
- {
|
||
- /* Update Freqs in Suffix Context */
|
||
-
|
||
- c = SUFFIX(p->MinContext);
|
||
-
|
||
- if (c->NumStats == 1)
|
||
- {
|
||
- CPpmd_State *s = ONE_STATE(c);
|
||
- if (s->Freq < 32)
|
||
- s->Freq++;
|
||
- }
|
||
- else
|
||
- {
|
||
- CPpmd_State *s = STATS(c);
|
||
- Byte sym = p->FoundState->Symbol;
|
||
-
|
||
- if (s->Symbol != sym)
|
||
- {
|
||
- do
|
||
- {
|
||
- // s++; if (s->Symbol == sym) break;
|
||
- s++;
|
||
- }
|
||
- while (s->Symbol != sym);
|
||
-
|
||
- if (s[0].Freq >= s[-1].Freq)
|
||
- {
|
||
- SwapStates(s);
|
||
- s--;
|
||
- }
|
||
- }
|
||
-
|
||
- if (s->Freq < MAX_FREQ - 9)
|
||
- {
|
||
- s->Freq = (Byte)(s->Freq + 2);
|
||
- c->Union2.SummFreq = (UInt16)(c->Union2.SummFreq + 2);
|
||
- }
|
||
- }
|
||
- }
|
||
-
|
||
-
|
||
- if (p->OrderFall == 0)
|
||
- {
|
||
- /* MAX ORDER context */
|
||
- /* (FoundState->Successor) is RAW-Successor. */
|
||
- p->MaxContext = p->MinContext = CreateSuccessors(p);
|
||
- if (!p->MinContext)
|
||
- {
|
||
- RestartModel(p);
|
||
- return;
|
||
- }
|
||
- SetSuccessor(p->FoundState, REF(p->MinContext));
|
||
- return;
|
||
- }
|
||
-
|
||
-
|
||
- /* NON-MAX ORDER context */
|
||
-
|
||
- {
|
||
- Byte *text = p->Text;
|
||
- *text++ = p->FoundState->Symbol;
|
||
- p->Text = text;
|
||
- if (text >= p->UnitsStart)
|
||
- {
|
||
- RestartModel(p);
|
||
- return;
|
||
- }
|
||
- maxSuccessor = REF(text);
|
||
- }
|
||
-
|
||
- minSuccessor = SUCCESSOR(p->FoundState);
|
||
-
|
||
- if (minSuccessor)
|
||
- {
|
||
- // there is Successor for FoundState in MinContext.
|
||
- // So the next context will be one order higher than MinContext.
|
||
-
|
||
- if (minSuccessor <= maxSuccessor)
|
||
- {
|
||
- // minSuccessor is RAW-Successor. So we will create real contexts records:
|
||
- CTX_PTR cs = CreateSuccessors(p);
|
||
- if (!cs)
|
||
- {
|
||
- RestartModel(p);
|
||
- return;
|
||
- }
|
||
- minSuccessor = REF(cs);
|
||
- }
|
||
-
|
||
- // minSuccessor now is real Context pointer that points to existing (Order+1) context
|
||
-
|
||
- if (--p->OrderFall == 0)
|
||
- {
|
||
- /*
|
||
- if we move to MaxOrder context, then minSuccessor will be common Succesor for both:
|
||
- MinContext that is (MaxOrder - 1)
|
||
- MaxContext that is (MaxOrder)
|
||
- so we don't need new RAW-Successor, and we can use real minSuccessor
|
||
- as succssors for both MinContext and MaxContext.
|
||
- */
|
||
- maxSuccessor = minSuccessor;
|
||
-
|
||
- /*
|
||
- if (MaxContext != MinContext)
|
||
- {
|
||
- there was order fall from MaxOrder and we don't need current symbol
|
||
- to transfer some RAW-Succesors to real contexts.
|
||
- So we roll back pointer in raw data for one position.
|
||
- }
|
||
- */
|
||
- p->Text -= (p->MaxContext != p->MinContext);
|
||
- }
|
||
- }
|
||
- else
|
||
- {
|
||
- /*
|
||
- FoundState has NULL-Successor here.
|
||
- And only root 0-order context can contain NULL-Successors.
|
||
- We change Successor in FoundState to RAW-Successor,
|
||
- And next context will be same 0-order root Context.
|
||
- */
|
||
- SetSuccessor(p->FoundState, maxSuccessor);
|
||
- minSuccessor = REF(p->MinContext);
|
||
- }
|
||
-
|
||
- mc = p->MinContext;
|
||
- c = p->MaxContext;
|
||
-
|
||
- p->MaxContext = p->MinContext = CTX(minSuccessor);
|
||
-
|
||
- if (c == mc)
|
||
- return;
|
||
-
|
||
- // s0 : is pure Escape Freq
|
||
- s0 = mc->Union2.SummFreq - (ns = mc->NumStats) - ((unsigned)p->FoundState->Freq - 1);
|
||
-
|
||
- do
|
||
- {
|
||
- unsigned ns1;
|
||
- UInt32 sum;
|
||
-
|
||
- if ((ns1 = c->NumStats) != 1)
|
||
- {
|
||
- if ((ns1 & 1) == 0)
|
||
- {
|
||
- /* Expand for one UNIT */
|
||
- unsigned oldNU = ns1 >> 1;
|
||
- unsigned i = U2I(oldNU);
|
||
- if (i != U2I((size_t)oldNU + 1))
|
||
- {
|
||
- void *ptr = AllocUnits(p, i + 1);
|
||
- void *oldPtr;
|
||
- if (!ptr)
|
||
- {
|
||
- RestartModel(p);
|
||
- return;
|
||
- }
|
||
- oldPtr = STATS(c);
|
||
- MyMem12Cpy(ptr, oldPtr, oldNU);
|
||
- InsertNode(p, oldPtr, i);
|
||
- c->Union4.Stats = STATS_REF(ptr);
|
||
- }
|
||
- }
|
||
- sum = c->Union2.SummFreq;
|
||
- /* max increase of Escape_Freq is 3 here.
|
||
- total increase of Union2.SummFreq for all symbols is less than 256 here */
|
||
- sum += (UInt32)(2 * ns1 < ns) + 2 * ((unsigned)(4 * ns1 <= ns) & (sum <= 8 * ns1));
|
||
- /* original PPMdH uses 16-bit variable for (sum) here.
|
||
- But (sum < 0x9000). So we don't truncate (sum) to 16-bit */
|
||
- // sum = (UInt16)sum;
|
||
- }
|
||
- else
|
||
- {
|
||
- // instead of One-symbol context we create 2-symbol context
|
||
- CPpmd_State *s = (CPpmd_State*)AllocUnits(p, 0);
|
||
- if (!s)
|
||
- {
|
||
- RestartModel(p);
|
||
- return;
|
||
- }
|
||
- {
|
||
- unsigned freq = c->Union2.State2.Freq;
|
||
- // s = *ONE_STATE(c);
|
||
- s->Symbol = c->Union2.State2.Symbol;
|
||
- s->Successor_0 = c->Union4.State4.Successor_0;
|
||
- s->Successor_1 = c->Union4.State4.Successor_1;
|
||
- // SetSuccessor(s, c->Union4.Stats); // call it only for debug purposes to check the order of
|
||
- // (Successor_0 and Successor_1) in LE/BE.
|
||
- c->Union4.Stats = REF(s);
|
||
- if (freq < MAX_FREQ / 4 - 1)
|
||
- freq <<= 1;
|
||
- else
|
||
- freq = MAX_FREQ - 4;
|
||
- // (max(s->freq) == 120), when we convert from 1-symbol into 2-symbol context
|
||
- s->Freq = (Byte)freq;
|
||
- // max(InitEsc = PPMD7_kExpEscape[*]) is 25. So the max(escapeFreq) is 26 here
|
||
- sum = freq + p->InitEsc + (ns > 3);
|
||
- }
|
||
- }
|
||
-
|
||
- {
|
||
- CPpmd_State *s = STATS(c) + ns1;
|
||
- UInt32 cf = 2 * (sum + 6) * (UInt32)p->FoundState->Freq;
|
||
- UInt32 sf = (UInt32)s0 + sum;
|
||
- s->Symbol = p->FoundState->Symbol;
|
||
- c->NumStats = (UInt16)(ns1 + 1);
|
||
- SetSuccessor(s, maxSuccessor);
|
||
-
|
||
- if (cf < 6 * sf)
|
||
- {
|
||
- cf = (UInt32)1 + (cf > sf) + (cf >= 4 * sf);
|
||
- sum += 3;
|
||
- /* It can add (0, 1, 2) to Escape_Freq */
|
||
- }
|
||
- else
|
||
- {
|
||
- cf = (UInt32)4 + (cf >= 9 * sf) + (cf >= 12 * sf) + (cf >= 15 * sf);
|
||
- sum += cf;
|
||
- }
|
||
-
|
||
- c->Union2.SummFreq = (UInt16)sum;
|
||
- s->Freq = (Byte)cf;
|
||
- }
|
||
- c = SUFFIX(c);
|
||
- }
|
||
- while (c != mc);
|
||
-}
|
||
-
|
||
-
|
||
-
|
||
-MY_NO_INLINE
|
||
-static void Rescale(CPpmd7 *p)
|
||
-{
|
||
- unsigned i, adder, sumFreq, escFreq;
|
||
- CPpmd_State *stats = STATS(p->MinContext);
|
||
- CPpmd_State *s = p->FoundState;
|
||
-
|
||
- /* Sort the list by Freq */
|
||
- if (s != stats)
|
||
- {
|
||
- CPpmd_State tmp = *s;
|
||
- do
|
||
- s[0] = s[-1];
|
||
- while (--s != stats);
|
||
- *s = tmp;
|
||
- }
|
||
-
|
||
- sumFreq = s->Freq;
|
||
- escFreq = p->MinContext->Union2.SummFreq - sumFreq;
|
||
-
|
||
- /*
|
||
- if (p->OrderFall == 0), adder = 0 : it's allowed to remove symbol from MAX Order context
|
||
- if (p->OrderFall != 0), adder = 1 : it's NOT allowed to remove symbol from NON-MAX Order context
|
||
- */
|
||
-
|
||
- adder = (p->OrderFall != 0);
|
||
-
|
||
- #ifdef PPMD7_ORDER_0_SUPPPORT
|
||
- adder |= (p->MaxOrder == 0); // we don't remove symbols from order-0 context
|
||
- #endif
|
||
-
|
||
- sumFreq = (sumFreq + 4 + adder) >> 1;
|
||
- i = (unsigned)p->MinContext->NumStats - 1;
|
||
- s->Freq = (Byte)sumFreq;
|
||
-
|
||
- do
|
||
- {
|
||
- unsigned freq = (++s)->Freq;
|
||
- escFreq -= freq;
|
||
- freq = (freq + adder) >> 1;
|
||
- sumFreq += freq;
|
||
- s->Freq = (Byte)freq;
|
||
- if (freq > s[-1].Freq)
|
||
- {
|
||
- CPpmd_State tmp = *s;
|
||
- CPpmd_State *s1 = s;
|
||
- do
|
||
- {
|
||
- s1[0] = s1[-1];
|
||
- }
|
||
- while (--s1 != stats && freq > s1[-1].Freq);
|
||
- *s1 = tmp;
|
||
- }
|
||
- }
|
||
- while (--i);
|
||
-
|
||
- if (s->Freq == 0)
|
||
- {
|
||
- /* Remove all items with Freq == 0 */
|
||
- CPpmd7_Context *mc;
|
||
- unsigned numStats, numStatsNew, n0, n1;
|
||
-
|
||
- i = 0; do { i++; } while ((--s)->Freq == 0);
|
||
-
|
||
- /* We increase (escFreq) for the number of removed symbols.
|
||
- So we will have (0.5) increase for Escape_Freq in avarage per
|
||
- removed symbol after Escape_Freq halving */
|
||
- escFreq += i;
|
||
- mc = p->MinContext;
|
||
- numStats = mc->NumStats;
|
||
- numStatsNew = numStats - i;
|
||
- mc->NumStats = (UInt16)(numStatsNew);
|
||
- n0 = (numStats + 1) >> 1;
|
||
-
|
||
- if (numStatsNew == 1)
|
||
- {
|
||
- /* Create Single-Symbol context */
|
||
- unsigned freq = stats->Freq;
|
||
-
|
||
- do
|
||
- {
|
||
- escFreq >>= 1;
|
||
- freq = (freq + 1) >> 1;
|
||
- }
|
||
- while (escFreq > 1);
|
||
-
|
||
- s = ONE_STATE(mc);
|
||
- *s = *stats;
|
||
- s->Freq = (Byte)freq; // (freq <= 260 / 4)
|
||
- p->FoundState = s;
|
||
- InsertNode(p, stats, U2I(n0));
|
||
- return;
|
||
- }
|
||
-
|
||
- n1 = (numStatsNew + 1) >> 1;
|
||
- if (n0 != n1)
|
||
- {
|
||
- // p->MinContext->Union4.Stats = STATS_REF(ShrinkUnits(p, stats, n0, n1));
|
||
- unsigned i0 = U2I(n0);
|
||
- unsigned i1 = U2I(n1);
|
||
- if (i0 != i1)
|
||
- {
|
||
- if (p->FreeList[i1] != 0)
|
||
- {
|
||
- void *ptr = RemoveNode(p, i1);
|
||
- p->MinContext->Union4.Stats = STATS_REF(ptr);
|
||
- MyMem12Cpy(ptr, (const void *)stats, n1);
|
||
- InsertNode(p, stats, i0);
|
||
- }
|
||
- else
|
||
- SplitBlock(p, stats, i0, i1);
|
||
- }
|
||
- }
|
||
- }
|
||
- {
|
||
- CPpmd7_Context *mc = p->MinContext;
|
||
- mc->Union2.SummFreq = (UInt16)(sumFreq + escFreq - (escFreq >> 1));
|
||
- // Escape_Freq halving here
|
||
- p->FoundState = STATS(mc);
|
||
- }
|
||
-}
|
||
-
|
||
-
|
||
-CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *escFreq)
|
||
-{
|
||
- CPpmd_See *see;
|
||
- const CPpmd7_Context *mc = p->MinContext;
|
||
- unsigned numStats = mc->NumStats;
|
||
- if (numStats != 256)
|
||
- {
|
||
- unsigned nonMasked = numStats - numMasked;
|
||
- see = p->See[(unsigned)p->NS2Indx[(size_t)nonMasked - 1]]
|
||
- + (nonMasked < (unsigned)SUFFIX(mc)->NumStats - numStats)
|
||
- + 2 * (unsigned)(mc->Union2.SummFreq < 11 * numStats)
|
||
- + 4 * (unsigned)(numMasked > nonMasked) +
|
||
- p->HiBitsFlag;
|
||
- {
|
||
- // if (see->Summ) field is larger than 16-bit, we need only low 16 bits of Summ
|
||
- unsigned summ = (UInt16)see->Summ; // & 0xFFFF
|
||
- unsigned r = (summ >> see->Shift);
|
||
- see->Summ = (UInt16)(summ - r);
|
||
- *escFreq = r + (r == 0);
|
||
- }
|
||
- }
|
||
- else
|
||
- {
|
||
- see = &p->DummySee;
|
||
- *escFreq = 1;
|
||
- }
|
||
- return see;
|
||
-}
|
||
-
|
||
-
|
||
-static void NextContext(CPpmd7 *p)
|
||
-{
|
||
- CTX_PTR c = CTX(SUCCESSOR(p->FoundState));
|
||
- if (p->OrderFall == 0 && (const Byte *)c > p->Text)
|
||
- p->MaxContext = p->MinContext = c;
|
||
- else
|
||
- Ppmd7_UpdateModel(p);
|
||
-}
|
||
-
|
||
-
|
||
-void Ppmd7_Update1(CPpmd7 *p)
|
||
-{
|
||
- CPpmd_State *s = p->FoundState;
|
||
- unsigned freq = s->Freq;
|
||
- freq += 4;
|
||
- p->MinContext->Union2.SummFreq = (UInt16)(p->MinContext->Union2.SummFreq + 4);
|
||
- s->Freq = (Byte)freq;
|
||
- if (freq > s[-1].Freq)
|
||
- {
|
||
- SwapStates(s);
|
||
- p->FoundState = --s;
|
||
- if (freq > MAX_FREQ)
|
||
- Rescale(p);
|
||
- }
|
||
- NextContext(p);
|
||
-}
|
||
-
|
||
-
|
||
-void Ppmd7_Update1_0(CPpmd7 *p)
|
||
-{
|
||
- CPpmd_State *s = p->FoundState;
|
||
- CPpmd7_Context *mc = p->MinContext;
|
||
- unsigned freq = s->Freq;
|
||
- unsigned summFreq = mc->Union2.SummFreq;
|
||
- p->PrevSuccess = (2 * freq > summFreq);
|
||
- p->RunLength += (int)p->PrevSuccess;
|
||
- mc->Union2.SummFreq = (UInt16)(summFreq + 4);
|
||
- freq += 4;
|
||
- s->Freq = (Byte)freq;
|
||
- if (freq > MAX_FREQ)
|
||
- Rescale(p);
|
||
- NextContext(p);
|
||
-}
|
||
-
|
||
-
|
||
-/*
|
||
-void Ppmd7_UpdateBin(CPpmd7 *p)
|
||
-{
|
||
- unsigned freq = p->FoundState->Freq;
|
||
- p->FoundState->Freq = (Byte)(freq + (freq < 128));
|
||
- p->PrevSuccess = 1;
|
||
- p->RunLength++;
|
||
- NextContext(p);
|
||
-}
|
||
-*/
|
||
-
|
||
-void Ppmd7_Update2(CPpmd7 *p)
|
||
-{
|
||
- CPpmd_State *s = p->FoundState;
|
||
- unsigned freq = s->Freq;
|
||
- freq += 4;
|
||
- p->RunLength = p->InitRL;
|
||
- p->MinContext->Union2.SummFreq = (UInt16)(p->MinContext->Union2.SummFreq + 4);
|
||
- s->Freq = (Byte)freq;
|
||
- if (freq > MAX_FREQ)
|
||
- Rescale(p);
|
||
- Ppmd7_UpdateModel(p);
|
||
-}
|
||
-
|
||
-
|
||
-
|
||
-/*
|
||
-PPMd Memory Map:
|
||
-{
|
||
- [ 0 ] contains subset of original raw text, that is required to create context
|
||
- records, Some symbols are not written, when max order context was reached
|
||
- [ Text ] free area
|
||
- [ UnitsStart ] CPpmd_State vectors and CPpmd7_Context records
|
||
- [ LoUnit ] free area for CPpmd_State and CPpmd7_Context items
|
||
-[ HiUnit ] CPpmd7_Context records
|
||
- [ Size ] end of array
|
||
-}
|
||
-
|
||
-These addresses don't cross at any time.
|
||
-And the following condtions is true for addresses:
|
||
- (0 <= Text < UnitsStart <= LoUnit <= HiUnit <= Size)
|
||
-
|
||
-Raw text is BYTE--aligned.
|
||
-the data in block [ UnitsStart ... Size ] contains 12-bytes aligned UNITs.
|
||
-
|
||
-Last UNIT of array at offset (Size - 12) is root order-0 CPpmd7_Context record.
|
||
-The code can free UNITs memory blocks that were allocated to store CPpmd_State vectors.
|
||
-The code doesn't free UNITs allocated for CPpmd7_Context records.
|
||
-
|
||
-The code calls RestartModel(), when there is no free memory for allocation.
|
||
-And RestartModel() changes the state to orignal start state, with full free block.
|
||
-
|
||
-
|
||
-The code allocates UNITs with the following order:
|
||
-
|
||
-Allocation of 1 UNIT for Context record
|
||
- - from free space (HiUnit) down to (LoUnit)
|
||
- - from FreeList[0]
|
||
- - AllocUnitsRare()
|
||
-
|
||
-AllocUnits() for CPpmd_State vectors:
|
||
- - from FreeList[i]
|
||
- - from free space (LoUnit) up to (HiUnit)
|
||
- - AllocUnitsRare()
|
||
-
|
||
-AllocUnitsRare()
|
||
- - if (GlueCount == 0)
|
||
- { Glue lists, GlueCount = 255, allocate from FreeList[i]] }
|
||
- - loop for all higher sized FreeList[...] lists
|
||
- - from (UnitsStart - Text), GlueCount--
|
||
- - ERROR
|
||
-
|
||
-
|
||
-Each Record with Context contains the CPpmd_State vector, where each
|
||
-CPpmd_State contains the link to Successor.
|
||
-There are 3 types of Successor:
|
||
- 1) NULL-Successor - NULL pointer. NULL-Successor links can be stored
|
||
- only in 0-order Root Context Record.
|
||
- We use 0 value as NULL-Successor
|
||
- 2) RAW-Successor - the link to position in raw text,
|
||
- that "RAW-Successor" is being created after first
|
||
- occurrence of new symbol for some existing context record.
|
||
- (RAW-Successor > 0).
|
||
- 3) RECORD-Successor - the link to CPpmd7_Context record of (Order+1),
|
||
- that record is being created when we go via RAW-Successor again.
|
||
-
|
||
-For any successors at any time: the following condtions are true for Successor links:
|
||
-(NULL-Successor < RAW-Successor < UnitsStart <= RECORD-Successor)
|
||
-
|
||
-
|
||
----------- Symbol Frequency, SummFreq and Range in Range_Coder ----------
|
||
-
|
||
-CPpmd7_Context::SummFreq = Sum(Stats[].Freq) + Escape_Freq
|
||
-
|
||
-The PPMd code tries to fulfill the condition:
|
||
- (SummFreq <= (256 * 128 = RC::kBot))
|
||
-
|
||
-We have (Sum(Stats[].Freq) <= 256 * 124), because of (MAX_FREQ = 124)
|
||
-So (4 = 128 - 124) is average reserve for Escape_Freq for each symbol.
|
||
-If (CPpmd_State::Freq) is not aligned for 4, the reserve can be 5, 6 or 7.
|
||
-SummFreq and Escape_Freq can be changed in Rescale() and *Update*() functions.
|
||
-Rescale() can remove symbols only from max-order contexts. So Escape_Freq can increase after multiple calls of Rescale() for
|
||
-max-order context.
|
||
-
|
||
-When the PPMd code still break (Total <= RC::Range) condition in range coder,
|
||
-we have two ways to resolve that problem:
|
||
- 1) we can report error, if we want to keep compatibility with original PPMd code that has no fix for such cases.
|
||
- 2) we can reduce (Total) value to (RC::Range) by reducing (Escape_Freq) part of (Total) value.
|
||
-*/
|
||
diff --git a/cut-n-paste/unarr/lzmasdk/Ppmd7.h b/cut-n-paste/unarr/lzmasdk/Ppmd7.h
|
||
deleted file mode 100644
|
||
index d31809ae..00000000
|
||
--- a/cut-n-paste/unarr/lzmasdk/Ppmd7.h
|
||
+++ /dev/null
|
||
@@ -1,181 +0,0 @@
|
||
-/* Ppmd7.h -- Ppmd7 (PPMdH) compression codec
|
||
-2021-04-13 : Igor Pavlov : Public domain
|
||
-This code is based on:
|
||
- PPMd var.H (2001): Dmitry Shkarin : Public domain */
|
||
-
|
||
-
|
||
-#ifndef __PPMD7_H
|
||
-#define __PPMD7_H
|
||
-
|
||
-#include "Ppmd.h"
|
||
-
|
||
-EXTERN_C_BEGIN
|
||
-
|
||
-#define PPMD7_MIN_ORDER 2
|
||
-#define PPMD7_MAX_ORDER 64
|
||
-
|
||
-#define PPMD7_MIN_MEM_SIZE (1 << 11)
|
||
-#define PPMD7_MAX_MEM_SIZE (0xFFFFFFFF - 12 * 3)
|
||
-
|
||
-struct CPpmd7_Context_;
|
||
-
|
||
-typedef Ppmd_Ref_Type(struct CPpmd7_Context_) CPpmd7_Context_Ref;
|
||
-
|
||
-// MY_CPU_pragma_pack_push_1
|
||
-
|
||
-typedef struct CPpmd7_Context_
|
||
-{
|
||
- UInt16 NumStats;
|
||
-
|
||
-
|
||
- union
|
||
- {
|
||
- UInt16 SummFreq;
|
||
- CPpmd_State2 State2;
|
||
- } Union2;
|
||
-
|
||
- union
|
||
- {
|
||
- CPpmd_State_Ref Stats;
|
||
- CPpmd_State4 State4;
|
||
- } Union4;
|
||
-
|
||
- CPpmd7_Context_Ref Suffix;
|
||
-} CPpmd7_Context;
|
||
-
|
||
-// MY_CPU_pragma_pop
|
||
-
|
||
-#define Ppmd7Context_OneState(p) ((CPpmd_State *)&(p)->Union2)
|
||
-
|
||
-
|
||
-
|
||
-
|
||
-typedef struct
|
||
-{
|
||
- UInt32 Range;
|
||
- UInt32 Code;
|
||
- UInt32 Low;
|
||
- IByteIn *Stream;
|
||
-} CPpmd7_RangeDec;
|
||
-
|
||
-
|
||
-typedef struct
|
||
-{
|
||
- UInt32 Range;
|
||
- Byte Cache;
|
||
- // Byte _dummy_[3];
|
||
- UInt64 Low;
|
||
- UInt64 CacheSize;
|
||
- IByteOut *Stream;
|
||
-} CPpmd7z_RangeEnc;
|
||
-
|
||
-
|
||
-typedef struct
|
||
-{
|
||
- CPpmd7_Context *MinContext, *MaxContext;
|
||
- CPpmd_State *FoundState;
|
||
- unsigned OrderFall, InitEsc, PrevSuccess, MaxOrder, HiBitsFlag;
|
||
- Int32 RunLength, InitRL; /* must be 32-bit at least */
|
||
-
|
||
- UInt32 Size;
|
||
- UInt32 GlueCount;
|
||
- UInt32 AlignOffset;
|
||
- Byte *Base, *LoUnit, *HiUnit, *Text, *UnitsStart;
|
||
-
|
||
-
|
||
-
|
||
-
|
||
- union
|
||
- {
|
||
- CPpmd7_RangeDec dec;
|
||
- CPpmd7z_RangeEnc enc;
|
||
- } rc;
|
||
-
|
||
- Byte Indx2Units[PPMD_NUM_INDEXES + 2]; // +2 for alignment
|
||
- Byte Units2Indx[128];
|
||
- CPpmd_Void_Ref FreeList[PPMD_NUM_INDEXES];
|
||
-
|
||
- Byte NS2BSIndx[256], NS2Indx[256];
|
||
- Byte ExpEscape[16];
|
||
- CPpmd_See DummySee, See[25][16];
|
||
- UInt16 BinSumm[128][64];
|
||
- // int LastSymbol;
|
||
-} CPpmd7;
|
||
-
|
||
-
|
||
-void Ppmd7_Construct(CPpmd7 *p);
|
||
-BoolInt Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAllocPtr alloc);
|
||
-void Ppmd7_Free(CPpmd7 *p, ISzAllocPtr alloc);
|
||
-void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder);
|
||
-#define Ppmd7_WasAllocated(p) ((p)->Base != NULL)
|
||
-
|
||
-
|
||
-/* ---------- Internal Functions ---------- */
|
||
-
|
||
-#define Ppmd7_GetPtr(p, ptr) Ppmd_GetPtr(p, ptr)
|
||
-#define Ppmd7_GetContext(p, ptr) Ppmd_GetPtr_Type(p, ptr, CPpmd7_Context)
|
||
-#define Ppmd7_GetStats(p, ctx) Ppmd_GetPtr_Type(p, (ctx)->Union4.Stats, CPpmd_State)
|
||
-
|
||
-void Ppmd7_Update1(CPpmd7 *p);
|
||
-void Ppmd7_Update1_0(CPpmd7 *p);
|
||
-void Ppmd7_Update2(CPpmd7 *p);
|
||
-
|
||
-#define PPMD7_HiBitsFlag_3(sym) ((((unsigned)sym + 0xC0) >> (8 - 3)) & (1 << 3))
|
||
-#define PPMD7_HiBitsFlag_4(sym) ((((unsigned)sym + 0xC0) >> (8 - 4)) & (1 << 4))
|
||
-// #define PPMD7_HiBitsFlag_3(sym) ((sym) < 0x40 ? 0 : (1 << 3))
|
||
-// #define PPMD7_HiBitsFlag_4(sym) ((sym) < 0x40 ? 0 : (1 << 4))
|
||
-
|
||
-#define Ppmd7_GetBinSumm(p) \
|
||
- &p->BinSumm[(size_t)(unsigned)Ppmd7Context_OneState(p->MinContext)->Freq - 1] \
|
||
- [ p->PrevSuccess + ((p->RunLength >> 26) & 0x20) \
|
||
- + p->NS2BSIndx[(size_t)Ppmd7_GetContext(p, p->MinContext->Suffix)->NumStats - 1] \
|
||
- + PPMD7_HiBitsFlag_4(Ppmd7Context_OneState(p->MinContext)->Symbol) \
|
||
- + (p->HiBitsFlag = PPMD7_HiBitsFlag_3(p->FoundState->Symbol)) ]
|
||
-
|
||
-CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *scale);
|
||
-
|
||
-
|
||
-/*
|
||
-We support two versions of Ppmd7 (PPMdH) methods that use same CPpmd7 structure:
|
||
- 1) Ppmd7a_*: original PPMdH
|
||
- 2) Ppmd7z_*: modified PPMdH with 7z Range Coder
|
||
-Ppmd7_*: the structures and functions that are common for both versions of PPMd7 (PPMdH)
|
||
-*/
|
||
-
|
||
-/* ---------- Decode ---------- */
|
||
-
|
||
-#define PPMD7_SYM_END (-1)
|
||
-#define PPMD7_SYM_ERROR (-2)
|
||
-
|
||
-/*
|
||
-You must set (CPpmd7::rc.dec.Stream) before Ppmd7*_RangeDec_Init()
|
||
-
|
||
-Ppmd7*_DecodeSymbol()
|
||
-out:
|
||
- >= 0 : decoded byte
|
||
- -1 : PPMD7_SYM_END : End of payload marker
|
||
- -2 : PPMD7_SYM_ERROR : Data error
|
||
-*/
|
||
-
|
||
-/* Ppmd7a_* : original PPMdH */
|
||
-BoolInt Ppmd7a_RangeDec_Init(CPpmd7_RangeDec *p);
|
||
-#define Ppmd7a_RangeDec_IsFinishedOK(p) ((p)->Code == 0)
|
||
-int Ppmd7a_DecodeSymbol(CPpmd7 *p);
|
||
-
|
||
-/* Ppmd7z_* : modified PPMdH with 7z Range Coder */
|
||
-BoolInt Ppmd7z_RangeDec_Init(CPpmd7_RangeDec *p);
|
||
-#define Ppmd7z_RangeDec_IsFinishedOK(p) ((p)->Code == 0)
|
||
-int Ppmd7z_DecodeSymbol(CPpmd7 *p);
|
||
-// Byte *Ppmd7z_DecodeSymbols(CPpmd7 *p, Byte *buf, const Byte *lim);
|
||
-
|
||
-
|
||
-/* ---------- Encode ---------- */
|
||
-
|
||
-void Ppmd7z_Init_RangeEnc(CPpmd7 *p);
|
||
-void Ppmd7z_Flush_RangeEnc(CPpmd7 *p);
|
||
-// void Ppmd7z_EncodeSymbol(CPpmd7 *p, int symbol);
|
||
-void Ppmd7z_EncodeSymbols(CPpmd7 *p, const Byte *buf, const Byte *lim);
|
||
-
|
||
-EXTERN_C_END
|
||
-
|
||
-#endif
|
||
diff --git a/cut-n-paste/unarr/lzmasdk/Ppmd7Dec.c b/cut-n-paste/unarr/lzmasdk/Ppmd7Dec.c
|
||
deleted file mode 100644
|
||
index 55d74ff9..00000000
|
||
--- a/cut-n-paste/unarr/lzmasdk/Ppmd7Dec.c
|
||
+++ /dev/null
|
||
@@ -1,297 +0,0 @@
|
||
-/* Ppmd7Dec.c -- Ppmd7z (PPMdH with 7z Range Coder) Decoder
|
||
-2021-04-13 : Igor Pavlov : Public domain
|
||
-This code is based on:
|
||
- PPMd var.H (2001): Dmitry Shkarin : Public domain */
|
||
-
|
||
-
|
||
-#include "Precomp.h"
|
||
-
|
||
-#include "Ppmd7.h"
|
||
-
|
||
-#define kTopValue (1 << 24)
|
||
-
|
||
-
|
||
-#define READ_BYTE(p) IByteIn_Read((p)->Stream)
|
||
-
|
||
-BoolInt Ppmd7z_RangeDec_Init(CPpmd7_RangeDec *p)
|
||
-{
|
||
- unsigned i;
|
||
- p->Code = 0;
|
||
- p->Range = 0xFFFFFFFF;
|
||
- if (READ_BYTE(p) != 0)
|
||
- return False;
|
||
- for (i = 0; i < 4; i++)
|
||
- p->Code = (p->Code << 8) | READ_BYTE(p);
|
||
- return (p->Code < 0xFFFFFFFF);
|
||
-}
|
||
-
|
||
-#define RC_NORM_BASE(p) if ((p)->Range < kTopValue) \
|
||
- { (p)->Code = ((p)->Code << 8) | READ_BYTE(p); (p)->Range <<= 8;
|
||
-
|
||
-#define RC_NORM_1(p) RC_NORM_BASE(p) }
|
||
-#define RC_NORM(p) RC_NORM_BASE(p) RC_NORM_BASE(p) }}
|
||
-
|
||
-// we must use only one type of Normalization from two: LOCAL or REMOTE
|
||
-#define RC_NORM_LOCAL(p) // RC_NORM(p)
|
||
-#define RC_NORM_REMOTE(p) RC_NORM(p)
|
||
-
|
||
-#define R (&p->rc.dec)
|
||
-
|
||
-MY_FORCE_INLINE
|
||
-// MY_NO_INLINE
|
||
-static void RangeDec_Decode(CPpmd7 *p, UInt32 start, UInt32 size)
|
||
-{
|
||
-
|
||
-
|
||
- R->Code -= start * R->Range;
|
||
- R->Range *= size;
|
||
- RC_NORM_LOCAL(R)
|
||
-}
|
||
-
|
||
-#define RC_Decode(start, size) RangeDec_Decode(p, start, size);
|
||
-#define RC_DecodeFinal(start, size) RC_Decode(start, size) RC_NORM_REMOTE(R)
|
||
-#define RC_GetThreshold(total) (R->Code / (R->Range /= (total)))
|
||
-
|
||
-
|
||
-#define CTX(ref) ((CPpmd7_Context *)Ppmd7_GetContext(p, ref))
|
||
-typedef CPpmd7_Context * CTX_PTR;
|
||
-#define SUCCESSOR(p) Ppmd_GET_SUCCESSOR(p)
|
||
-void Ppmd7_UpdateModel(CPpmd7 *p);
|
||
-
|
||
-#define MASK(sym) ((unsigned char *)charMask)[sym]
|
||
-// MY_FORCE_INLINE
|
||
-// static
|
||
-int Ppmd7z_DecodeSymbol(CPpmd7 *p)
|
||
-{
|
||
- size_t charMask[256 / sizeof(size_t)];
|
||
-
|
||
- if (p->MinContext->NumStats != 1)
|
||
- {
|
||
- CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext);
|
||
- unsigned i;
|
||
- UInt32 count, hiCnt;
|
||
- UInt32 summFreq = p->MinContext->Union2.SummFreq;
|
||
-
|
||
-
|
||
-
|
||
-
|
||
- count = RC_GetThreshold(summFreq);
|
||
- hiCnt = count;
|
||
-
|
||
- if ((Int32)(count -= s->Freq) < 0)
|
||
- {
|
||
- Byte sym;
|
||
- RC_DecodeFinal(0, s->Freq);
|
||
- p->FoundState = s;
|
||
- sym = s->Symbol;
|
||
- Ppmd7_Update1_0(p);
|
||
- return sym;
|
||
- }
|
||
-
|
||
- p->PrevSuccess = 0;
|
||
- i = (unsigned)p->MinContext->NumStats - 1;
|
||
-
|
||
- do
|
||
- {
|
||
- if ((Int32)(count -= (++s)->Freq) < 0)
|
||
- {
|
||
- Byte sym;
|
||
- RC_DecodeFinal((hiCnt - count) - s->Freq, s->Freq);
|
||
- p->FoundState = s;
|
||
- sym = s->Symbol;
|
||
- Ppmd7_Update1(p);
|
||
- return sym;
|
||
- }
|
||
- }
|
||
- while (--i);
|
||
-
|
||
- if (hiCnt >= summFreq)
|
||
- return PPMD7_SYM_ERROR;
|
||
-
|
||
- hiCnt -= count;
|
||
- RC_Decode(hiCnt, summFreq - hiCnt);
|
||
-
|
||
- p->HiBitsFlag = PPMD7_HiBitsFlag_3(p->FoundState->Symbol);
|
||
- PPMD_SetAllBitsIn256Bytes(charMask);
|
||
- // i = p->MinContext->NumStats - 1;
|
||
- // do { MASK((--s)->Symbol) = 0; } while (--i);
|
||
- {
|
||
- CPpmd_State *s2 = Ppmd7_GetStats(p, p->MinContext);
|
||
- MASK(s->Symbol) = 0;
|
||
- do
|
||
- {
|
||
- unsigned sym0 = s2[0].Symbol;
|
||
- unsigned sym1 = s2[1].Symbol;
|
||
- s2 += 2;
|
||
- MASK(sym0) = 0;
|
||
- MASK(sym1) = 0;
|
||
- }
|
||
- while (s2 < s);
|
||
- }
|
||
- }
|
||
- else
|
||
- {
|
||
- CPpmd_State *s = Ppmd7Context_OneState(p->MinContext);
|
||
- UInt16 *prob = Ppmd7_GetBinSumm(p);
|
||
- UInt32 pr = *prob;
|
||
- UInt32 size0 = (R->Range >> 14) * pr;
|
||
- pr = PPMD_UPDATE_PROB_1(pr);
|
||
-
|
||
- if (R->Code < size0)
|
||
- {
|
||
- Byte sym;
|
||
- *prob = (UInt16)(pr + (1 << PPMD_INT_BITS));
|
||
-
|
||
- // RangeDec_DecodeBit0(size0);
|
||
- R->Range = size0;
|
||
- RC_NORM_1(R)
|
||
- /* we can use single byte normalization here because of
|
||
- (min(BinSumm[][]) = 95) > (1 << (14 - 8)) */
|
||
-
|
||
- // sym = (p->FoundState = Ppmd7Context_OneState(p->MinContext))->Symbol;
|
||
- // Ppmd7_UpdateBin(p);
|
||
- {
|
||
- unsigned freq = s->Freq;
|
||
- CTX_PTR c = CTX(SUCCESSOR(s));
|
||
- sym = s->Symbol;
|
||
- p->FoundState = s;
|
||
- p->PrevSuccess = 1;
|
||
- p->RunLength++;
|
||
- s->Freq = (Byte)(freq + (freq < 128));
|
||
- // NextContext(p);
|
||
- if (p->OrderFall == 0 && (const Byte *)c > p->Text)
|
||
- p->MaxContext = p->MinContext = c;
|
||
- else
|
||
- Ppmd7_UpdateModel(p);
|
||
- }
|
||
- return sym;
|
||
- }
|
||
-
|
||
- *prob = (UInt16)pr;
|
||
- p->InitEsc = p->ExpEscape[pr >> 10];
|
||
-
|
||
- // RangeDec_DecodeBit1(size0);
|
||
-
|
||
- R->Code -= size0;
|
||
- R->Range -= size0;
|
||
- RC_NORM_LOCAL(R)
|
||
-
|
||
- PPMD_SetAllBitsIn256Bytes(charMask);
|
||
- MASK(Ppmd7Context_OneState(p->MinContext)->Symbol) = 0;
|
||
- p->PrevSuccess = 0;
|
||
- }
|
||
-
|
||
- for (;;)
|
||
- {
|
||
- CPpmd_State *s, *s2;
|
||
- UInt32 freqSum, count, hiCnt;
|
||
-
|
||
- CPpmd_See *see;
|
||
- CPpmd7_Context *mc;
|
||
- unsigned numMasked;
|
||
- RC_NORM_REMOTE(R)
|
||
- mc = p->MinContext;
|
||
- numMasked = mc->NumStats;
|
||
-
|
||
- do
|
||
- {
|
||
- p->OrderFall++;
|
||
- if (!mc->Suffix)
|
||
- return PPMD7_SYM_END;
|
||
- mc = Ppmd7_GetContext(p, mc->Suffix);
|
||
- }
|
||
- while (mc->NumStats == numMasked);
|
||
-
|
||
- s = Ppmd7_GetStats(p, mc);
|
||
-
|
||
- {
|
||
- unsigned num = mc->NumStats;
|
||
- unsigned num2 = num / 2;
|
||
-
|
||
- num &= 1;
|
||
- hiCnt = (s->Freq & (unsigned)(MASK(s->Symbol))) & (0 - (UInt32)num);
|
||
- s += num;
|
||
- p->MinContext = mc;
|
||
-
|
||
- do
|
||
- {
|
||
- unsigned sym0 = s[0].Symbol;
|
||
- unsigned sym1 = s[1].Symbol;
|
||
- s += 2;
|
||
- hiCnt += (s[-2].Freq & (unsigned)(MASK(sym0)));
|
||
- hiCnt += (s[-1].Freq & (unsigned)(MASK(sym1)));
|
||
- }
|
||
- while (--num2);
|
||
- }
|
||
-
|
||
- see = Ppmd7_MakeEscFreq(p, numMasked, &freqSum);
|
||
- freqSum += hiCnt;
|
||
-
|
||
-
|
||
-
|
||
-
|
||
- count = RC_GetThreshold(freqSum);
|
||
-
|
||
- if (count < hiCnt)
|
||
- {
|
||
- Byte sym;
|
||
-
|
||
- s = Ppmd7_GetStats(p, p->MinContext);
|
||
- hiCnt = count;
|
||
- // count -= s->Freq & (unsigned)(MASK(s->Symbol));
|
||
- // if ((Int32)count >= 0)
|
||
- {
|
||
- for (;;)
|
||
- {
|
||
- count -= s->Freq & (unsigned)(MASK((s)->Symbol)); s++; if ((Int32)count < 0) break;
|
||
- // count -= s->Freq & (unsigned)(MASK((s)->Symbol)); s++; if ((Int32)count < 0) break;
|
||
- };
|
||
- }
|
||
- s--;
|
||
- RC_DecodeFinal((hiCnt - count) - s->Freq, s->Freq);
|
||
-
|
||
- // new (see->Summ) value can overflow over 16-bits in some rare cases
|
||
- Ppmd_See_Update(see);
|
||
- p->FoundState = s;
|
||
- sym = s->Symbol;
|
||
- Ppmd7_Update2(p);
|
||
- return sym;
|
||
- }
|
||
-
|
||
- if (count >= freqSum)
|
||
- return PPMD7_SYM_ERROR;
|
||
-
|
||
- RC_Decode(hiCnt, freqSum - hiCnt);
|
||
-
|
||
- // We increase (see->Summ) for sum of Freqs of all non_Masked symbols.
|
||
- // new (see->Summ) value can overflow over 16-bits in some rare cases
|
||
- see->Summ = (UInt16)(see->Summ + freqSum);
|
||
-
|
||
- s = Ppmd7_GetStats(p, p->MinContext);
|
||
- s2 = s + p->MinContext->NumStats;
|
||
- do
|
||
- {
|
||
- MASK(s->Symbol) = 0;
|
||
- s++;
|
||
- }
|
||
- while (s != s2);
|
||
- }
|
||
-}
|
||
-
|
||
-/*
|
||
-Byte *Ppmd7z_DecodeSymbols(CPpmd7 *p, Byte *buf, const Byte *lim)
|
||
-{
|
||
- int sym = 0;
|
||
- if (buf != lim)
|
||
- do
|
||
- {
|
||
- sym = Ppmd7z_DecodeSymbol(p);
|
||
- if (sym < 0)
|
||
- break;
|
||
- *buf = (Byte)sym;
|
||
- }
|
||
- while (++buf < lim);
|
||
- p->LastSymbol = sym;
|
||
- return buf;
|
||
-}
|
||
-*/
|
||
diff --git a/cut-n-paste/unarr/lzmasdk/Precomp.h b/cut-n-paste/unarr/lzmasdk/Precomp.h
|
||
deleted file mode 100644
|
||
index 25d8aedf..00000000
|
||
--- a/cut-n-paste/unarr/lzmasdk/Precomp.h
|
||
+++ /dev/null
|
||
@@ -1,10 +0,0 @@
|
||
-/* Precomp.h -- StdAfx
|
||
-2013-11-12 : Igor Pavlov : Public domain */
|
||
-
|
||
-#ifndef __7Z_PRECOMP_H
|
||
-#define __7Z_PRECOMP_H
|
||
-
|
||
-/* #include "Compiler.h" */
|
||
-/* #include "7zTypes.h" */
|
||
-
|
||
-#endif
|
||
diff --git a/cut-n-paste/unarr/lzmasdk/README.lzmasdk b/cut-n-paste/unarr/lzmasdk/README.lzmasdk
|
||
deleted file mode 100644
|
||
index d6051387..00000000
|
||
--- a/cut-n-paste/unarr/lzmasdk/README.lzmasdk
|
||
+++ /dev/null
|
||
@@ -1,15 +0,0 @@
|
||
-To update to the latest version of the LZMA SDK:
|
||
-1. Grab the latest version from:
|
||
- https://sourceforge.net/projects/sevenzip/files/LZMA%20SDK/
|
||
- and unpack it
|
||
-2. For the files in evince's copy/paste, copy the originals from the
|
||
- C/ sub-directory of the SDK:
|
||
- for i in *.[ch] ; do cp /tmp/lzma1803/C/$i . ; done
|
||
-3. Convert the copied files to Unix format:
|
||
- dos2unix *.[ch]
|
||
-4. Use "git add -p" to apply only the sections that are of interest
|
||
- and do not regress warning fixes (see commits a2aa919 and 5e1a0ef
|
||
- for example)
|
||
-
|
||
-Note that you might end up with an empty commit (for example 79b5fe5)
|
||
-which is fine, as long as the change is documented.
|
||
diff --git a/cut-n-paste/unarr/meson.build b/cut-n-paste/unarr/meson.build
|
||
deleted file mode 100644
|
||
index 3f148c57..00000000
|
||
--- a/cut-n-paste/unarr/meson.build
|
||
+++ /dev/null
|
||
@@ -1,28 +0,0 @@
|
||
-sources = files(
|
||
- 'common/conv.c',
|
||
- 'common/crc32.c',
|
||
- 'common/stream.c',
|
||
- 'common/unarr.c',
|
||
- 'lzmasdk/CpuArch.c',
|
||
- 'lzmasdk/Ppmd7.c',
|
||
- 'lzmasdk/Ppmd7Dec.c',
|
||
- 'rar/filter-rar.c',
|
||
- 'rar/huffman-rar.c',
|
||
- 'rar/parse-rar.c',
|
||
- 'rar/rar.c',
|
||
- 'rar/rarvm.c',
|
||
- 'rar/uncompress-rar.c',
|
||
-)
|
||
-
|
||
-libunarr = static_library(
|
||
- 'unarr',
|
||
- sources: sources,
|
||
- dependencies: zlib_dep,
|
||
- c_args: [ '-DHAVE_ZLIB', '-DNDEBUG' ],
|
||
- gnu_symbol_visibility: 'hidden',
|
||
-)
|
||
-
|
||
-libunarr_dep = declare_dependency(
|
||
- include_directories: include_directories('.'),
|
||
- link_with: libunarr,
|
||
-)
|
||
diff --git a/cut-n-paste/unarr/rar/filter-rar.c b/cut-n-paste/unarr/rar/filter-rar.c
|
||
deleted file mode 100644
|
||
index cbb2916d..00000000
|
||
--- a/cut-n-paste/unarr/rar/filter-rar.c
|
||
+++ /dev/null
|
||
@@ -1,704 +0,0 @@
|
||
-/* Copyright 2015 the unarr project authors (see AUTHORS file).
|
||
- License: LGPLv3 */
|
||
-
|
||
-#include "rar.h"
|
||
-#include "rarvm.h"
|
||
-
|
||
-/* adapted from https://code.google.com/p/theunarchiver/source/browse/XADMaster/XADRARVirtualMachine.m */
|
||
-/* adapted from https://code.google.com/p/theunarchiver/source/browse/XADMaster/XADRAR30Filter.m */
|
||
-
|
||
-struct MemBitReader {
|
||
- const uint8_t *bytes;
|
||
- size_t length;
|
||
- size_t offset;
|
||
- uint64_t bits;
|
||
- int available;
|
||
- bool at_eof;
|
||
-};
|
||
-
|
||
-struct RARProgramCode {
|
||
- RARProgram *prog;
|
||
- uint8_t *staticdata;
|
||
- uint32_t staticdatalen;
|
||
- uint8_t *globalbackup;
|
||
- uint32_t globalbackuplen;
|
||
- uint64_t fingerprint;
|
||
- uint32_t usagecount;
|
||
- uint32_t oldfilterlength;
|
||
- struct RARProgramCode *next;
|
||
-};
|
||
-
|
||
-struct RARFilter {
|
||
- struct RARProgramCode *prog;
|
||
- uint32_t initialregisters[8];
|
||
- uint8_t *globaldata;
|
||
- uint32_t globaldatalen;
|
||
- size_t blockstartpos;
|
||
- uint32_t blocklength;
|
||
- uint32_t filteredblockaddress;
|
||
- uint32_t filteredblocklength;
|
||
- struct RARFilter *next;
|
||
-};
|
||
-
|
||
-static bool br_fill(struct MemBitReader *br, int bits)
|
||
-{
|
||
- while (br->available < bits && br->offset < br->length) {
|
||
- br->bits = (br->bits << 8) | br->bytes[br->offset++];
|
||
- br->available += 8;
|
||
- }
|
||
- if (bits > br->available) {
|
||
- br->at_eof = true;
|
||
- return false;
|
||
- }
|
||
- return true;
|
||
-}
|
||
-
|
||
-static inline uint32_t br_bits(struct MemBitReader *br, int bits)
|
||
-{
|
||
- if (bits > br->available && (br->at_eof || !br_fill(br, bits)))
|
||
- return 0;
|
||
- return (uint32_t)((br->bits >> (br->available -= bits)) & (((uint64_t)1 << bits) - 1));
|
||
-}
|
||
-
|
||
-static inline bool br_available(struct MemBitReader *br, int bits)
|
||
-{
|
||
- return !br->at_eof && (bits <= br->available || br_fill(br, bits));
|
||
-}
|
||
-
|
||
-static uint32_t br_next_rarvm_number(struct MemBitReader *br)
|
||
-{
|
||
- uint32_t val;
|
||
- switch (br_bits(br, 2)) {
|
||
- case 0:
|
||
- return br_bits(br, 4);
|
||
- case 1:
|
||
- val = br_bits(br, 8);
|
||
- if (val >= 16)
|
||
- return val;
|
||
- return 0xFFFFFF00 | (val << 4) | br_bits(br, 4);
|
||
- case 2:
|
||
- return br_bits(br, 16);
|
||
- default:
|
||
- return br_bits(br, 32);
|
||
- }
|
||
-}
|
||
-
|
||
-static void bw_write32le(uint8_t *dst, uint32_t value)
|
||
-{
|
||
- dst[0] = value & 0xFF;
|
||
- dst[1] = (value >> 8) & 0xFF;
|
||
- dst[2] = (value >> 16) & 0xFF;
|
||
- dst[3] = (value >> 24) & 0xFF;
|
||
-}
|
||
-
|
||
-static void rar_delete_program(struct RARProgramCode *prog)
|
||
-{
|
||
- while (prog) {
|
||
- struct RARProgramCode *next = prog->next;
|
||
- RARDeleteProgram(prog->prog);
|
||
- free(prog->staticdata);
|
||
- free(prog->globalbackup);
|
||
- free(prog);
|
||
- prog = next;
|
||
- }
|
||
-}
|
||
-
|
||
-static bool rar_parse_operand(struct MemBitReader *br, uint8_t instruction, bool bytemode, uint32_t instrcount, uint8_t *addressmode, uint32_t *value)
|
||
-{
|
||
- if (br_bits(br, 1)) {
|
||
- *addressmode = RARRegisterAddressingMode((uint8_t)br_bits(br, 3));
|
||
- *value = 0;
|
||
- }
|
||
- else if (br_bits(br, 1)) {
|
||
- if (br_bits(br, 1)) {
|
||
- if (br_bits(br, 1))
|
||
- *addressmode = RARAbsoluteAddressingMode;
|
||
- else
|
||
- *addressmode = RARIndexedAbsoluteAddressingMode((uint8_t)br_bits(br, 3));
|
||
- *value = br_next_rarvm_number(br);
|
||
- }
|
||
- else {
|
||
- *addressmode = RARRegisterIndirectAddressingMode((uint8_t)br_bits(br, 3));
|
||
- *value = 0;
|
||
- }
|
||
- }
|
||
- else {
|
||
- *addressmode = RARImmediateAddressingMode;
|
||
- if (!bytemode)
|
||
- *value = br_next_rarvm_number(br);
|
||
- else
|
||
- *value = br_bits(br, 8);
|
||
- if (instrcount != (uint32_t)-1 && RARInstructionIsRelativeJump(instruction)) {
|
||
- if (*value >= 256) /* absolute address */
|
||
- *value -= 256;
|
||
- else { /* relative address */
|
||
- if (*value >= 136)
|
||
- *value -= 264;
|
||
- else if (*value >= 16)
|
||
- *value -= 8;
|
||
- else if (*value >= 8)
|
||
- *value -= 16;
|
||
- *value += instrcount;
|
||
- }
|
||
- }
|
||
- }
|
||
- return !br->at_eof;
|
||
-}
|
||
-
|
||
-static struct RARProgramCode *rar_compile_program(const uint8_t *bytes, size_t length)
|
||
-{
|
||
- struct MemBitReader br = { 0 };
|
||
- struct RARProgramCode *prog;
|
||
- uint32_t instrcount = 0;
|
||
- uint8_t xor;
|
||
- size_t i;
|
||
-
|
||
- xor = 0;
|
||
- for (i = 1; i < length; i++)
|
||
- xor ^= bytes[i];
|
||
- if (!length || xor != bytes[0])
|
||
- return NULL;
|
||
-
|
||
- br.bytes = bytes;
|
||
- br.length = length;
|
||
- br.offset = 1;
|
||
-
|
||
- prog = calloc(1, sizeof(*prog));
|
||
- if (!prog)
|
||
- return NULL;
|
||
- prog->prog = RARCreateProgram();
|
||
- if (!prog->prog) {
|
||
- rar_delete_program(prog);
|
||
- return NULL;
|
||
- }
|
||
- prog->fingerprint = ar_crc32(0, bytes, length) | ((uint64_t)length << 32);
|
||
-
|
||
- if (br_bits(&br, 1)) {
|
||
- prog->staticdatalen = br_next_rarvm_number(&br) + 1;
|
||
- prog->staticdata = malloc(prog->staticdatalen);
|
||
- if (!prog->staticdata) {
|
||
- rar_delete_program(prog);
|
||
- return NULL;
|
||
- }
|
||
- for (i = 0; i < prog->staticdatalen; i++)
|
||
- prog->staticdata[i] = (uint8_t)br_bits(&br, 8);
|
||
- }
|
||
-
|
||
- while (br_available(&br, 8)) {
|
||
- bool ok = true;
|
||
- uint8_t instruction = (uint8_t)br_bits(&br, 4);
|
||
- bool bytemode = false;
|
||
- int numargs = 0;
|
||
- uint8_t addrmode1 = 0, addrmode2 = 0;
|
||
- uint32_t value1 = 0, value2 = 0;
|
||
-
|
||
- if ((instruction & 0x08))
|
||
- instruction = ((instruction << 2) | (uint8_t)br_bits(&br, 2)) - 24;
|
||
- if (RARInstructionHasByteMode(instruction))
|
||
- bytemode = br_bits(&br, 1) != 0;
|
||
- ok = RARProgramAddInstr(prog->prog, instruction, bytemode);
|
||
- numargs = NumberOfRARInstructionOperands(instruction);
|
||
- if (ok && numargs >= 1)
|
||
- ok = rar_parse_operand(&br, instruction, bytemode, instrcount, &addrmode1, &value1);
|
||
- if (ok && numargs == 2)
|
||
- ok = rar_parse_operand(&br, instruction, bytemode, (uint32_t)-1, &addrmode2, &value2);
|
||
- if (ok)
|
||
- ok = RARSetLastInstrOperands(prog->prog, addrmode1, value1, addrmode2, value2);
|
||
- if (!ok) {
|
||
- warn("Invalid RAR program instruction");
|
||
- rar_delete_program(prog);
|
||
- return NULL;
|
||
- }
|
||
- instrcount++;
|
||
- }
|
||
-
|
||
- if (!RARIsProgramTerminated(prog->prog)) {
|
||
- if (!RARProgramAddInstr(prog->prog, RARRetInstruction, false)) {
|
||
- rar_delete_program(prog);
|
||
- return NULL;
|
||
- }
|
||
- }
|
||
-
|
||
- return prog;
|
||
-}
|
||
-
|
||
-static bool rar_execute_filter_prog(struct RARFilter *filter, RARVirtualMachine *vm)
|
||
-{
|
||
- uint32_t newgloballength;
|
||
- uint32_t globallength = filter->globaldatalen;
|
||
- if (globallength > RARProgramSystemGlobalSize)
|
||
- globallength = RARProgramSystemGlobalSize;
|
||
- memcpy(&vm->memory[RARProgramSystemGlobalAddress], filter->globaldata, globallength);
|
||
- if (filter->prog->staticdata) {
|
||
- uint32_t staticlength = filter->prog->staticdatalen;
|
||
- if (staticlength > RARProgramUserGlobalSize - globallength)
|
||
- staticlength = RARProgramUserGlobalSize - globallength;
|
||
- memcpy(&vm->memory[RARProgramUserGlobalAddress], filter->prog->staticdata, staticlength);
|
||
- }
|
||
- RARSetVirtualMachineRegisters(vm, filter->initialregisters);
|
||
-
|
||
- if (!RARExecuteProgram(vm, filter->prog->prog)) {
|
||
- warn("Error while executing program in RAR VM");
|
||
- return false;
|
||
- }
|
||
-
|
||
- newgloballength = RARVirtualMachineRead32(vm, RARProgramSystemGlobalAddress + 0x30);
|
||
- if (newgloballength > RARProgramUserGlobalSize)
|
||
- newgloballength = RARProgramUserGlobalSize;
|
||
- if (newgloballength > 0) {
|
||
- uint32_t newglobaldatalength = RARProgramSystemGlobalSize + newgloballength;
|
||
- if (newglobaldatalength > filter->globaldatalen) {
|
||
- uint8_t *newglobaldata = malloc(newglobaldatalength);
|
||
- if (!newglobaldata)
|
||
- return false;
|
||
- free(filter->globaldata);
|
||
- filter->globaldata = newglobaldata;
|
||
- }
|
||
- filter->globaldatalen = newglobaldatalength;
|
||
- memcpy(filter->globaldata, &vm->memory[RARProgramSystemGlobalAddress], filter->globaldatalen);
|
||
- }
|
||
- else
|
||
- filter->globaldatalen = 0;
|
||
-
|
||
- return true;
|
||
-}
|
||
-
|
||
-static struct RARFilter *rar_create_filter(struct RARProgramCode *prog, const uint8_t *globaldata, uint32_t globaldatalen, uint32_t registers[8], size_t startpos, uint32_t length)
|
||
-{
|
||
- struct RARFilter *filter;
|
||
-
|
||
- filter = calloc(1, sizeof(*filter));
|
||
- if (!filter)
|
||
- return NULL;
|
||
- filter->prog = prog;
|
||
- filter->globaldatalen = globaldatalen > RARProgramSystemGlobalSize ? globaldatalen : RARProgramSystemGlobalSize;
|
||
- filter->globaldata = calloc(1, filter->globaldatalen);
|
||
- if (!filter->globaldata)
|
||
- return NULL;
|
||
- if (globaldata)
|
||
- memcpy(filter->globaldata, globaldata, globaldatalen);
|
||
- if (registers)
|
||
- memcpy(filter->initialregisters, registers, sizeof(filter->initialregisters));
|
||
- filter->blockstartpos = startpos;
|
||
- filter->blocklength = length;
|
||
-
|
||
- return filter;
|
||
-}
|
||
-
|
||
-static void rar_delete_filter(struct RARFilter *filter)
|
||
-{
|
||
- while (filter) {
|
||
- struct RARFilter *next = filter->next;
|
||
- free(filter->globaldata);
|
||
- free(filter);
|
||
- filter = next;
|
||
- }
|
||
-}
|
||
-
|
||
-static bool rar_execute_filter_delta(struct RARFilter *filter, RARVirtualMachine *vm)
|
||
-{
|
||
- uint32_t length = filter->initialregisters[4];
|
||
- uint32_t numchannels = filter->initialregisters[0];
|
||
- uint8_t *src, *dst;
|
||
- uint32_t i, idx;
|
||
-
|
||
- if (length > RARProgramWorkSize / 2)
|
||
- return false;
|
||
-
|
||
- src = &vm->memory[0];
|
||
- dst = &vm->memory[length];
|
||
- for (i = 0; i < numchannels; i++) {
|
||
- uint8_t lastbyte = 0;
|
||
- for (idx = i; idx < length; idx += numchannels)
|
||
- lastbyte = dst[idx] = lastbyte - *src++;
|
||
- }
|
||
-
|
||
- filter->filteredblockaddress = length;
|
||
- filter->filteredblocklength = length;
|
||
-
|
||
- return true;
|
||
-}
|
||
-
|
||
-static bool rar_execute_filter_e8(struct RARFilter *filter, RARVirtualMachine *vm, size_t pos, bool e9also)
|
||
-{
|
||
- uint32_t length = filter->initialregisters[4];
|
||
- uint32_t filesize = 0x1000000;
|
||
- uint32_t i;
|
||
-
|
||
- if (length > RARProgramWorkSize || length < 4)
|
||
- return false;
|
||
-
|
||
- for (i = 0; i <= length - 5; i++) {
|
||
- if (vm->memory[i] == 0xE8 || (e9also && vm->memory[i] == 0xE9)) {
|
||
- uint32_t currpos = (uint32_t)pos + i + 1;
|
||
- int32_t address = (int32_t)RARVirtualMachineRead32(vm, i + 1);
|
||
- if (address < 0 && currpos >= (uint32_t)-address)
|
||
- RARVirtualMachineWrite32(vm, i + 1, address + filesize);
|
||
- else if (address >= 0 && (uint32_t)address < filesize)
|
||
- RARVirtualMachineWrite32(vm, i + 1, address - currpos);
|
||
- i += 4;
|
||
- }
|
||
- }
|
||
-
|
||
- filter->filteredblockaddress = 0;
|
||
- filter->filteredblocklength = length;
|
||
-
|
||
- return true;
|
||
-}
|
||
-
|
||
-static bool rar_execute_filter_rgb(struct RARFilter *filter, RARVirtualMachine *vm)
|
||
-{
|
||
- uint32_t stride = filter->initialregisters[0];
|
||
- uint32_t byteoffset = filter->initialregisters[1];
|
||
- uint32_t blocklength = filter->initialregisters[4];
|
||
- uint8_t *src, *dst;
|
||
- uint32_t i, j;
|
||
-
|
||
- if (blocklength > RARProgramWorkSize / 2 || stride > blocklength)
|
||
- return false;
|
||
-
|
||
- src = &vm->memory[0];
|
||
- dst = &vm->memory[blocklength];
|
||
- for (i = 0; i < 3; i++) {
|
||
- uint8_t byte = 0;
|
||
- uint8_t *prev = dst + i - stride;
|
||
- for (j = i; j < blocklength; j += 3) {
|
||
- if (prev >= dst) {
|
||
- uint32_t delta1 = abs(prev[3] - prev[0]);
|
||
- uint32_t delta2 = abs(byte - prev[0]);
|
||
- uint32_t delta3 = abs(prev[3] - prev[0] + byte - prev[0]);
|
||
- if (delta1 > delta2 || delta1 > delta3)
|
||
- byte = delta2 <= delta3 ? prev[3] : prev[0];
|
||
- }
|
||
- byte -= *src++;
|
||
- dst[j] = byte;
|
||
- prev += 3;
|
||
- }
|
||
- }
|
||
- for (i = byteoffset; i < blocklength - 2; i += 3) {
|
||
- dst[i] += dst[i + 1];
|
||
- dst[i + 2] += dst[i + 1];
|
||
- }
|
||
-
|
||
- filter->filteredblockaddress = blocklength;
|
||
- filter->filteredblocklength = blocklength;
|
||
-
|
||
- return true;
|
||
-}
|
||
-
|
||
-static bool rar_execute_filter_audio(struct RARFilter *filter, RARVirtualMachine *vm)
|
||
-{
|
||
- uint32_t length = filter->initialregisters[4];
|
||
- uint32_t numchannels = filter->initialregisters[0];
|
||
- uint8_t *src, *dst;
|
||
- uint32_t i, j;
|
||
-
|
||
- if (length > RARProgramWorkSize / 2)
|
||
- return false;
|
||
-
|
||
- src = &vm->memory[0];
|
||
- dst = &vm->memory[length];
|
||
- for (i = 0; i < numchannels; i++) {
|
||
- struct AudioState state;
|
||
- memset(&state, 0, sizeof(state));
|
||
- for (j = i; j < length; j += numchannels) {
|
||
- int8_t delta = (int8_t)*src++;
|
||
- uint8_t predbyte, byte;
|
||
- int prederror;
|
||
- state.delta[2] = state.delta[1];
|
||
- state.delta[1] = state.lastdelta - state.delta[0];
|
||
- state.delta[0] = state.lastdelta;
|
||
- predbyte = ((8 * state.lastbyte + state.weight[0] * state.delta[0] + state.weight[1] * state.delta[1] + state.weight[2] * state.delta[2]) >> 3) & 0xFF;
|
||
- byte = (predbyte - delta) & 0xFF;
|
||
- prederror = delta << 3;
|
||
- state.error[0] += abs(prederror);
|
||
- state.error[1] += abs(prederror - state.delta[0]); state.error[2] += abs(prederror + state.delta[0]);
|
||
- state.error[3] += abs(prederror - state.delta[1]); state.error[4] += abs(prederror + state.delta[1]);
|
||
- state.error[5] += abs(prederror - state.delta[2]); state.error[6] += abs(prederror + state.delta[2]);
|
||
- state.lastdelta = (int8_t)(byte - state.lastbyte);
|
||
- dst[j] = state.lastbyte = byte;
|
||
- if (!(state.count++ & 0x1F)) {
|
||
- uint8_t k, idx = 0;
|
||
- for (k = 1; k < 7; k++) {
|
||
- if (state.error[k] < state.error[idx])
|
||
- idx = k;
|
||
- }
|
||
- memset(state.error, 0, sizeof(state.error));
|
||
- switch (idx) {
|
||
- case 1: if (state.weight[0] >= -16) state.weight[0]--; break;
|
||
- case 2: if (state.weight[0] < 16) state.weight[0]++; break;
|
||
- case 3: if (state.weight[1] >= -16) state.weight[1]--; break;
|
||
- case 4: if (state.weight[1] < 16) state.weight[1]++; break;
|
||
- case 5: if (state.weight[2] >= -16) state.weight[2]--; break;
|
||
- case 6: if (state.weight[2] < 16) state.weight[2]++; break;
|
||
- }
|
||
- }
|
||
- }
|
||
- }
|
||
-
|
||
- filter->filteredblockaddress = length;
|
||
- filter->filteredblocklength = length;
|
||
-
|
||
- return true;
|
||
-}
|
||
-
|
||
-static bool rar_execute_filter(struct RARFilter *filter, RARVirtualMachine *vm, size_t pos)
|
||
-{
|
||
- if (filter->prog->fingerprint == 0x1D0E06077D)
|
||
- return rar_execute_filter_delta(filter, vm);
|
||
- if (filter->prog->fingerprint == 0x35AD576887)
|
||
- return rar_execute_filter_e8(filter, vm, pos, false);
|
||
- if (filter->prog->fingerprint == 0x393CD7E57E)
|
||
- return rar_execute_filter_e8(filter, vm, pos, true);
|
||
- if (filter->prog->fingerprint == 0x951C2C5DC8)
|
||
- return rar_execute_filter_rgb(filter, vm);
|
||
- if (filter->prog->fingerprint == 0xD8BC85E701)
|
||
- return rar_execute_filter_audio(filter, vm);
|
||
- log("Unknown parsing filter 0x%x%08x", (uint32_t)(filter->prog->fingerprint >> 32), (uint32_t)filter->prog->fingerprint);
|
||
-
|
||
- /* XADRAR30Filter.m @executeOnVirtualMachine claims that this is required */
|
||
- if (filter->prog->globalbackuplen > RARProgramSystemGlobalSize) {
|
||
- uint8_t *newglobaldata = malloc(filter->prog->globalbackuplen);
|
||
- if (newglobaldata) {
|
||
- free(filter->globaldata);
|
||
- filter->globaldata = newglobaldata;
|
||
- filter->globaldatalen = filter->prog->globalbackuplen;
|
||
- memcpy(filter->globaldata, filter->prog->globalbackup, filter->prog->globalbackuplen);
|
||
- }
|
||
- }
|
||
-
|
||
- filter->initialregisters[6] = (uint32_t)pos;
|
||
- bw_write32le(&filter->globaldata[0x24], (uint32_t)pos);
|
||
- bw_write32le(&filter->globaldata[0x28], (uint32_t)((uint64_t)pos >> 32));
|
||
-
|
||
- if (!rar_execute_filter_prog(filter, vm))
|
||
- return false;
|
||
-
|
||
- filter->filteredblockaddress = RARVirtualMachineRead32(vm, RARProgramSystemGlobalAddress + 0x20) & RARProgramMemoryMask;
|
||
- filter->filteredblocklength = RARVirtualMachineRead32(vm, RARProgramSystemGlobalAddress + 0x1C) & RARProgramMemoryMask;
|
||
- if (filter->filteredblockaddress + filter->filteredblocklength >= RARProgramMemorySize) {
|
||
- filter->filteredblockaddress = filter->filteredblocklength = 0;
|
||
- return false;
|
||
- }
|
||
-
|
||
- if (filter->globaldatalen > RARProgramSystemGlobalSize) {
|
||
- uint8_t *newglobalbackup = malloc(filter->globaldatalen);
|
||
- if (newglobalbackup) {
|
||
- free(filter->prog->globalbackup);
|
||
- filter->prog->globalbackup = newglobalbackup;
|
||
- filter->prog->globalbackuplen = filter->globaldatalen;
|
||
- memcpy(filter->prog->globalbackup, filter->globaldata, filter->globaldatalen);
|
||
- }
|
||
- }
|
||
- else
|
||
- filter->prog->globalbackuplen = 0;
|
||
-
|
||
- return true;
|
||
-}
|
||
-
|
||
-bool rar_parse_filter(ar_archive_rar *rar, const uint8_t *bytes, uint16_t length, uint8_t flags)
|
||
-{
|
||
- struct ar_archive_rar_uncomp_v3 *uncomp = &rar->uncomp.state.v3;
|
||
- struct ar_archive_rar_filters *filters = &uncomp->filters;
|
||
-
|
||
- struct MemBitReader br = { 0 };
|
||
- struct RARProgramCode *prog;
|
||
- struct RARFilter *filter, **nextfilter;
|
||
-
|
||
- uint32_t numprogs, num, blocklength, globaldatalen;
|
||
- uint8_t *globaldata;
|
||
- size_t blockstartpos;
|
||
- uint32_t registers[8] = { 0 };
|
||
- uint32_t i;
|
||
-
|
||
- br.bytes = bytes;
|
||
- br.length = length;
|
||
-
|
||
- numprogs = 0;
|
||
- for (prog = filters->progs; prog; prog = prog->next)
|
||
- numprogs++;
|
||
-
|
||
- if ((flags & 0x80)) {
|
||
- num = br_next_rarvm_number(&br);
|
||
- if (num == 0) {
|
||
- rar_delete_filter(filters->stack);
|
||
- filters->stack = NULL;
|
||
- rar_delete_program(filters->progs);
|
||
- filters->progs = NULL;
|
||
- }
|
||
- else
|
||
- num--;
|
||
- if (num > numprogs) {
|
||
- warn("Invalid program number");
|
||
- return false;
|
||
- }
|
||
- filters->lastfilternum = num;
|
||
- }
|
||
- else
|
||
- num = filters->lastfilternum;
|
||
-
|
||
- prog = filters->progs;
|
||
- for (i = 0; i < num; i++)
|
||
- prog = prog->next;
|
||
- if (prog)
|
||
- prog->usagecount++;
|
||
-
|
||
- blockstartpos = br_next_rarvm_number(&br) + (size_t)lzss_position(&rar->uncomp.lzss);
|
||
- if ((flags & 0x40))
|
||
- blockstartpos += 258;
|
||
- if ((flags & 0x20))
|
||
- blocklength = br_next_rarvm_number(&br);
|
||
- else
|
||
- blocklength = prog ? prog->oldfilterlength : 0;
|
||
-
|
||
- registers[3] = RARProgramSystemGlobalAddress;
|
||
- registers[4] = blocklength;
|
||
- registers[5] = prog ? prog->usagecount : 0;
|
||
- registers[7] = RARProgramMemorySize;
|
||
-
|
||
- if ((flags & 0x10)) {
|
||
- uint8_t mask = (uint8_t)br_bits(&br, 7);
|
||
- for (i = 0; i < 7; i++) {
|
||
- if ((mask & (1 << i)))
|
||
- registers[i] = br_next_rarvm_number(&br);
|
||
- }
|
||
- }
|
||
-
|
||
- if (!prog) {
|
||
- uint32_t len = br_next_rarvm_number(&br);
|
||
- uint8_t *bytecode;
|
||
- struct RARProgramCode **next;
|
||
-
|
||
- if (len == 0 || len > 0x10000) {
|
||
- warn("Invalid RARVM bytecode length");
|
||
- return false;
|
||
- }
|
||
- bytecode = malloc(len);
|
||
- if (!bytecode)
|
||
- return false;
|
||
- for (i = 0; i < len; i++)
|
||
- bytecode[i] = (uint8_t)br_bits(&br, 8);
|
||
- prog = rar_compile_program(bytecode, len);
|
||
- if (!prog) {
|
||
- free(bytecode);
|
||
- return false;
|
||
- }
|
||
- free(bytecode);
|
||
- next = &filters->progs;
|
||
- while (*next)
|
||
- next = &(*next)->next;
|
||
- *next = prog;
|
||
- }
|
||
- prog->oldfilterlength = blocklength;
|
||
-
|
||
- globaldata = NULL;
|
||
- globaldatalen = 0;
|
||
- if ((flags & 0x08)) {
|
||
- globaldatalen = br_next_rarvm_number(&br);
|
||
- if (globaldatalen > RARProgramUserGlobalSize) {
|
||
- warn("Invalid RARVM data length");
|
||
- return false;
|
||
- }
|
||
- globaldata = malloc(globaldatalen + RARProgramSystemGlobalSize);
|
||
- if (!globaldata)
|
||
- return false;
|
||
- for (i = 0; i < globaldatalen; i++)
|
||
- globaldata[i + RARProgramSystemGlobalSize] = (uint8_t)br_bits(&br, 8);
|
||
- }
|
||
-
|
||
- if (br.at_eof) {
|
||
- free(globaldata);
|
||
- return false;
|
||
- }
|
||
-
|
||
- filter = rar_create_filter(prog, globaldata, globaldatalen, registers, blockstartpos, blocklength);
|
||
- free(globaldata);
|
||
- if (!filter)
|
||
- return false;
|
||
-
|
||
- for (i = 0; i < 7; i++)
|
||
- bw_write32le(&filter->globaldata[i * 4], registers[i]);
|
||
- bw_write32le(&filter->globaldata[0x1C], blocklength);
|
||
- bw_write32le(&filter->globaldata[0x20], 0);
|
||
- bw_write32le(&filter->globaldata[0x2C], prog->usagecount);
|
||
-
|
||
- nextfilter = &filters->stack;
|
||
- while (*nextfilter)
|
||
- nextfilter = &(*nextfilter)->next;
|
||
- *nextfilter = filter;
|
||
-
|
||
- if (!filters->stack->next)
|
||
- filters->filterstart = blockstartpos;
|
||
-
|
||
- return true;
|
||
-}
|
||
-
|
||
-bool rar_run_filters(ar_archive_rar *rar)
|
||
-{
|
||
- struct ar_archive_rar_filters *filters = &rar->uncomp.state.v3.filters;
|
||
- struct RARFilter *filter = filters->stack;
|
||
- size_t start = filters->filterstart;
|
||
- size_t end = start + filter->blocklength;
|
||
- uint32_t lastfilteraddress;
|
||
- uint32_t lastfilterlength;
|
||
-
|
||
- filters->filterstart = SIZE_MAX;
|
||
- end = (size_t)rar_expand(rar, end);
|
||
- if (end != start + filter->blocklength) {
|
||
- warn("Failed to expand the expected amout of bytes");
|
||
- return false;
|
||
- }
|
||
-
|
||
- if (!filters->vm) {
|
||
- filters->vm = calloc(1, sizeof(*filters->vm));
|
||
- if (!filters->vm)
|
||
- return false;
|
||
- }
|
||
-
|
||
- lzss_copy_bytes_from_window(&rar->uncomp.lzss, filters->vm->memory, start, filter->blocklength);
|
||
- if (!rar_execute_filter(filter, filters->vm, rar->progress.bytes_done)) {
|
||
- warn("Failed to execute parsing filter");
|
||
- return false;
|
||
- }
|
||
-
|
||
- lastfilteraddress = filter->filteredblockaddress;
|
||
- lastfilterlength = filter->filteredblocklength;
|
||
- filters->stack = filter->next;
|
||
- filter->next = NULL;
|
||
- rar_delete_filter(filter);
|
||
-
|
||
- while ((filter = filters->stack) != NULL && filter->blockstartpos == filters->filterstart && filter->blocklength == lastfilterlength) {
|
||
- memmove(&filters->vm->memory[0], &filters->vm->memory[lastfilteraddress], lastfilterlength);
|
||
- if (!rar_execute_filter(filter, filters->vm, rar->progress.bytes_done)) {
|
||
- warn("Failed to execute parsing filter");
|
||
- return false;
|
||
- }
|
||
-
|
||
- lastfilteraddress = filter->filteredblockaddress;
|
||
- lastfilterlength = filter->filteredblocklength;
|
||
- filters->stack = filter->next;
|
||
- filter->next = NULL;
|
||
- rar_delete_filter(filter);
|
||
- }
|
||
-
|
||
- if (filters->stack) {
|
||
- if (filters->stack->blockstartpos < end) {
|
||
- warn("Bad filter order");
|
||
- return false;
|
||
- }
|
||
- filters->filterstart = filters->stack->blockstartpos;
|
||
- }
|
||
-
|
||
- filters->lastend = end;
|
||
- filters->bytes = &filters->vm->memory[lastfilteraddress];
|
||
- filters->bytes_ready = lastfilterlength;
|
||
-
|
||
- return true;
|
||
-}
|
||
-
|
||
-void rar_clear_filters(struct ar_archive_rar_filters *filters)
|
||
-{
|
||
- rar_delete_filter(filters->stack);
|
||
- rar_delete_program(filters->progs);
|
||
- free(filters->vm);
|
||
-}
|
||
diff --git a/cut-n-paste/unarr/rar/huffman-rar.c b/cut-n-paste/unarr/rar/huffman-rar.c
|
||
deleted file mode 100644
|
||
index c77eed93..00000000
|
||
--- a/cut-n-paste/unarr/rar/huffman-rar.c
|
||
+++ /dev/null
|
||
@@ -1,142 +0,0 @@
|
||
-/* Copyright 2015 the unarr project authors (see AUTHORS file).
|
||
- License: LGPLv3 */
|
||
-
|
||
-/* adapted from https://code.google.com/p/theunarchiver/source/browse/XADMaster/XADPrefixCode.m */
|
||
-
|
||
-#include "rar.h"
|
||
-
|
||
-bool rar_new_node(struct huffman_code *code)
|
||
-{
|
||
- if (!code->tree) {
|
||
- code->minlength = INT_MAX;
|
||
- code->maxlength = INT_MIN;
|
||
- }
|
||
- if (code->numentries + 1 >= code->capacity) {
|
||
- /* in my small file sample, 1024 is the value needed most often */
|
||
- int new_capacity = code->capacity ? code->capacity * 2 : 1024;
|
||
- void *new_tree = calloc(new_capacity, sizeof(*code->tree));
|
||
- if (!new_tree) {
|
||
- warn("OOM during decompression");
|
||
- return false;
|
||
- }
|
||
- memcpy(new_tree, code->tree, code->capacity * sizeof(*code->tree));
|
||
- free(code->tree);
|
||
- code->tree = new_tree;
|
||
- code->capacity = new_capacity;
|
||
- }
|
||
- code->tree[code->numentries].branches[0] = -1;
|
||
- code->tree[code->numentries].branches[1] = -2;
|
||
- code->numentries++;
|
||
- return true;
|
||
-}
|
||
-
|
||
-bool rar_add_value(struct huffman_code *code, int value, int codebits, int length)
|
||
-{
|
||
- int lastnode, bitpos, bit;
|
||
-
|
||
- free(code->table);
|
||
- code->table = NULL;
|
||
-
|
||
- if (length > code->maxlength)
|
||
- code->maxlength = length;
|
||
- if (length < code->minlength)
|
||
- code->minlength = length;
|
||
-
|
||
- lastnode = 0;
|
||
- for (bitpos = length - 1; bitpos >= 0; bitpos--) {
|
||
- bit = (codebits >> bitpos) & 1;
|
||
- if (rar_is_leaf_node(code, lastnode)) {
|
||
- warn("Invalid data in bitstream"); /* prefix found */
|
||
- return false;
|
||
- }
|
||
- if (code->tree[lastnode].branches[bit] < 0) {
|
||
- if (!rar_new_node(code))
|
||
- return false;
|
||
- code->tree[lastnode].branches[bit] = code->numentries - 1;
|
||
- }
|
||
- lastnode = code->tree[lastnode].branches[bit];
|
||
- }
|
||
-
|
||
- if (code->tree[lastnode].branches[0] != -1 || code->tree[lastnode].branches[1] != -2) {
|
||
- warn("Invalid data in bitstream"); /* prefix found */
|
||
- return false;
|
||
- }
|
||
- code->tree[lastnode].branches[0] = code->tree[lastnode].branches[1] = value;
|
||
- return true;
|
||
-}
|
||
-
|
||
-bool rar_create_code(struct huffman_code *code, uint8_t *lengths, int numsymbols)
|
||
-{
|
||
- int symbolsleft = numsymbols;
|
||
- int codebits = 0;
|
||
- int i, j;
|
||
-
|
||
- if (!rar_new_node(code))
|
||
- return false;
|
||
-
|
||
- for (i = 1; i <= 0x0F; i++) {
|
||
- for (j = 0; j < numsymbols; j++) {
|
||
- if (lengths[j] != i)
|
||
- continue;
|
||
- if (!rar_add_value(code, j, codebits, i))
|
||
- return false;
|
||
- if (--symbolsleft <= 0)
|
||
- return true;
|
||
- codebits++;
|
||
- }
|
||
- codebits <<= 1;
|
||
- }
|
||
- return true;
|
||
-}
|
||
-
|
||
-static bool rar_make_table_rec(struct huffman_code *code, int node, int offset, int depth, int maxdepth)
|
||
-{
|
||
- int currtablesize = 1 << (maxdepth - depth);
|
||
-
|
||
- if (node < 0 || code->numentries <= node) {
|
||
- warn("Invalid data in bitstream"); /* invalid location to Huffman tree specified */
|
||
- return false;
|
||
- }
|
||
-
|
||
- if (rar_is_leaf_node(code, node)) {
|
||
- int i;
|
||
- for (i = 0; i < currtablesize; i++) {
|
||
- code->table[offset + i].length = depth;
|
||
- code->table[offset + i].value = code->tree[node].branches[0];
|
||
- }
|
||
- }
|
||
- else if (depth == maxdepth) {
|
||
- code->table[offset].length = maxdepth + 1;
|
||
- code->table[offset].value = node;
|
||
- }
|
||
- else {
|
||
- if (!rar_make_table_rec(code, code->tree[node].branches[0], offset, depth + 1, maxdepth))
|
||
- return false;
|
||
- if (!rar_make_table_rec(code, code->tree[node].branches[1], offset + currtablesize / 2, depth + 1, maxdepth))
|
||
- return false;
|
||
- }
|
||
- return true;
|
||
-}
|
||
-
|
||
-bool rar_make_table(struct huffman_code *code)
|
||
-{
|
||
- if (code->minlength <= code->maxlength && code->maxlength <= 10)
|
||
- code->tablesize = code->maxlength;
|
||
- else
|
||
- code->tablesize = 10;
|
||
-
|
||
- code->table = calloc(1ULL << code->tablesize, sizeof(*code->table));
|
||
- if (!code->table) {
|
||
- warn("OOM during decompression");
|
||
- return false;
|
||
- }
|
||
-
|
||
- return rar_make_table_rec(code, 0, 0, 0, code->tablesize);
|
||
-}
|
||
-
|
||
-void rar_free_code(struct huffman_code *code)
|
||
-{
|
||
- free(code->tree);
|
||
- free(code->table);
|
||
- memset(code, 0, sizeof(*code));
|
||
-}
|
||
diff --git a/cut-n-paste/unarr/rar/lzss.h b/cut-n-paste/unarr/rar/lzss.h
|
||
deleted file mode 100644
|
||
index 580fe4c5..00000000
|
||
--- a/cut-n-paste/unarr/rar/lzss.h
|
||
+++ /dev/null
|
||
@@ -1,88 +0,0 @@
|
||
-/* Copyright 2015 the unarr project authors (see AUTHORS file).
|
||
- License: LGPLv3 */
|
||
-
|
||
-/* adapted from https://code.google.com/p/theunarchiver/source/browse/XADMaster/LZSS.h */
|
||
-
|
||
-#ifndef rar_lzss_h
|
||
-#define rar_lzss_h
|
||
-
|
||
-#include <stdlib.h>
|
||
-#include <stdint.h>
|
||
-#include <stdbool.h>
|
||
-#include <string.h>
|
||
-
|
||
-#if defined(_MSC_VER) && !defined(inline)
|
||
-#define inline __inline
|
||
-#endif
|
||
-
|
||
-typedef struct {
|
||
- uint8_t *window;
|
||
- int mask;
|
||
- int64_t position;
|
||
-} LZSS;
|
||
-
|
||
-static inline int64_t lzss_position(LZSS *self) { return self->position; }
|
||
-
|
||
-static inline int lzss_mask(LZSS *self) { return self->mask; }
|
||
-
|
||
-static inline int lzss_size(LZSS *self) { return self->mask + 1; }
|
||
-
|
||
-static inline uint8_t *lzss_window_pointer(LZSS *self) { return self->window; }
|
||
-
|
||
-static inline int lzss_offset_for_position(LZSS *self, int64_t pos) { return (int)(pos & self->mask); }
|
||
-
|
||
-static inline uint8_t *lzss_window_pointer_for_position(LZSS *self, int64_t pos) { return &self->window[lzss_offset_for_position(self, pos)]; }
|
||
-
|
||
-static inline int lzss_current_window_offset(LZSS *self) { return lzss_offset_for_position(self, self->position); }
|
||
-
|
||
-static inline uint8_t *lzss_current_window_pointer(LZSS *self) { return lzss_window_pointer_for_position(self, self->position); }
|
||
-
|
||
-static inline int64_t lzss_next_window_edge_after_position(LZSS *self, int64_t pos) { return (pos + lzss_size(self)) & ~(int64_t)lzss_mask(self); }
|
||
-
|
||
-static inline int64_t lzss_next_window_edge(LZSS *self) { return lzss_next_window_edge_after_position(self, self->position); }
|
||
-
|
||
-static inline uint8_t lzss_get_byte_from_window(LZSS *self, int64_t pos) { return *lzss_window_pointer_for_position(self, pos); }
|
||
-
|
||
-static inline void lzss_emit_literal(LZSS *self, uint8_t literal) {
|
||
- /* self->window[(self->position & self->mask)] = literal; */
|
||
- *lzss_current_window_pointer(self) = literal;
|
||
- self->position++;
|
||
-}
|
||
-
|
||
-static inline void lzss_emit_match(LZSS *self, int offset, int length) {
|
||
- int windowoffs = lzss_current_window_offset(self);
|
||
- int i;
|
||
- for (i = 0; i < length; i++) {
|
||
- self->window[(windowoffs + i) & lzss_mask(self)] = self->window[(windowoffs + i - offset) & lzss_mask(self)];
|
||
- }
|
||
- self->position += length;
|
||
-}
|
||
-
|
||
-static inline void lzss_copy_bytes_from_window(LZSS *self, uint8_t *buffer, int64_t startpos, int length) {
|
||
- int windowoffs = lzss_offset_for_position(self, startpos);
|
||
- int firstpart = lzss_size(self) - windowoffs;
|
||
- if (length <= firstpart) {
|
||
- /* Request fits inside window */
|
||
- memcpy(buffer, &self->window[windowoffs], length);
|
||
- }
|
||
- else {
|
||
- /* Request wraps around window */
|
||
- memcpy(buffer, &self->window[windowoffs], firstpart);
|
||
- memcpy(buffer + firstpart, &self->window[0], length - firstpart);
|
||
- }
|
||
-}
|
||
-
|
||
-static inline bool lzss_initialize(LZSS *self, int windowsize) {
|
||
- self->window = malloc(windowsize);
|
||
- if (!self->window)
|
||
- return false;
|
||
-
|
||
- self->mask = windowsize - 1; /* Assume windows are power-of-two sized! */
|
||
- memset(self->window, 0, lzss_size(self));
|
||
- self->position = 0;
|
||
- return true;
|
||
-}
|
||
-
|
||
-static inline void lzss_cleanup(LZSS *self) { free(self->window); }
|
||
-
|
||
-#endif
|
||
diff --git a/cut-n-paste/unarr/rar/parse-rar.c b/cut-n-paste/unarr/rar/parse-rar.c
|
||
deleted file mode 100644
|
||
index f41534c6..00000000
|
||
--- a/cut-n-paste/unarr/rar/parse-rar.c
|
||
+++ /dev/null
|
||
@@ -1,236 +0,0 @@
|
||
-/* Copyright 2015 the unarr project authors (see AUTHORS file).
|
||
- License: LGPLv3 */
|
||
-
|
||
-/* adapted from https://code.google.com/p/theunarchiver/source/browse/XADMaster/XADRARParser.m */
|
||
-
|
||
-#include "rar.h"
|
||
-
|
||
-static inline uint8_t uint8le(unsigned char *data) { return data[0]; }
|
||
-static inline uint16_t uint16le(unsigned char *data) { return data[0] | data[1] << 8; }
|
||
-static inline uint32_t uint32le(unsigned char *data) { return data[0] | data[1] << 8 | data[2] << 16 | data[3] << 24; }
|
||
-
|
||
-bool rar_parse_header(ar_archive *ar, struct rar_header *header)
|
||
-{
|
||
- unsigned char header_data[7];
|
||
- size_t read = ar_read(ar->stream, header_data, sizeof(header_data));
|
||
- if (read == 0) {
|
||
- ar->at_eof = true;
|
||
- return false;
|
||
- }
|
||
- if (read < sizeof(header_data))
|
||
- return false;
|
||
-
|
||
- header->crc = uint16le(header_data + 0);
|
||
- header->type = uint8le(header_data + 2);
|
||
- header->flags = uint16le(header_data + 3);
|
||
- header->size = uint16le(header_data + 5);
|
||
-
|
||
- header->datasize = 0;
|
||
- if ((header->flags & LHD_LONG_BLOCK) || header->type == 0x74) {
|
||
- unsigned char size_data[4];
|
||
- if (!(header->flags & LHD_LONG_BLOCK))
|
||
- log("File header without LHD_LONG_BLOCK set");
|
||
- read += ar_read(ar->stream, size_data, sizeof(size_data));
|
||
- if (read < sizeof(header_data) + sizeof(size_data))
|
||
- return false;
|
||
- header->datasize = uint32le(size_data);
|
||
- }
|
||
-
|
||
- if (header->size < read) {
|
||
- warn("Invalid header size %d", header->size);
|
||
- return false;
|
||
- }
|
||
-
|
||
- return true;
|
||
-}
|
||
-
|
||
-bool rar_check_header_crc(ar_archive *ar)
|
||
-{
|
||
- unsigned char buffer[256];
|
||
- uint16_t crc16, size;
|
||
- uint32_t crc32;
|
||
-
|
||
- if (!ar_seek(ar->stream, ar->entry_offset, SEEK_SET))
|
||
- return false;
|
||
- if (ar_read(ar->stream, buffer, 7) != 7)
|
||
- return false;
|
||
-
|
||
- crc16 = uint16le(buffer + 0);
|
||
- size = uint16le(buffer + 5);
|
||
- if (size < 7)
|
||
- return false;
|
||
- size -= 7;
|
||
-
|
||
- crc32 = ar_crc32(0, buffer + 2, 5);
|
||
- while (size > 0) {
|
||
- if (ar_read(ar->stream, buffer, smin(size, sizeof(buffer))) != smin(size, sizeof(buffer)))
|
||
- return false;
|
||
- crc32 = ar_crc32(crc32, buffer, smin(size, sizeof(buffer)));
|
||
- size -= (uint16_t)smin(size, sizeof(buffer));
|
||
- }
|
||
- return (crc32 & 0xFFFF) == crc16;
|
||
-}
|
||
-
|
||
-bool rar_parse_header_entry(ar_archive_rar *rar, struct rar_header *header, struct rar_entry *entry)
|
||
-{
|
||
- unsigned char data[21];
|
||
- if (ar_read(rar->super.stream, data, sizeof(data)) != sizeof(data))
|
||
- return false;
|
||
-
|
||
- entry->size = uint32le(data + 0);
|
||
- entry->os = uint8le(data + 4);
|
||
- entry->crc = uint32le(data + 5);
|
||
- entry->dosdate = uint32le(data + 9);
|
||
- entry->version = uint8le(data + 13);
|
||
- entry->method = uint8le(data + 14);
|
||
- entry->namelen = uint16le(data + 15);
|
||
- entry->attrs = uint32le(data + 17);
|
||
- if ((header->flags & LHD_LARGE)) {
|
||
- unsigned char more_data[8];
|
||
- if (ar_read(rar->super.stream, more_data, sizeof(more_data)) != sizeof(more_data))
|
||
- return false;
|
||
- header->datasize += (uint64_t)uint32le(more_data + 0);
|
||
- entry->size += (uint64_t)uint32le(more_data + 4);
|
||
- }
|
||
- if (!ar_skip(rar->super.stream, entry->namelen))
|
||
- return false;
|
||
- if ((header->flags & LHD_SALT)) {
|
||
- log("Skipping LHD_SALT");
|
||
- ar_skip(rar->super.stream, 8);
|
||
- }
|
||
-
|
||
- rar->entry.version = entry->version;
|
||
- rar->entry.method = entry->method;
|
||
- rar->entry.crc = entry->crc;
|
||
- rar->entry.header_size = header->size;
|
||
- rar->entry.solid = entry->version < 20 ? (rar->archive_flags & MHD_SOLID) : (header->flags & LHD_SOLID);
|
||
- free(rar->entry.name);
|
||
- rar->entry.name = NULL;
|
||
-
|
||
- return true;
|
||
-}
|
||
-
|
||
-/* this seems to be what RAR considers "Unicode" */
|
||
-static char *rar_conv_unicode_to_utf8(const char *data, uint16_t len)
|
||
-{
|
||
-#define Check(cond) if (!(cond)) { free(str); return NULL; } else ((void)0)
|
||
-
|
||
- uint8_t highbyte, flagbyte, flagbits, size, length, i;
|
||
- const uint8_t *in = (uint8_t *)data + strlen(data) + 1;
|
||
- const uint8_t *end_in = (uint8_t *)data + len;
|
||
- char *str = calloc(len + 1, 3);
|
||
- char *out = str;
|
||
- char *end_out = str + len * 3;
|
||
-
|
||
- if (!str)
|
||
- return NULL;
|
||
- if (end_in - in <= 1) {
|
||
- memcpy(str, data, len);
|
||
- return str;
|
||
- }
|
||
-
|
||
- highbyte = *in++;
|
||
- flagbyte = 0;
|
||
- flagbits = 0;
|
||
- size = 0;
|
||
-
|
||
- while (in < end_in && out < end_out) {
|
||
- if (flagbits == 0) {
|
||
- flagbyte = *in++;
|
||
- flagbits = 8;
|
||
- }
|
||
- flagbits -= 2;
|
||
- switch ((flagbyte >> flagbits) & 3) {
|
||
- case 0:
|
||
- Check(in + 1 <= end_in);
|
||
- out += ar_conv_rune_to_utf8(*in++, out, end_out - out);
|
||
- size++;
|
||
- break;
|
||
- case 1:
|
||
- Check(in + 1 <= end_in);
|
||
- out += ar_conv_rune_to_utf8(((uint16_t)highbyte << 8) | *in++, out, end_out - out);
|
||
- size++;
|
||
- break;
|
||
- case 2:
|
||
- Check(in + 2 <= end_in);
|
||
- out += ar_conv_rune_to_utf8(((uint16_t)*(in + 1) << 8) | *in, out, end_out - out);
|
||
- in += 2;
|
||
- size++;
|
||
- break;
|
||
- case 3:
|
||
- Check(in + 1 <= end_in);
|
||
- length = *in++;
|
||
- if ((length & 0x80)) {
|
||
- uint8_t correction = *in++;
|
||
- for (i = 0; i < (length & 0x7F) + 2; i++) {
|
||
- Check(size < len);
|
||
- out += ar_conv_rune_to_utf8(((uint16_t)highbyte << 8) | (data[size] + (correction & 0xFF)), out, end_out - out);
|
||
- size++;
|
||
- }
|
||
- }
|
||
- else {
|
||
- for (i = 0; i < (length & 0x7F) + 2; i++) {
|
||
- Check(size < len);
|
||
- out += ar_conv_rune_to_utf8(data[size], out, end_out - out);
|
||
- size++;
|
||
- }
|
||
- }
|
||
- break;
|
||
- }
|
||
- }
|
||
-
|
||
- return str;
|
||
-
|
||
-#undef Check
|
||
-}
|
||
-
|
||
-const char *rar_get_name(ar_archive *ar)
|
||
-{
|
||
- ar_archive_rar *rar = (ar_archive_rar *)ar;
|
||
- if (!rar->entry.name) {
|
||
- unsigned char data[21];
|
||
- uint16_t namelen;
|
||
- char *name;
|
||
-
|
||
- struct rar_header header;
|
||
- if (!ar_seek(ar->stream, ar->entry_offset, SEEK_SET))
|
||
- return NULL;
|
||
- if (!rar_parse_header(ar, &header))
|
||
- return NULL;
|
||
- if (ar_read(ar->stream, data, sizeof(data)) != sizeof(data))
|
||
- return NULL;
|
||
- if ((header.flags & LHD_LARGE) && !ar_skip(ar->stream, 8))
|
||
- return NULL;
|
||
-
|
||
- namelen = uint16le(data + 15);
|
||
- name = malloc(namelen + 1);
|
||
- if (!name || ar_read(ar->stream, name, namelen) != namelen) {
|
||
- free(name);
|
||
- return NULL;
|
||
- }
|
||
- name[namelen] = '\0';
|
||
-
|
||
- if (!(header.flags & LHD_UNICODE)) {
|
||
- rar->entry.name = ar_conv_dos_to_utf8(name);
|
||
- free(name);
|
||
- }
|
||
- else if (namelen == strlen(name)) {
|
||
- rar->entry.name = name;
|
||
- }
|
||
- else {
|
||
- rar->entry.name = rar_conv_unicode_to_utf8(name, namelen);
|
||
- free(name);
|
||
- }
|
||
- /* normalize path separators */
|
||
- if (rar->entry.name) {
|
||
- char *p = rar->entry.name;
|
||
- while ((p = strchr(p, '\\')) != NULL) {
|
||
- *p = '/';
|
||
- }
|
||
- }
|
||
-
|
||
- if (!ar_seek(ar->stream, ar->entry_offset + rar->entry.header_size, SEEK_SET))
|
||
- warn("Couldn't seek back to the end of the entry header");
|
||
- }
|
||
- return rar->entry.name;
|
||
-}
|
||
diff --git a/cut-n-paste/unarr/rar/rar.c b/cut-n-paste/unarr/rar/rar.c
|
||
deleted file mode 100644
|
||
index d03b2da4..00000000
|
||
--- a/cut-n-paste/unarr/rar/rar.c
|
||
+++ /dev/null
|
||
@@ -1,254 +0,0 @@
|
||
-/* Copyright 2015 the unarr project authors (see AUTHORS file).
|
||
- License: LGPLv3 */
|
||
-
|
||
-#include "rar.h"
|
||
-
|
||
-static void rar_close(ar_archive *ar)
|
||
-{
|
||
- ar_archive_rar *rar = (ar_archive_rar *)ar;
|
||
- free(rar->entry.name);
|
||
- rar_clear_uncompress(&rar->uncomp);
|
||
-}
|
||
-
|
||
-static bool rar_parse_entry(ar_archive *ar, off64_t offset)
|
||
-{
|
||
- ar_archive_rar *rar = (ar_archive_rar *)ar;
|
||
- struct rar_header header;
|
||
- struct rar_entry entry;
|
||
- bool out_of_order = offset != ar->entry_offset_next;
|
||
-
|
||
- if (!ar_seek(ar->stream, offset, SEEK_SET)) {
|
||
- warn("Couldn't seek to offset %" PRIi64, offset);
|
||
- return false;
|
||
- }
|
||
-
|
||
- for (;;) {
|
||
- ar->entry_offset = ar_tell(ar->stream);
|
||
- ar->entry_size_uncompressed = 0;
|
||
-
|
||
- if (!rar_parse_header(ar, &header))
|
||
- return false;
|
||
-
|
||
- ar->entry_offset_next = ar->entry_offset + header.size + header.datasize;
|
||
- if (ar->entry_offset_next < ar->entry_offset + header.size) {
|
||
- warn("Integer overflow due to overly large data size");
|
||
- return false;
|
||
- }
|
||
-
|
||
- switch (header.type) {
|
||
- case TYPE_MAIN_HEADER:
|
||
- if ((header.flags & MHD_PASSWORD)) {
|
||
- warn("Encrypted archives aren't supported");
|
||
- return false;
|
||
- }
|
||
- ar_skip(ar->stream, 6 /* reserved data */);
|
||
- if ((header.flags & MHD_ENCRYPTVER)) {
|
||
- log("MHD_ENCRYPTVER is set");
|
||
- ar_skip(ar->stream, 1);
|
||
- }
|
||
- if ((header.flags & MHD_COMMENT))
|
||
- log("MHD_COMMENT is set");
|
||
- if (ar_tell(ar->stream) - ar->entry_offset > header.size) {
|
||
- warn("Invalid RAR header size: %d", header.size);
|
||
- return false;
|
||
- }
|
||
- rar->archive_flags = header.flags;
|
||
- break;
|
||
-
|
||
- case TYPE_FILE_ENTRY:
|
||
- if (!rar_parse_header_entry(rar, &header, &entry))
|
||
- return false;
|
||
- if ((header.flags & LHD_PASSWORD))
|
||
- warn("Encrypted entries will fail to uncompress");
|
||
- if ((header.flags & LHD_DIRECTORY) == LHD_DIRECTORY) {
|
||
- if (header.datasize == 0) {
|
||
- log("Skipping directory entry \"%s\"", rar_get_name(ar));
|
||
- break;
|
||
- }
|
||
- warn("Can't skip directory entries containing data");
|
||
- }
|
||
- if ((header.flags & (LHD_SPLIT_BEFORE | LHD_SPLIT_AFTER)))
|
||
- warn("Splitting files isn't really supported");
|
||
- ar->entry_size_uncompressed = (size_t)entry.size;
|
||
- ar->entry_filetime = ar_conv_dosdate_to_filetime(entry.dosdate);
|
||
- if (!rar->entry.solid || rar->entry.method == METHOD_STORE || out_of_order) {
|
||
- rar_clear_uncompress(&rar->uncomp);
|
||
- memset(&rar->solid, 0, sizeof(rar->solid));
|
||
- }
|
||
- else {
|
||
- br_clear_leftover_bits(&rar->uncomp);
|
||
- }
|
||
-
|
||
- rar->solid.restart = rar->entry.solid && (out_of_order || !rar->solid.part_done);
|
||
- rar->solid.part_done = !ar->entry_size_uncompressed;
|
||
- rar->progress.data_left = (size_t)header.datasize;
|
||
- rar->progress.bytes_done = 0;
|
||
- rar->progress.crc = 0;
|
||
-
|
||
- /* TODO: CRC checks don't always hold (claim in XADRARParser.m @readBlockHeader) */
|
||
- if (!rar_check_header_crc(ar))
|
||
- warn("Invalid header checksum @%" PRIi64, ar->entry_offset);
|
||
- if (ar_tell(ar->stream) != ar->entry_offset + rar->entry.header_size) {
|
||
- warn("Couldn't seek to offset %" PRIi64, ar->entry_offset + rar->entry.header_size);
|
||
- return false;
|
||
- }
|
||
- return true;
|
||
-
|
||
- case TYPE_NEWSUB:
|
||
- log("Skipping newsub header @%" PRIi64, ar->entry_offset);
|
||
- break;
|
||
-
|
||
- case TYPE_END_OF_ARCHIVE:
|
||
- ar->at_eof = true;
|
||
- return false;
|
||
-
|
||
- default:
|
||
- log("Unknown RAR header type %02x", header.type);
|
||
- break;
|
||
- }
|
||
-
|
||
- /* TODO: CRC checks don't always hold (claim in XADRARParser.m @readBlockHeader) */
|
||
- if (!rar_check_header_crc(ar))
|
||
- warn("Invalid header checksum @%" PRIi64, ar->entry_offset);
|
||
- if (!ar_seek(ar->stream, ar->entry_offset_next, SEEK_SET)) {
|
||
- warn("Couldn't seek to offset %" PRIi64, ar->entry_offset_next);
|
||
- return false;
|
||
- }
|
||
- }
|
||
-}
|
||
-
|
||
-static bool rar_copy_stored(ar_archive_rar *rar, void *buffer, size_t count)
|
||
-{
|
||
- if (count > rar->progress.data_left) {
|
||
- warn("Unexpected EOS in stored data");
|
||
- return false;
|
||
- }
|
||
- if (ar_read(rar->super.stream, buffer, count) != count) {
|
||
- warn("Unexpected EOF in stored data");
|
||
- return false;
|
||
- }
|
||
- rar->progress.data_left -= count;
|
||
- rar->progress.bytes_done += count;
|
||
- return true;
|
||
-}
|
||
-
|
||
-static bool rar_restart_solid(ar_archive *ar)
|
||
-{
|
||
- ar_archive_rar *rar = (ar_archive_rar *)ar;
|
||
- off64_t current_offset = ar->entry_offset;
|
||
- log("Restarting decompression for solid entry");
|
||
- if (!ar_parse_entry_at(ar, ar->entry_offset_first)) {
|
||
- ar_parse_entry_at(ar, current_offset);
|
||
- return false;
|
||
- }
|
||
- while (ar->entry_offset < current_offset) {
|
||
- size_t size = ar->entry_size_uncompressed;
|
||
- rar->solid.restart = false;
|
||
- while (size > 0) {
|
||
- unsigned char buffer[1024];
|
||
- size_t count = smin(size, sizeof(buffer));
|
||
- if (!ar_entry_uncompress(ar, buffer, count)) {
|
||
- ar_parse_entry_at(ar, current_offset);
|
||
- return false;
|
||
- }
|
||
- size -= count;
|
||
- }
|
||
- if (!ar_parse_entry(ar)) {
|
||
- ar_parse_entry_at(ar, current_offset);
|
||
- return false;
|
||
- }
|
||
- }
|
||
- rar->solid.restart = false;
|
||
- return true;
|
||
-}
|
||
-
|
||
-static bool rar_uncompress(ar_archive *ar, void *buffer, size_t count)
|
||
-{
|
||
- ar_archive_rar *rar = (ar_archive_rar *)ar;
|
||
- if (count > ar->entry_size_uncompressed - rar->progress.bytes_done) {
|
||
- warn("Requesting too much data (%" PRIuPTR " < %" PRIuPTR ")", ar->entry_size_uncompressed - rar->progress.bytes_done, count);
|
||
- return false;
|
||
- }
|
||
- if (rar->entry.method == METHOD_STORE) {
|
||
- if (!rar_copy_stored(rar, buffer, count))
|
||
- return false;
|
||
- }
|
||
- else if (rar->entry.method == METHOD_FASTEST || rar->entry.method == METHOD_FAST ||
|
||
- rar->entry.method == METHOD_NORMAL || rar->entry.method == METHOD_GOOD ||
|
||
- rar->entry.method == METHOD_BEST) {
|
||
- if (rar->solid.restart && !rar_restart_solid(ar)) {
|
||
- warn("Failed to produce the required solid decompression state");
|
||
- return false;
|
||
- }
|
||
- if (!rar_uncompress_part(rar, buffer, count))
|
||
- return false;
|
||
- }
|
||
- else {
|
||
- warn("Unknown compression method %#02x", rar->entry.method);
|
||
- return false;
|
||
- }
|
||
-
|
||
- rar->progress.crc = ar_crc32(rar->progress.crc, buffer, count);
|
||
- if (rar->progress.bytes_done < ar->entry_size_uncompressed)
|
||
- return true;
|
||
- if (rar->progress.data_left)
|
||
- log("Compressed block has more data than required");
|
||
- rar->solid.part_done = true;
|
||
- rar->solid.size_total += rar->progress.bytes_done;
|
||
- if (rar->progress.crc != rar->entry.crc) {
|
||
- warn("Checksum of extracted data doesn't match");
|
||
- return false;
|
||
- }
|
||
- return true;
|
||
-}
|
||
-
|
||
-ar_archive *ar_open_rar_archive(ar_stream *stream)
|
||
-{
|
||
- char signature[FILE_SIGNATURE_SIZE];
|
||
- if (!ar_seek(stream, 0, SEEK_SET))
|
||
- return NULL;
|
||
- if (ar_read(stream, signature, sizeof(signature)) != sizeof(signature))
|
||
- return NULL;
|
||
- if (memcmp(signature, "Rar!\x1A\x07\x00", sizeof(signature)) != 0) {
|
||
- if (memcmp(signature, "Rar!\x1A\x07\x01", sizeof(signature)) == 0)
|
||
- warn("RAR 5 format isn't supported");
|
||
- else if (memcmp(signature, "RE~^", 4) == 0)
|
||
- warn("Ancient RAR format isn't supported");
|
||
- else if (memcmp(signature, "MZ", 2) == 0 || memcmp(signature, "\x7F\x45LF", 4) == 0)
|
||
- warn("SFX archives aren't supported");
|
||
- return NULL;
|
||
- }
|
||
-
|
||
- return ar_open_archive(stream, sizeof(ar_archive_rar), rar_close, rar_parse_entry, rar_get_name, rar_uncompress, NULL, FILE_SIGNATURE_SIZE);
|
||
-}
|
||
-
|
||
-ar_archive *ar_open_rar_archive_with_error(ar_stream *stream,
|
||
- ArArchiveError *error_code)
|
||
-{
|
||
- char signature[FILE_SIGNATURE_SIZE];
|
||
- ar_archive *ret;
|
||
-
|
||
- if (!ar_seek(stream, 0, SEEK_SET)) {
|
||
- *error_code = AR_ARCHIVE_ERROR_UNKNOWN;
|
||
- return NULL;
|
||
- }
|
||
- if (ar_read(stream, signature, sizeof(signature)) != sizeof(signature)) {
|
||
- *error_code = AR_ARCHIVE_ERROR_UNKNOWN;
|
||
- return NULL;
|
||
- }
|
||
- if (memcmp(signature, "Rar!\x1A\x07\x00", sizeof(signature)) != 0) {
|
||
- if (memcmp(signature, "Rar!\x1A\x07\x01", sizeof(signature)) == 0)
|
||
- *error_code = AR_ARCHIVE_ERROR_RAR5;
|
||
- else if (memcmp(signature, "RE~^", 4) == 0)
|
||
- *error_code = AR_ARCHIVE_ERROR_OLDRAR;
|
||
- else if (memcmp(signature, "MZ", 2) == 0 || memcmp(signature, "\x7F\x45LF", 4) == 0)
|
||
- *error_code = AR_ARCHIVE_ERROR_SFX;
|
||
- return NULL;
|
||
- }
|
||
-
|
||
-
|
||
- ret = ar_open_archive(stream, sizeof(ar_archive_rar), rar_close, rar_parse_entry, rar_get_name, rar_uncompress, NULL, FILE_SIGNATURE_SIZE);
|
||
- if (!ret)
|
||
- *error_code = AR_ARCHIVE_ERROR_UNKNOWN;
|
||
- return ret;
|
||
-}
|
||
diff --git a/cut-n-paste/unarr/rar/rar.h b/cut-n-paste/unarr/rar/rar.h
|
||
deleted file mode 100644
|
||
index 783f9f75..00000000
|
||
--- a/cut-n-paste/unarr/rar/rar.h
|
||
+++ /dev/null
|
||
@@ -1,252 +0,0 @@
|
||
-/* Copyright 2015 the unarr project authors (see AUTHORS file).
|
||
- License: LGPLv3 */
|
||
-
|
||
-#ifndef rar_rar_h
|
||
-#define rar_rar_h
|
||
-
|
||
-#include "../common/unarr-imp.h"
|
||
-
|
||
-#include "lzss.h"
|
||
-#include "../lzmasdk/Ppmd7.h"
|
||
-#include <limits.h>
|
||
-
|
||
-static inline size_t smin(size_t a, size_t b) { return a < b ? a : b; }
|
||
-
|
||
-typedef struct ar_archive_rar_s ar_archive_rar;
|
||
-
|
||
-/***** parse-rar *****/
|
||
-
|
||
-#define FILE_SIGNATURE_SIZE 7
|
||
-
|
||
-enum block_types {
|
||
- TYPE_FILE_SIGNATURE = 0x72, TYPE_MAIN_HEADER = 0x73, TYPE_FILE_ENTRY = 0x74,
|
||
- TYPE_NEWSUB = 0x7A, TYPE_END_OF_ARCHIVE = 0x7B,
|
||
-};
|
||
-
|
||
-enum archive_flags {
|
||
- MHD_VOLUME = 1 << 0, MHD_COMMENT = 1 << 1, MHD_LOCK = 1 << 2,
|
||
- MHD_SOLID = 1 << 3, MHD_PACK_COMMENT = 1 << 4, MHD_AV = 1 << 5,
|
||
- MHD_PROTECT = 1 << 6, MHD_PASSWORD = 1 << 7, MHD_FIRSTVOLUME = 1 << 8,
|
||
- MHD_ENCRYPTVER = 1 << 9,
|
||
- MHD_LONG_BLOCK = 1 << 15,
|
||
-};
|
||
-
|
||
-enum entry_flags {
|
||
- LHD_SPLIT_BEFORE = 1 << 0, LHD_SPLIT_AFTER = 1 << 1, LHD_PASSWORD = 1 << 2,
|
||
- LHD_COMMENT = 1 << 3, LHD_SOLID = 1 << 4,
|
||
- LHD_DIRECTORY = (1 << 5) | (1 << 6) | (1 << 7),
|
||
- LHD_LARGE = 1 << 8, LHD_UNICODE = 1 << 9, LHD_SALT = 1 << 10,
|
||
- LHD_VERSION = 1 << 11, LHD_EXTTIME = 1 << 12, LHD_EXTFLAGS = 1 << 13,
|
||
- LHD_LONG_BLOCK = 1 << 15,
|
||
-};
|
||
-
|
||
-enum compression_method {
|
||
- METHOD_STORE = 0x30,
|
||
- METHOD_FASTEST = 0x31, METHOD_FAST = 0x32, METHOD_NORMAL = 0x33,
|
||
- METHOD_GOOD = 0x34, METHOD_BEST = 0x35,
|
||
-};
|
||
-
|
||
-struct rar_header {
|
||
- uint16_t crc;
|
||
- uint8_t type;
|
||
- uint16_t flags;
|
||
- uint16_t size;
|
||
- uint64_t datasize;
|
||
-};
|
||
-
|
||
-struct rar_entry {
|
||
- uint64_t size;
|
||
- uint8_t os;
|
||
- uint32_t crc;
|
||
- uint32_t dosdate;
|
||
- uint8_t version;
|
||
- uint8_t method;
|
||
- uint16_t namelen;
|
||
- uint32_t attrs;
|
||
-};
|
||
-
|
||
-struct ar_archive_rar_entry {
|
||
- uint8_t version;
|
||
- uint8_t method;
|
||
- uint32_t crc;
|
||
- uint16_t header_size;
|
||
- bool solid;
|
||
- char *name;
|
||
-};
|
||
-
|
||
-bool rar_parse_header(ar_archive *ar, struct rar_header *header);
|
||
-bool rar_check_header_crc(ar_archive *ar);
|
||
-bool rar_parse_header_entry(ar_archive_rar *rar, struct rar_header *header, struct rar_entry *entry);
|
||
-const char *rar_get_name(ar_archive *ar);
|
||
-
|
||
-/***** filter-rar *****/
|
||
-
|
||
-struct RARVirtualMachine;
|
||
-struct RARProgramCode;
|
||
-struct RARFilter;
|
||
-
|
||
-struct ar_archive_rar_filters {
|
||
- struct RARVirtualMachine *vm;
|
||
- struct RARProgramCode *progs;
|
||
- struct RARFilter *stack;
|
||
- size_t filterstart;
|
||
- uint32_t lastfilternum;
|
||
- size_t lastend;
|
||
- uint8_t *bytes;
|
||
- size_t bytes_ready;
|
||
-};
|
||
-
|
||
-bool rar_parse_filter(ar_archive_rar *rar, const uint8_t *bytes, uint16_t length, uint8_t flags);
|
||
-bool rar_run_filters(ar_archive_rar *rar);
|
||
-void rar_clear_filters(struct ar_archive_rar_filters *filters);
|
||
-
|
||
-/***** huffman-rar *****/
|
||
-
|
||
-struct huffman_code {
|
||
- struct {
|
||
- int branches[2];
|
||
- } *tree;
|
||
- int numentries;
|
||
- int capacity;
|
||
- int minlength;
|
||
- int maxlength;
|
||
- struct {
|
||
- int length;
|
||
- int value;
|
||
- } *table;
|
||
- int tablesize;
|
||
-};
|
||
-
|
||
-bool rar_new_node(struct huffman_code *code);
|
||
-bool rar_add_value(struct huffman_code *code, int value, int codebits, int length);
|
||
-bool rar_create_code(struct huffman_code *code, uint8_t *lengths, int numsymbols);
|
||
-bool rar_make_table(struct huffman_code *code);
|
||
-void rar_free_code(struct huffman_code *code);
|
||
-
|
||
-static inline bool rar_is_leaf_node(struct huffman_code *code, int node) { return code->tree[node].branches[0] == code->tree[node].branches[1]; }
|
||
-
|
||
-/***** uncompress-rar *****/
|
||
-
|
||
-#define LZSS_WINDOW_SIZE 0x400000
|
||
-#define LZSS_OVERFLOW_SIZE 288
|
||
-
|
||
-#define MAINCODE_SIZE 299
|
||
-#define OFFSETCODE_SIZE 60
|
||
-#define LOWOFFSETCODE_SIZE 17
|
||
-#define LENGTHCODE_SIZE 28
|
||
-#define HUFFMAN_TABLE_SIZE MAINCODE_SIZE + OFFSETCODE_SIZE + LOWOFFSETCODE_SIZE + LENGTHCODE_SIZE
|
||
-
|
||
-struct ByteReader {
|
||
- IByteIn super;
|
||
- ar_archive_rar *rar;
|
||
-};
|
||
-
|
||
-struct CPpmdRAR_RangeDec {
|
||
- CPpmd7_RangeDec super;
|
||
- UInt32 Range;
|
||
- UInt32 Code;
|
||
- UInt32 Low;
|
||
- IByteIn *Stream;
|
||
-};
|
||
-
|
||
-struct ar_archive_rar_uncomp_v3 {
|
||
- struct huffman_code maincode;
|
||
- struct huffman_code offsetcode;
|
||
- struct huffman_code lowoffsetcode;
|
||
- struct huffman_code lengthcode;
|
||
- uint8_t lengthtable[HUFFMAN_TABLE_SIZE];
|
||
- uint32_t lastlength;
|
||
- uint32_t lastoffset;
|
||
- uint32_t oldoffset[4];
|
||
- uint32_t lastlowoffset;
|
||
- uint32_t numlowoffsetrepeats;
|
||
-
|
||
- bool is_ppmd_block;
|
||
- int ppmd_escape;
|
||
- CPpmd7 ppmd7_context;
|
||
- struct CPpmdRAR_RangeDec range_dec;
|
||
- struct ByteReader bytein;
|
||
-
|
||
- struct ar_archive_rar_filters filters;
|
||
-};
|
||
-
|
||
-#define MAINCODE_SIZE_20 298
|
||
-#define OFFSETCODE_SIZE_20 48
|
||
-#define LENGTHCODE_SIZE_20 28
|
||
-#define HUFFMAN_TABLE_SIZE_20 4 * 257
|
||
-
|
||
-struct AudioState {
|
||
- int8_t weight[5];
|
||
- int16_t delta[4];
|
||
- int8_t lastdelta;
|
||
- int error[11];
|
||
- int count;
|
||
- uint8_t lastbyte;
|
||
-};
|
||
-
|
||
-struct ar_archive_rar_uncomp_v2 {
|
||
- struct huffman_code maincode;
|
||
- struct huffman_code offsetcode;
|
||
- struct huffman_code lengthcode;
|
||
- struct huffman_code audiocode[4];
|
||
- uint8_t lengthtable[HUFFMAN_TABLE_SIZE_20];
|
||
- uint32_t lastoffset;
|
||
- uint32_t lastlength;
|
||
- uint32_t oldoffset[4];
|
||
- uint32_t oldoffsetindex;
|
||
-
|
||
- bool audioblock;
|
||
- uint8_t channel;
|
||
- uint8_t numchannels;
|
||
- struct AudioState audiostate[4];
|
||
- int8_t channeldelta;
|
||
-};
|
||
-
|
||
-struct ar_archive_rar_uncomp {
|
||
- uint8_t version;
|
||
-
|
||
- LZSS lzss;
|
||
- size_t bytes_ready;
|
||
- bool start_new_table;
|
||
-
|
||
- union {
|
||
- struct ar_archive_rar_uncomp_v3 v3;
|
||
- struct ar_archive_rar_uncomp_v2 v2;
|
||
- } state;
|
||
-
|
||
- struct StreamBitReader {
|
||
- uint64_t bits;
|
||
- int available;
|
||
- bool at_eof;
|
||
- } br;
|
||
-};
|
||
-
|
||
-bool rar_uncompress_part(ar_archive_rar *rar, void *buffer, size_t buffer_size);
|
||
-int64_t rar_expand(ar_archive_rar *rar, int64_t end);
|
||
-void rar_clear_uncompress(struct ar_archive_rar_uncomp *uncomp);
|
||
-static inline void br_clear_leftover_bits(struct ar_archive_rar_uncomp *uncomp) { uncomp->br.available &= ~0x07; }
|
||
-
|
||
-/***** rar *****/
|
||
-
|
||
-struct ar_archive_rar_progress {
|
||
- size_t data_left;
|
||
- size_t bytes_done;
|
||
- uint32_t crc;
|
||
-};
|
||
-
|
||
-struct ar_archive_rar_solid {
|
||
- size_t size_total;
|
||
- bool part_done;
|
||
- bool restart;
|
||
-};
|
||
-
|
||
-struct ar_archive_rar_s {
|
||
- ar_archive super;
|
||
- uint16_t archive_flags;
|
||
- struct ar_archive_rar_entry entry;
|
||
- struct ar_archive_rar_uncomp uncomp;
|
||
- struct ar_archive_rar_progress progress;
|
||
- struct ar_archive_rar_solid solid;
|
||
-};
|
||
-
|
||
-#endif
|
||
diff --git a/cut-n-paste/unarr/rar/rarvm.c b/cut-n-paste/unarr/rar/rarvm.c
|
||
deleted file mode 100644
|
||
index 6f738ec3..00000000
|
||
--- a/cut-n-paste/unarr/rar/rarvm.c
|
||
+++ /dev/null
|
||
@@ -1,616 +0,0 @@
|
||
-/* Copyright 2015 the unarr project authors (see AUTHORS file).
|
||
- License: LGPLv3 */
|
||
-
|
||
-/* adapted from https://code.google.com/p/theunarchiver/source/browse/XADMaster/RARVirtualMachine.c */
|
||
-
|
||
-#include "rarvm.h"
|
||
-#include "../common/allocator.h"
|
||
-
|
||
-#include <stdlib.h>
|
||
-#include <string.h>
|
||
-
|
||
-typedef struct RAROpcode_s RAROpcode;
|
||
-
|
||
-struct RAROpcode_s {
|
||
- uint8_t instruction;
|
||
- uint8_t bytemode;
|
||
- uint8_t addressingmode1;
|
||
- uint8_t addressingmode2;
|
||
- uint32_t value1;
|
||
- uint32_t value2;
|
||
-};
|
||
-
|
||
-struct RARProgram_s {
|
||
- RAROpcode *opcodes;
|
||
- uint32_t length;
|
||
- uint32_t capacity;
|
||
-};
|
||
-
|
||
-/* Program building */
|
||
-
|
||
-RARProgram *RARCreateProgram()
|
||
-{
|
||
- return calloc(1, sizeof(RARProgram));
|
||
-}
|
||
-
|
||
-void RARDeleteProgram(RARProgram *prog)
|
||
-{
|
||
- if (prog)
|
||
- free(prog->opcodes);
|
||
- free(prog);
|
||
-}
|
||
-
|
||
-bool RARProgramAddInstr(RARProgram *prog, uint8_t instruction, bool bytemode)
|
||
-{
|
||
- if (instruction >= RARNumberOfInstructions)
|
||
- return false;
|
||
- if (bytemode && !RARInstructionHasByteMode(instruction))
|
||
- return false;
|
||
- if (prog->length + 1 >= prog->capacity) {
|
||
- /* in my small file sample, 16 is the value needed most often */
|
||
- uint32_t newCapacity = prog->capacity ? prog->capacity * 4 : 32;
|
||
- RAROpcode *newCodes = calloc(newCapacity, sizeof(*prog->opcodes));
|
||
- if (!newCodes)
|
||
- return false;
|
||
- memcpy(newCodes, prog->opcodes, prog->capacity * sizeof(*prog->opcodes));
|
||
- free(prog->opcodes);
|
||
- prog->opcodes = newCodes;
|
||
- prog->capacity = newCapacity;
|
||
- }
|
||
- memset(&prog->opcodes[prog->length], 0, sizeof(prog->opcodes[prog->length]));
|
||
- prog->opcodes[prog->length].instruction = instruction;
|
||
- if (instruction == RARMovzxInstruction || instruction == RARMovsxInstruction)
|
||
- prog->opcodes[prog->length].bytemode = 2; /* second argument only */
|
||
- else if (bytemode)
|
||
- prog->opcodes[prog->length].bytemode = (1 | 2);
|
||
- else
|
||
- prog->opcodes[prog->length].bytemode = 0;
|
||
- prog->length++;
|
||
- return true;
|
||
-}
|
||
-
|
||
-bool RARSetLastInstrOperands(RARProgram *prog, uint8_t addressingmode1, uint32_t value1, uint8_t addressingmode2, uint32_t value2)
|
||
-{
|
||
- RAROpcode *opcode = &prog->opcodes[prog->length - 1];
|
||
- int numoperands;
|
||
-
|
||
- if (addressingmode1 >= RARNumberOfAddressingModes || addressingmode2 >= RARNumberOfAddressingModes)
|
||
- return false;
|
||
- if (!prog->length || opcode->addressingmode1 || opcode->value1 || opcode->addressingmode2 || opcode->value2)
|
||
- return false;
|
||
-
|
||
- numoperands = NumberOfRARInstructionOperands(opcode->instruction);
|
||
- if (numoperands == 0)
|
||
- return true;
|
||
-
|
||
- if (addressingmode1 == RARImmediateAddressingMode && RARInstructionWritesFirstOperand(opcode->instruction))
|
||
- return false;
|
||
- opcode->addressingmode1 = addressingmode1;
|
||
- opcode->value1 = value1;
|
||
-
|
||
- if (numoperands == 2) {
|
||
- if (addressingmode2 == RARImmediateAddressingMode && RARInstructionWritesSecondOperand(opcode->instruction))
|
||
- return false;
|
||
- opcode->addressingmode2 = addressingmode2;
|
||
- opcode->value2 = value2;
|
||
- }
|
||
-
|
||
- return true;
|
||
-}
|
||
-
|
||
-bool RARIsProgramTerminated(RARProgram *prog)
|
||
-{
|
||
- return prog->length > 0 && RARInstructionIsUnconditionalJump(prog->opcodes[prog->length - 1].instruction);
|
||
-}
|
||
-
|
||
-/* Execution */
|
||
-
|
||
-#define EXTMACRO_BEGIN do {
|
||
-#ifdef _MSC_VER
|
||
-#define EXTMACRO_END } __pragma(warning(push)) __pragma(warning(disable:4127)) while (0) __pragma(warning(pop))
|
||
-#else
|
||
-#define EXTMACRO_END } while (0)
|
||
-#endif
|
||
-
|
||
-#define CarryFlag 1
|
||
-#define ZeroFlag 2
|
||
-#define SignFlag 0x80000000
|
||
-
|
||
-#define SignExtend(a) ((uint32_t)((int8_t)(a)))
|
||
-
|
||
-static uint32_t _RARGetOperand(RARVirtualMachine *vm, uint8_t addressingmode, uint32_t value, bool bytemode);
|
||
-static void _RARSetOperand(RARVirtualMachine *vm, uint8_t addressingmode, uint32_t value, bool bytemode, uint32_t data);
|
||
-
|
||
-#define GetOperand1() _RARGetOperand(vm, opcode->addressingmode1, opcode->value1, opcode->bytemode & 1)
|
||
-#define GetOperand2() _RARGetOperand(vm, opcode->addressingmode2, opcode->value2, opcode->bytemode & 2)
|
||
-#define SetOperand1(data) _RARSetOperand(vm, opcode->addressingmode1, opcode->value1, opcode->bytemode & 1, data)
|
||
-#define SetOperand2(data) _RARSetOperand(vm, opcode->addressingmode2, opcode->value2, opcode->bytemode & 2, data)
|
||
-
|
||
-#define SetFlagsWithCarry(res, carry) EXTMACRO_BEGIN uint32_t result = (res); flags = (result == 0 ? ZeroFlag : (result & SignFlag)) | ((carry) ? CarryFlag : 0); EXTMACRO_END
|
||
-#define SetByteFlagsWithCarry(res, carry) EXTMACRO_BEGIN uint8_t result = (res); flags = (result == 0 ? ZeroFlag : (SignExtend(result) & SignFlag)) | ((carry) ? CarryFlag : 0); EXTMACRO_END
|
||
-#define SetFlags(res) SetFlagsWithCarry(res, 0)
|
||
-
|
||
-#define SetOperand1AndFlagsWithCarry(res, carry) EXTMACRO_BEGIN uint32_t r = (res); SetFlagsWithCarry(r, carry); SetOperand1(r); EXTMACRO_END
|
||
-#define SetOperand1AndByteFlagsWithCarry(res, carry) EXTMACRO_BEGIN uint8_t r = (res); SetByteFlagsWithCarry(r, carry); SetOperand1(r); EXTMACRO_END
|
||
-#define SetOperand1AndFlags(res) EXTMACRO_BEGIN uint32_t r = (res); SetFlags(r); SetOperand1(r); EXTMACRO_END
|
||
-
|
||
-#define NextInstruction() { opcode++; continue; }
|
||
-#define Jump(offs) { uint32_t o = (offs); if (o >= prog->length) return false; opcode = &prog->opcodes[o]; continue; }
|
||
-
|
||
-bool RARExecuteProgram(RARVirtualMachine *vm, RARProgram *prog)
|
||
-{
|
||
- RAROpcode *opcode = prog->opcodes;
|
||
- uint32_t flags = 0;
|
||
- uint32_t op1, op2, carry, i;
|
||
- uint32_t counter = 0;
|
||
-
|
||
- if (!RARIsProgramTerminated(prog))
|
||
- return false;
|
||
-
|
||
- while ((uint32_t)(opcode - prog->opcodes) < prog->length && counter++ < RARRuntimeMaxInstructions) {
|
||
- switch (opcode->instruction) {
|
||
- case RARMovInstruction:
|
||
- SetOperand1(GetOperand2());
|
||
- NextInstruction();
|
||
-
|
||
- case RARCmpInstruction:
|
||
- op1 = GetOperand1();
|
||
- SetFlagsWithCarry(op1 - GetOperand2(), result > op1);
|
||
- NextInstruction();
|
||
-
|
||
- case RARAddInstruction:
|
||
- op1 = GetOperand1();
|
||
- if (opcode->bytemode)
|
||
- SetOperand1AndByteFlagsWithCarry((op1 + GetOperand2()) & 0xFF, result < op1);
|
||
- else
|
||
- SetOperand1AndFlagsWithCarry(op1 + GetOperand2(), result < op1);
|
||
- NextInstruction();
|
||
-
|
||
- case RARSubInstruction:
|
||
- op1 = GetOperand1();
|
||
-#if 0 /* apparently not correctly implemented in the RAR VM */
|
||
- if (opcode->bytemode)
|
||
- SetOperand1AndByteFlagsWithCarry((op1 - GetOperand2()) & 0xFF, result > op1);
|
||
- else
|
||
-#endif
|
||
- SetOperand1AndFlagsWithCarry(op1 - GetOperand2(), result > op1);
|
||
- NextInstruction();
|
||
-
|
||
- case RARJzInstruction:
|
||
- if ((flags & ZeroFlag))
|
||
- Jump(GetOperand1());
|
||
- NextInstruction();
|
||
-
|
||
- case RARJnzInstruction:
|
||
- if (!(flags & ZeroFlag))
|
||
- Jump(GetOperand1());
|
||
- NextInstruction();
|
||
-
|
||
- case RARIncInstruction:
|
||
- if (opcode->bytemode)
|
||
- SetOperand1AndFlags((GetOperand1() + 1) & 0xFF);
|
||
- else
|
||
- SetOperand1AndFlags(GetOperand1() + 1);
|
||
- NextInstruction();
|
||
-
|
||
- case RARDecInstruction:
|
||
- if (opcode->bytemode)
|
||
- SetOperand1AndFlags((GetOperand1() - 1) & 0xFF);
|
||
- else
|
||
- SetOperand1AndFlags(GetOperand1() - 1);
|
||
- NextInstruction();
|
||
-
|
||
- case RARJmpInstruction:
|
||
- Jump(GetOperand1());
|
||
-
|
||
- case RARXorInstruction:
|
||
- SetOperand1AndFlags(GetOperand1() ^ GetOperand2());
|
||
- NextInstruction();
|
||
-
|
||
- case RARAndInstruction:
|
||
- SetOperand1AndFlags(GetOperand1() & GetOperand2());
|
||
- NextInstruction();
|
||
-
|
||
- case RAROrInstruction:
|
||
- SetOperand1AndFlags(GetOperand1() | GetOperand2());
|
||
- NextInstruction();
|
||
-
|
||
- case RARTestInstruction:
|
||
- SetFlags(GetOperand1() & GetOperand2());
|
||
- NextInstruction();
|
||
-
|
||
- case RARJsInstruction:
|
||
- if ((flags & SignFlag))
|
||
- Jump(GetOperand1());
|
||
- NextInstruction();
|
||
-
|
||
- case RARJnsInstruction:
|
||
- if (!(flags & SignFlag))
|
||
- Jump(GetOperand1());
|
||
- NextInstruction();
|
||
-
|
||
- case RARJbInstruction:
|
||
- if ((flags & CarryFlag))
|
||
- Jump(GetOperand1());
|
||
- NextInstruction();
|
||
-
|
||
- case RARJbeInstruction:
|
||
- if ((flags & (CarryFlag | ZeroFlag)))
|
||
- Jump(GetOperand1());
|
||
- NextInstruction();
|
||
-
|
||
- case RARJaInstruction:
|
||
- if (!(flags & (CarryFlag | ZeroFlag)))
|
||
- Jump(GetOperand1());
|
||
- NextInstruction();
|
||
-
|
||
- case RARJaeInstruction:
|
||
- if (!(flags & CarryFlag))
|
||
- Jump(GetOperand1());
|
||
- NextInstruction();
|
||
-
|
||
- case RARPushInstruction:
|
||
- vm->registers[7] -= 4;
|
||
- RARVirtualMachineWrite32(vm, vm->registers[7], GetOperand1());
|
||
- NextInstruction();
|
||
-
|
||
- case RARPopInstruction:
|
||
- SetOperand1(RARVirtualMachineRead32(vm, vm->registers[7]));
|
||
- vm->registers[7] += 4;
|
||
- NextInstruction();
|
||
-
|
||
- case RARCallInstruction:
|
||
- vm->registers[7] -= 4;
|
||
- RARVirtualMachineWrite32(vm, vm->registers[7], (uint32_t)(opcode - prog->opcodes + 1));
|
||
- Jump(GetOperand1());
|
||
-
|
||
- case RARRetInstruction:
|
||
- if (vm->registers[7] >= RARProgramMemorySize)
|
||
- return true;
|
||
- i = RARVirtualMachineRead32(vm, vm->registers[7]);
|
||
- vm->registers[7] += 4;
|
||
- Jump(i);
|
||
-
|
||
- case RARNotInstruction:
|
||
- SetOperand1(~GetOperand1());
|
||
- NextInstruction();
|
||
-
|
||
- case RARShlInstruction:
|
||
- op1 = GetOperand1();
|
||
- op2 = GetOperand2();
|
||
- SetOperand1AndFlagsWithCarry(op1 << op2, ((op1 << (op2 - 1)) & 0x80000000) != 0);
|
||
- NextInstruction();
|
||
-
|
||
- case RARShrInstruction:
|
||
- op1 = GetOperand1();
|
||
- op2 = GetOperand2();
|
||
- SetOperand1AndFlagsWithCarry(op1 >> op2, ((op1 >> (op2 - 1)) & 1) != 0);
|
||
- NextInstruction();
|
||
-
|
||
- case RARSarInstruction:
|
||
- op1 = GetOperand1();
|
||
- op2 = GetOperand2();
|
||
- SetOperand1AndFlagsWithCarry(((int32_t)op1) >> op2, ((op1 >> (op2 - 1)) & 1) != 0);
|
||
- NextInstruction();
|
||
-
|
||
- case RARNegInstruction:
|
||
- SetOperand1AndFlagsWithCarry(-(int32_t)GetOperand1(), result != 0);
|
||
- NextInstruction();
|
||
-
|
||
- case RARPushaInstruction:
|
||
- vm->registers[7] -= 32;
|
||
- for (i = 0; i < 8; i++)
|
||
- RARVirtualMachineWrite32(vm, vm->registers[7] + (7 - i) * 4, vm->registers[i]);
|
||
- NextInstruction();
|
||
-
|
||
- case RARPopaInstruction:
|
||
- for (i = 0; i < 8; i++)
|
||
- vm->registers[i] = RARVirtualMachineRead32(vm, vm->registers[7] + (7 - i) * 4);
|
||
- vm->registers[7] += 32;
|
||
- NextInstruction();
|
||
-
|
||
- case RARPushfInstruction:
|
||
- vm->registers[7] -= 4;
|
||
- RARVirtualMachineWrite32(vm, vm->registers[7], flags);
|
||
- NextInstruction();
|
||
-
|
||
- case RARPopfInstruction:
|
||
- flags = RARVirtualMachineRead32(vm, vm->registers[7]);
|
||
- vm->registers[7] += 4;
|
||
- NextInstruction();
|
||
-
|
||
- case RARMovzxInstruction:
|
||
- SetOperand1(GetOperand2());
|
||
- NextInstruction();
|
||
-
|
||
- case RARMovsxInstruction:
|
||
- SetOperand1(SignExtend(GetOperand2()));
|
||
- NextInstruction();
|
||
-
|
||
- case RARXchgInstruction:
|
||
- op1 = GetOperand1();
|
||
- op2 = GetOperand2();
|
||
- SetOperand1(op2);
|
||
- SetOperand2(op1);
|
||
- NextInstruction();
|
||
-
|
||
- case RARMulInstruction:
|
||
- SetOperand1(GetOperand1() * GetOperand2());
|
||
- NextInstruction();
|
||
-
|
||
- case RARDivInstruction:
|
||
- op2 = GetOperand2();
|
||
- if (op2 != 0)
|
||
- SetOperand1(GetOperand1() / op2);
|
||
- NextInstruction();
|
||
-
|
||
- case RARAdcInstruction:
|
||
- op1 = GetOperand1();
|
||
- carry = (flags & CarryFlag);
|
||
- if (opcode->bytemode)
|
||
- SetOperand1AndFlagsWithCarry((op1 + GetOperand2() + carry) & 0xFF, result < op1 || (result == op1 && carry)); /* does not correctly set sign bit */
|
||
- else
|
||
- SetOperand1AndFlagsWithCarry(op1 + GetOperand2() + carry, result < op1 || (result == op1 && carry));
|
||
- NextInstruction();
|
||
-
|
||
- case RARSbbInstruction:
|
||
- op1 = GetOperand1();
|
||
- carry = (flags & CarryFlag);
|
||
- if (opcode->bytemode)
|
||
- SetOperand1AndFlagsWithCarry((op1 - GetOperand2() - carry) & 0xFF, result > op1 || (result == op1 && carry)); /* does not correctly set sign bit */
|
||
- else
|
||
- SetOperand1AndFlagsWithCarry(op1 - GetOperand2() - carry, result > op1 || (result == op1 && carry));
|
||
- NextInstruction();
|
||
-
|
||
- case RARPrintInstruction:
|
||
- /* TODO: ??? */
|
||
- NextInstruction();
|
||
- }
|
||
- }
|
||
-
|
||
- return false;
|
||
-}
|
||
-
|
||
-/* Memory and register access */
|
||
-
|
||
-static uint32_t _RARRead32(const uint8_t *b)
|
||
-{
|
||
- return ((uint32_t)b[3] << 24) | ((uint32_t)b[2] << 16) | ((uint32_t)b[1] << 8) | (uint32_t)b[0];
|
||
-}
|
||
-
|
||
-static void _RARWrite32(uint8_t *b, uint32_t n)
|
||
-{
|
||
- b[3] = (n >> 24) & 0xFF;
|
||
- b[2] = (n >> 16) & 0xFF;
|
||
- b[1] = (n >> 8) & 0xFF;
|
||
- b[0] = n & 0xFF;
|
||
-}
|
||
-
|
||
-void RARSetVirtualMachineRegisters(RARVirtualMachine *vm, uint32_t registers[8])
|
||
-{
|
||
- if (registers)
|
||
- memcpy(vm->registers, registers, sizeof(vm->registers));
|
||
- else
|
||
- memset(vm->registers, 0, sizeof(vm->registers));
|
||
-}
|
||
-
|
||
-uint32_t RARVirtualMachineRead32(RARVirtualMachine *vm, uint32_t address)
|
||
-{
|
||
- return _RARRead32(&vm->memory[address & RARProgramMemoryMask]);
|
||
-}
|
||
-
|
||
-void RARVirtualMachineWrite32(RARVirtualMachine *vm, uint32_t address, uint32_t val)
|
||
-{
|
||
- _RARWrite32(&vm->memory[address & RARProgramMemoryMask], val);
|
||
-}
|
||
-
|
||
-uint8_t RARVirtualMachineRead8(RARVirtualMachine *vm, uint32_t address)
|
||
-{
|
||
- return vm->memory[address & RARProgramMemoryMask];
|
||
-}
|
||
-
|
||
-void RARVirtualMachineWrite8(RARVirtualMachine *vm, uint32_t address, uint8_t val)
|
||
-{
|
||
- vm->memory[address & RARProgramMemoryMask] = val;
|
||
-}
|
||
-
|
||
-static uint32_t _RARGetOperand(RARVirtualMachine *vm, uint8_t addressingmode, uint32_t value, bool bytemode)
|
||
-{
|
||
- if (RARRegisterAddressingMode(0) <= addressingmode && addressingmode <= RARRegisterAddressingMode(7)) {
|
||
- uint32_t result = vm->registers[addressingmode % 8];
|
||
- if (bytemode)
|
||
- result = result & 0xFF;
|
||
- return result;
|
||
- }
|
||
- if (RARRegisterIndirectAddressingMode(0) <= addressingmode && addressingmode <= RARRegisterIndirectAddressingMode(7)) {
|
||
- if (bytemode)
|
||
- return RARVirtualMachineRead8(vm, vm->registers[addressingmode % 8]);
|
||
- return RARVirtualMachineRead32(vm, vm->registers[addressingmode % 8]);
|
||
- }
|
||
- if (RARIndexedAbsoluteAddressingMode(0) <= addressingmode && addressingmode <= RARIndexedAbsoluteAddressingMode(7)) {
|
||
- if (bytemode)
|
||
- return RARVirtualMachineRead8(vm, value + vm->registers[addressingmode % 8]);
|
||
- return RARVirtualMachineRead32(vm, value + vm->registers[addressingmode % 8]);
|
||
- }
|
||
- if (addressingmode == RARAbsoluteAddressingMode) {
|
||
- if (bytemode)
|
||
- return RARVirtualMachineRead8(vm, value);
|
||
- return RARVirtualMachineRead32(vm, value);
|
||
- }
|
||
- /* if (addressingmode == RARImmediateAddressingMode) */
|
||
- return value;
|
||
-}
|
||
-
|
||
-static void _RARSetOperand(RARVirtualMachine *vm, uint8_t addressingmode, uint32_t value, bool bytemode, uint32_t data)
|
||
-{
|
||
- if (RARRegisterAddressingMode(0) <= addressingmode && addressingmode <= RARRegisterAddressingMode(7)) {
|
||
- if (bytemode)
|
||
- data = data & 0xFF;
|
||
- vm->registers[addressingmode % 8] = data;
|
||
- }
|
||
- else if (RARRegisterIndirectAddressingMode(0) <= addressingmode && addressingmode <= RARRegisterIndirectAddressingMode(7)) {
|
||
- if (bytemode)
|
||
- RARVirtualMachineWrite8(vm, vm->registers[addressingmode % 8], (uint8_t)data);
|
||
- else
|
||
- RARVirtualMachineWrite32(vm, vm->registers[addressingmode % 8], data);
|
||
- }
|
||
- else if (RARIndexedAbsoluteAddressingMode(0) <= addressingmode && addressingmode <= RARIndexedAbsoluteAddressingMode(7)) {
|
||
- if (bytemode)
|
||
- RARVirtualMachineWrite8(vm, value + vm->registers[addressingmode % 8], (uint8_t)data);
|
||
- else
|
||
- RARVirtualMachineWrite32(vm, value + vm->registers[addressingmode % 8], data);
|
||
- }
|
||
- else if (addressingmode == RARAbsoluteAddressingMode) {
|
||
- if (bytemode)
|
||
- RARVirtualMachineWrite8(vm, value, (uint8_t)data);
|
||
- else
|
||
- RARVirtualMachineWrite32(vm, value, data);
|
||
- }
|
||
-}
|
||
-
|
||
-/* Instruction properties */
|
||
-
|
||
-#define RAR0OperandsFlag 0
|
||
-#define RAR1OperandFlag 1
|
||
-#define RAR2OperandsFlag 2
|
||
-#define RAROperandsFlag 3
|
||
-#define RARHasByteModeFlag 4
|
||
-#define RARIsUnconditionalJumpFlag 8
|
||
-#define RARIsRelativeJumpFlag 16
|
||
-#define RARWritesFirstOperandFlag 32
|
||
-#define RARWritesSecondOperandFlag 64
|
||
-#define RARReadsStatusFlag 128
|
||
-#define RARWritesStatusFlag 256
|
||
-
|
||
-static const int InstructionFlags[RARNumberOfInstructions] = {
|
||
- /*RARMovInstruction*/ RAR2OperandsFlag | RARHasByteModeFlag | RARWritesFirstOperandFlag,
|
||
- /*RARCmpInstruction*/ RAR2OperandsFlag | RARHasByteModeFlag | RARWritesStatusFlag,
|
||
- /*RARAddInstruction*/ RAR2OperandsFlag | RARHasByteModeFlag | RARWritesFirstOperandFlag | RARWritesStatusFlag,
|
||
- /*RARSubInstruction*/ RAR2OperandsFlag | RARHasByteModeFlag | RARWritesFirstOperandFlag | RARWritesStatusFlag,
|
||
- /*RARJzInstruction*/ RAR1OperandFlag | RARIsUnconditionalJumpFlag | RARIsRelativeJumpFlag | RARReadsStatusFlag,
|
||
- /*RARJnzInstruction*/ RAR1OperandFlag | RARIsRelativeJumpFlag | RARReadsStatusFlag,
|
||
- /*RARIncInstruction*/ RAR1OperandFlag | RARHasByteModeFlag | RARWritesFirstOperandFlag | RARWritesStatusFlag,
|
||
- /*RARDecInstruction*/ RAR1OperandFlag | RARHasByteModeFlag | RARWritesFirstOperandFlag | RARWritesStatusFlag,
|
||
- /*RARJmpInstruction*/ RAR1OperandFlag | RARIsRelativeJumpFlag,
|
||
- /*RARXorInstruction*/ RAR2OperandsFlag | RARHasByteModeFlag | RARWritesFirstOperandFlag | RARWritesStatusFlag,
|
||
- /*RARAndInstruction*/ RAR2OperandsFlag | RARHasByteModeFlag | RARWritesFirstOperandFlag | RARWritesStatusFlag,
|
||
- /*RAROrInstruction*/ RAR2OperandsFlag | RARHasByteModeFlag | RARWritesFirstOperandFlag | RARWritesStatusFlag,
|
||
- /*RARTestInstruction*/ RAR2OperandsFlag | RARHasByteModeFlag | RARWritesStatusFlag,
|
||
- /*RARJsInstruction*/ RAR1OperandFlag | RARIsRelativeJumpFlag | RARReadsStatusFlag,
|
||
- /*RARJnsInstruction*/ RAR1OperandFlag | RARIsRelativeJumpFlag | RARReadsStatusFlag,
|
||
- /*RARJbInstruction*/ RAR1OperandFlag | RARIsRelativeJumpFlag | RARReadsStatusFlag,
|
||
- /*RARJbeInstruction*/ RAR1OperandFlag | RARIsRelativeJumpFlag | RARReadsStatusFlag,
|
||
- /*RARJaInstruction*/ RAR1OperandFlag | RARIsRelativeJumpFlag | RARReadsStatusFlag,
|
||
- /*RARJaeInstruction*/ RAR1OperandFlag | RARIsRelativeJumpFlag | RARReadsStatusFlag,
|
||
- /*RARPushInstruction*/ RAR1OperandFlag,
|
||
- /*RARPopInstruction*/ RAR1OperandFlag,
|
||
- /*RARCallInstruction*/ RAR1OperandFlag | RARIsRelativeJumpFlag,
|
||
- /*RARRetInstruction*/ RAR0OperandsFlag | RARIsUnconditionalJumpFlag,
|
||
- /*RARNotInstruction*/ RAR1OperandFlag | RARHasByteModeFlag | RARWritesFirstOperandFlag,
|
||
- /*RARShlInstruction*/ RAR2OperandsFlag | RARHasByteModeFlag | RARWritesFirstOperandFlag | RARWritesStatusFlag,
|
||
- /*RARShrInstruction*/ RAR2OperandsFlag | RARHasByteModeFlag | RARWritesFirstOperandFlag | RARWritesStatusFlag,
|
||
- /*RARSarInstruction*/ RAR2OperandsFlag | RARHasByteModeFlag | RARWritesFirstOperandFlag | RARWritesStatusFlag,
|
||
- /*RARNegInstruction*/ RAR1OperandFlag | RARHasByteModeFlag | RARWritesFirstOperandFlag | RARWritesStatusFlag,
|
||
- /*RARPushaInstruction*/ RAR0OperandsFlag,
|
||
- /*RARPopaInstruction*/ RAR0OperandsFlag,
|
||
- /*RARPushfInstruction*/ RAR0OperandsFlag | RARReadsStatusFlag,
|
||
- /*RARPopfInstruction*/ RAR0OperandsFlag | RARWritesStatusFlag,
|
||
- /*RARMovzxInstruction*/ RAR2OperandsFlag | RARWritesFirstOperandFlag,
|
||
- /*RARMovsxInstruction*/ RAR2OperandsFlag | RARWritesFirstOperandFlag,
|
||
- /*RARXchgInstruction*/ RAR2OperandsFlag | RARWritesFirstOperandFlag | RARWritesSecondOperandFlag | RARHasByteModeFlag,
|
||
- /*RARMulInstruction*/ RAR2OperandsFlag | RARHasByteModeFlag | RARWritesFirstOperandFlag,
|
||
- /*RARDivInstruction*/ RAR2OperandsFlag | RARHasByteModeFlag | RARWritesFirstOperandFlag,
|
||
- /*RARAdcInstruction*/ RAR2OperandsFlag | RARHasByteModeFlag | RARWritesFirstOperandFlag | RARReadsStatusFlag | RARWritesStatusFlag,
|
||
- /*RARSbbInstruction*/ RAR2OperandsFlag | RARHasByteModeFlag | RARWritesFirstOperandFlag | RARReadsStatusFlag | RARWritesStatusFlag,
|
||
- /*RARPrintInstruction*/ RAR0OperandsFlag
|
||
-};
|
||
-
|
||
-int NumberOfRARInstructionOperands(uint8_t instruction)
|
||
-{
|
||
- if (instruction >= RARNumberOfInstructions)
|
||
- return 0;
|
||
- return InstructionFlags[instruction] & RAROperandsFlag;
|
||
-}
|
||
-
|
||
-bool RARInstructionHasByteMode(uint8_t instruction)
|
||
-{
|
||
- if (instruction >= RARNumberOfInstructions)
|
||
- return false;
|
||
- return (InstructionFlags[instruction] & RARHasByteModeFlag)!=0;
|
||
-}
|
||
-
|
||
-bool RARInstructionIsUnconditionalJump(uint8_t instruction)
|
||
-{
|
||
- if (instruction >= RARNumberOfInstructions)
|
||
- return false;
|
||
- return (InstructionFlags[instruction] & RARIsUnconditionalJumpFlag) != 0;
|
||
-}
|
||
-
|
||
-bool RARInstructionIsRelativeJump(uint8_t instruction)
|
||
-{
|
||
- if (instruction >= RARNumberOfInstructions)
|
||
- return false;
|
||
- return (InstructionFlags[instruction] & RARIsRelativeJumpFlag) != 0;
|
||
-}
|
||
-
|
||
-bool RARInstructionWritesFirstOperand(uint8_t instruction)
|
||
-{
|
||
- if (instruction >= RARNumberOfInstructions)
|
||
- return false;
|
||
- return (InstructionFlags[instruction] & RARWritesFirstOperandFlag) != 0;
|
||
-}
|
||
-
|
||
-bool RARInstructionWritesSecondOperand(uint8_t instruction)
|
||
-{
|
||
- if (instruction >= RARNumberOfInstructions)
|
||
- return false;
|
||
- return (InstructionFlags[instruction] & RARWritesSecondOperandFlag) != 0;
|
||
-}
|
||
-
|
||
-/* Program debugging */
|
||
-
|
||
-#ifndef NDEBUG
|
||
-#include <stdio.h>
|
||
-
|
||
-static void RARPrintOperand(uint8_t addressingmode, uint32_t value)
|
||
-{
|
||
- if (RARRegisterAddressingMode(0) <= addressingmode && addressingmode <= RARRegisterAddressingMode(7))
|
||
- printf("r%d", addressingmode % 8);
|
||
- else if (RARRegisterIndirectAddressingMode(0) <= addressingmode && addressingmode <= RARRegisterIndirectAddressingMode(7))
|
||
- printf("@(r%d)", addressingmode % 8);
|
||
- else if (RARIndexedAbsoluteAddressingMode(0) <= addressingmode && addressingmode <= RARIndexedAbsoluteAddressingMode(7))
|
||
- printf("@(r%d+$%02x)", addressingmode % 8, value);
|
||
- else if (addressingmode == RARAbsoluteAddressingMode)
|
||
- printf("@($%02x)", value);
|
||
- else if (addressingmode == RARImmediateAddressingMode)
|
||
- printf("$%02x", value);
|
||
-}
|
||
-
|
||
-void RARPrintProgram(RARProgram *prog)
|
||
-{
|
||
- static const char *instructionNames[RARNumberOfInstructions] = {
|
||
- "Mov", "Cmp", "Add", "Sub", "Jz", "Jnz", "Inc", "Dec", "Jmp", "Xor",
|
||
- "And", "Or", "Test", "Js", "Jns", "Jb", "Jbe", "Ja", "Jae", "Push",
|
||
- "Pop", "Call", "Ret", "Not", "Shl", "Shr", "Sar", "Neg", "Pusha", "Popa",
|
||
- "Pushf", "Popf", "Movzx", "Movsx", "Xchg", "Mul", "Div", "Adc", "Sbb", "Print",
|
||
- };
|
||
-
|
||
- uint32_t i;
|
||
- for (i = 0; i < prog->length; i++) {
|
||
- RAROpcode *opcode = &prog->opcodes[i];
|
||
- int numoperands = NumberOfRARInstructionOperands(opcode->instruction);
|
||
- printf(" %02x: %s", i, instructionNames[opcode->instruction]);
|
||
- if (opcode->bytemode)
|
||
- printf("B");
|
||
- if (numoperands >= 1) {
|
||
- printf(" ");
|
||
- RARPrintOperand(opcode->addressingmode1, opcode->value1);
|
||
- }
|
||
- if (numoperands == 2) {
|
||
- printf(", ");
|
||
- RARPrintOperand(opcode->addressingmode2, opcode->value2);
|
||
- }
|
||
- printf("\n");
|
||
- }
|
||
-}
|
||
-#endif
|
||
diff --git a/cut-n-paste/unarr/rar/rarvm.h b/cut-n-paste/unarr/rar/rarvm.h
|
||
deleted file mode 100644
|
||
index 51567a9a..00000000
|
||
--- a/cut-n-paste/unarr/rar/rarvm.h
|
||
+++ /dev/null
|
||
@@ -1,117 +0,0 @@
|
||
-/* Copyright 2015 the unarr project authors (see AUTHORS file).
|
||
- License: LGPLv3 */
|
||
-
|
||
-/* adapted from https://code.google.com/p/theunarchiver/source/browse/XADMaster/RARVirtualMachine.h */
|
||
-
|
||
-#ifndef rar_vm_h
|
||
-#define rar_vm_h
|
||
-
|
||
-#include <stdint.h>
|
||
-#include <stdbool.h>
|
||
-
|
||
-#define RARProgramMemorySize 0x40000
|
||
-#define RARProgramMemoryMask (RARProgramMemorySize - 1)
|
||
-#define RARProgramWorkSize 0x3c000
|
||
-#define RARProgramGlobalSize 0x2000
|
||
-#define RARProgramSystemGlobalAddress RARProgramWorkSize
|
||
-#define RARProgramSystemGlobalSize 64
|
||
-#define RARProgramUserGlobalAddress (RARProgramSystemGlobalAddress + RARProgramSystemGlobalSize)
|
||
-#define RARProgramUserGlobalSize (RARProgramGlobalSize - RARProgramSystemGlobalSize)
|
||
-#define RARRuntimeMaxInstructions 250000000
|
||
-
|
||
-#define RARRegisterAddressingMode(n) (0 + (n))
|
||
-#define RARRegisterIndirectAddressingMode(n) (8 + (n))
|
||
-#define RARIndexedAbsoluteAddressingMode(n) (16 + (n))
|
||
-#define RARAbsoluteAddressingMode 24
|
||
-#define RARImmediateAddressingMode 25
|
||
-#define RARNumberOfAddressingModes 26
|
||
-
|
||
-typedef struct RARVirtualMachine RARVirtualMachine;
|
||
-
|
||
-struct RARVirtualMachine {
|
||
- uint32_t registers[8];
|
||
- uint8_t memory[RARProgramMemorySize + sizeof(uint32_t) /* overflow sentinel */];
|
||
-};
|
||
-
|
||
-typedef struct RARProgram_s RARProgram;
|
||
-
|
||
-/* Program building */
|
||
-
|
||
-enum {
|
||
- RARMovInstruction = 0,
|
||
- RARCmpInstruction = 1,
|
||
- RARAddInstruction = 2,
|
||
- RARSubInstruction = 3,
|
||
- RARJzInstruction = 4,
|
||
- RARJnzInstruction = 5,
|
||
- RARIncInstruction = 6,
|
||
- RARDecInstruction = 7,
|
||
- RARJmpInstruction = 8,
|
||
- RARXorInstruction = 9,
|
||
- RARAndInstruction = 10,
|
||
- RAROrInstruction = 11,
|
||
- RARTestInstruction = 12,
|
||
- RARJsInstruction = 13,
|
||
- RARJnsInstruction = 14,
|
||
- RARJbInstruction = 15,
|
||
- RARJbeInstruction = 16,
|
||
- RARJaInstruction = 17,
|
||
- RARJaeInstruction = 18,
|
||
- RARPushInstruction = 19,
|
||
- RARPopInstruction = 20,
|
||
- RARCallInstruction = 21,
|
||
- RARRetInstruction = 22,
|
||
- RARNotInstruction = 23,
|
||
- RARShlInstruction = 24,
|
||
- RARShrInstruction = 25,
|
||
- RARSarInstruction = 26,
|
||
- RARNegInstruction = 27,
|
||
- RARPushaInstruction = 28,
|
||
- RARPopaInstruction = 29,
|
||
- RARPushfInstruction = 30,
|
||
- RARPopfInstruction = 31,
|
||
- RARMovzxInstruction = 32,
|
||
- RARMovsxInstruction = 33,
|
||
- RARXchgInstruction = 34,
|
||
- RARMulInstruction = 35,
|
||
- RARDivInstruction = 36,
|
||
- RARAdcInstruction = 37,
|
||
- RARSbbInstruction = 38,
|
||
- RARPrintInstruction = 39,
|
||
- RARNumberOfInstructions = 40,
|
||
-};
|
||
-
|
||
-RARProgram *RARCreateProgram(void);
|
||
-void RARDeleteProgram(RARProgram *prog);
|
||
-bool RARProgramAddInstr(RARProgram *prog, uint8_t instruction, bool bytemode);
|
||
-bool RARSetLastInstrOperands(RARProgram *prog, uint8_t addressingmode1, uint32_t value1, uint8_t addressingmode2, uint32_t value2);
|
||
-bool RARIsProgramTerminated(RARProgram *prog);
|
||
-
|
||
-/* Execution */
|
||
-
|
||
-bool RARExecuteProgram(RARVirtualMachine *vm, RARProgram *prog);
|
||
-
|
||
-/* Memory and register access (convenience) */
|
||
-
|
||
-void RARSetVirtualMachineRegisters(RARVirtualMachine *vm, uint32_t registers[8]);
|
||
-uint32_t RARVirtualMachineRead32(RARVirtualMachine *vm, uint32_t address);
|
||
-void RARVirtualMachineWrite32(RARVirtualMachine *vm, uint32_t address, uint32_t val);
|
||
-uint8_t RARVirtualMachineRead8(RARVirtualMachine *vm, uint32_t address);
|
||
-void RARVirtualMachineWrite8(RARVirtualMachine *vm, uint32_t address, uint8_t val);
|
||
-
|
||
-/* Instruction properties */
|
||
-
|
||
-int NumberOfRARInstructionOperands(uint8_t instruction);
|
||
-bool RARInstructionHasByteMode(uint8_t instruction);
|
||
-bool RARInstructionIsUnconditionalJump(uint8_t instruction);
|
||
-bool RARInstructionIsRelativeJump(uint8_t instruction);
|
||
-bool RARInstructionWritesFirstOperand(uint8_t instruction);
|
||
-bool RARInstructionWritesSecondOperand(uint8_t instruction);
|
||
-
|
||
-/* Program debugging */
|
||
-
|
||
-#ifndef NDEBUG
|
||
-void RARPrintProgram(RARProgram *prog);
|
||
-#endif
|
||
-
|
||
-#endif
|
||
diff --git a/cut-n-paste/unarr/rar/uncompress-rar.c b/cut-n-paste/unarr/rar/uncompress-rar.c
|
||
deleted file mode 100644
|
||
index 53449ba3..00000000
|
||
--- a/cut-n-paste/unarr/rar/uncompress-rar.c
|
||
+++ /dev/null
|
||
@@ -1,1000 +0,0 @@
|
||
-/* Copyright 2015 the unarr project authors (see AUTHORS file).
|
||
- License: LGPLv3 */
|
||
-
|
||
-/* adapted from https://code.google.com/p/theunarchiver/source/browse/XADMaster/XADRAR30Handle.m */
|
||
-/* adapted from https://code.google.com/p/theunarchiver/source/browse/XADMaster/XADRAR20Handle.m */
|
||
-
|
||
-#include "rar.h"
|
||
-
|
||
-static void *gSzAlloc_Alloc(ISzAllocPtr p, size_t size) { return malloc(size); }
|
||
-static void gSzAlloc_Free(ISzAllocPtr p, void *ptr) { free(ptr); }
|
||
-static ISzAlloc gSzAlloc = { gSzAlloc_Alloc, gSzAlloc_Free };
|
||
-
|
||
-static bool br_fill(ar_archive_rar *rar, int bits)
|
||
-{
|
||
- uint8_t bytes[8];
|
||
- int count, i;
|
||
- /* read as many bits as possible */
|
||
- count = (64 - rar->uncomp.br.available) / 8;
|
||
- if (rar->progress.data_left < (size_t)count)
|
||
- count = (int)rar->progress.data_left;
|
||
-
|
||
- if (bits > rar->uncomp.br.available + 8 * count || ar_read(rar->super.stream, bytes, count) != (size_t)count) {
|
||
- if (!rar->uncomp.br.at_eof) {
|
||
- warn("Unexpected EOF during decompression (truncated file?)");
|
||
- rar->uncomp.br.at_eof = true;
|
||
- }
|
||
- return false;
|
||
- }
|
||
- rar->progress.data_left -= count;
|
||
- for (i = 0; i < count; i++) {
|
||
- rar->uncomp.br.bits = (rar->uncomp.br.bits << 8) | bytes[i];
|
||
- }
|
||
- rar->uncomp.br.available += 8 * count;
|
||
- return true;
|
||
-}
|
||
-
|
||
-static inline bool br_check(ar_archive_rar *rar, int bits)
|
||
-{
|
||
- return bits <= rar->uncomp.br.available || br_fill(rar, bits);
|
||
-}
|
||
-
|
||
-static inline uint64_t br_bits(ar_archive_rar *rar, int bits)
|
||
-{
|
||
- return (rar->uncomp.br.bits >> (rar->uncomp.br.available -= bits)) & (((uint64_t)1 << bits) - 1);
|
||
-}
|
||
-
|
||
-static Byte ByteIn_Read(const IByteIn *p)
|
||
-{
|
||
- struct ByteReader *self = (struct ByteReader *) p;
|
||
- return br_check(self->rar, 8) ? (Byte)br_bits(self->rar, 8) : 0xFF;
|
||
-}
|
||
-
|
||
-static void ByteIn_CreateVTable(struct ByteReader *br, ar_archive_rar *rar)
|
||
-{
|
||
- br->super.Read = ByteIn_Read;
|
||
- br->rar = rar;
|
||
-}
|
||
-
|
||
-/* Ppmd7 range decoder differs between 7z and RAR */
|
||
-static void PpmdRAR_RangeDec_Init(struct CPpmdRAR_RangeDec *p)
|
||
-{
|
||
- int i;
|
||
- p->Code = 0;
|
||
- p->Low = 0;
|
||
- p->Range = 0xFFFFFFFF;
|
||
- for (i = 0; i < 4; i++) {
|
||
- p->Code = (p->Code << 8) | p->Stream->Read(p->Stream);
|
||
- }
|
||
-}
|
||
-
|
||
-static void PpmdRAR_RangeDec_CreateVTable(struct CPpmdRAR_RangeDec *p, IByteIn *stream)
|
||
-{
|
||
- p->Stream = stream;
|
||
-}
|
||
-
|
||
-static bool rar_init_uncompress(struct ar_archive_rar_uncomp *uncomp, uint8_t version)
|
||
-{
|
||
- /* per XADRARParser.m @handleForSolidStreamWithObject these versions are identical */
|
||
- if (version == 29 || version == 36)
|
||
- version = 3;
|
||
- else if (version == 20 || version == 26)
|
||
- version = 2;
|
||
- else {
|
||
- warn("Unsupported compression version: %d", version);
|
||
- return false;
|
||
- }
|
||
- if (uncomp->version) {
|
||
- if (uncomp->version != version) {
|
||
- warn("Compression version mismatch: %d != %d", version, uncomp->version);
|
||
- return false;
|
||
- }
|
||
- return true;
|
||
- }
|
||
- memset(uncomp, 0, sizeof(*uncomp));
|
||
- uncomp->start_new_table = true;
|
||
- if (!lzss_initialize(&uncomp->lzss, LZSS_WINDOW_SIZE)) {
|
||
- warn("OOM during decompression");
|
||
- return false;
|
||
- }
|
||
- if (version == 3) {
|
||
- uncomp->state.v3.ppmd_escape = 2;
|
||
- uncomp->state.v3.filters.filterstart = SIZE_MAX;
|
||
- }
|
||
- uncomp->version = version;
|
||
- return true;
|
||
-}
|
||
-
|
||
-static void rar_free_codes(struct ar_archive_rar_uncomp *uncomp);
|
||
-
|
||
-void rar_clear_uncompress(struct ar_archive_rar_uncomp *uncomp)
|
||
-{
|
||
- if (!uncomp->version)
|
||
- return;
|
||
- rar_free_codes(uncomp);
|
||
- lzss_cleanup(&uncomp->lzss);
|
||
- if (uncomp->version == 3) {
|
||
- Ppmd7_Free(&uncomp->state.v3.ppmd7_context, &gSzAlloc);
|
||
- rar_clear_filters(&uncomp->state.v3.filters);
|
||
- }
|
||
- uncomp->version = 0;
|
||
-}
|
||
-
|
||
-static int rar_read_next_symbol(ar_archive_rar *rar, struct huffman_code *code)
|
||
-{
|
||
- int node = 0;
|
||
-
|
||
- if (!code->table && !rar_make_table(code))
|
||
- return -1;
|
||
-
|
||
- /* performance optimization */
|
||
- if (code->tablesize <= rar->uncomp.br.available) {
|
||
- uint16_t bits = (uint16_t)br_bits(rar, code->tablesize);
|
||
- int length = code->table[bits].length;
|
||
- int value = code->table[bits].value;
|
||
-
|
||
- if (length < 0) {
|
||
- warn("Invalid data in bitstream"); /* invalid prefix code in bitstream */
|
||
- return -1;
|
||
- }
|
||
- if (length <= code->tablesize) {
|
||
- /* Skip only length bits */
|
||
- rar->uncomp.br.available += code->tablesize - length;
|
||
- return value;
|
||
- }
|
||
-
|
||
- node = value;
|
||
- }
|
||
-
|
||
- while (!rar_is_leaf_node(code, node)) {
|
||
- uint8_t bit;
|
||
- if (!br_check(rar, 1))
|
||
- return -1;
|
||
- bit = (uint8_t)br_bits(rar, 1);
|
||
- if (code->tree[node].branches[bit] < 0) {
|
||
- warn("Invalid data in bitstream"); /* invalid prefix code in bitstream */
|
||
- return -1;
|
||
- }
|
||
- node = code->tree[node].branches[bit];
|
||
- }
|
||
-
|
||
- return code->tree[node].branches[0];
|
||
-}
|
||
-
|
||
-/***** RAR version 2 decompression *****/
|
||
-
|
||
-static void rar_free_codes_v2(struct ar_archive_rar_uncomp_v2 *uncomp_v2)
|
||
-{
|
||
- int i;
|
||
- rar_free_code(&uncomp_v2->maincode);
|
||
- rar_free_code(&uncomp_v2->offsetcode);
|
||
- rar_free_code(&uncomp_v2->lengthcode);
|
||
- for (i = 0; i < 4; i++)
|
||
- rar_free_code(&uncomp_v2->audiocode[i]);
|
||
-}
|
||
-
|
||
-static bool rar_parse_codes_v2(ar_archive_rar *rar)
|
||
-{
|
||
- struct ar_archive_rar_uncomp_v2 *uncomp_v2 = &rar->uncomp.state.v2;
|
||
- struct huffman_code precode;
|
||
- uint8_t prelengths[19];
|
||
- uint16_t i, count;
|
||
- int j, val, n;
|
||
- bool ok = false;
|
||
-
|
||
- rar_free_codes_v2(uncomp_v2);
|
||
-
|
||
- if (!br_check(rar, 2))
|
||
- return false;
|
||
- uncomp_v2->audioblock = br_bits(rar, 1) != 0;
|
||
- if (!br_bits(rar, 1))
|
||
- memset(uncomp_v2->lengthtable, 0, sizeof(uncomp_v2->lengthtable));
|
||
-
|
||
- if (uncomp_v2->audioblock) {
|
||
- if (!br_check(rar, 2))
|
||
- return false;
|
||
- uncomp_v2->numchannels = (uint8_t)br_bits(rar, 2) + 1;
|
||
- count = uncomp_v2->numchannels * 257;
|
||
- if (uncomp_v2->channel > uncomp_v2->numchannels)
|
||
- uncomp_v2->channel = 0;
|
||
- }
|
||
- else
|
||
- count = MAINCODE_SIZE_20 + OFFSETCODE_SIZE_20 + LENGTHCODE_SIZE_20;
|
||
-
|
||
- for (i = 0; i < 19; i++) {
|
||
- if (!br_check(rar, 4))
|
||
- return false;
|
||
- prelengths[i] = (uint8_t)br_bits(rar, 4);
|
||
- }
|
||
-
|
||
- memset(&precode, 0, sizeof(precode));
|
||
- if (!rar_create_code(&precode, prelengths, 19))
|
||
- goto PrecodeError;
|
||
- for (i = 0; i < count; ) {
|
||
- val = rar_read_next_symbol(rar, &precode);
|
||
- if (val < 0)
|
||
- goto PrecodeError;
|
||
- if (val < 16) {
|
||
- uncomp_v2->lengthtable[i] = (uncomp_v2->lengthtable[i] + val) & 0x0F;
|
||
- i++;
|
||
- }
|
||
- else if (val == 16) {
|
||
- if (i == 0) {
|
||
- warn("Invalid data in bitstream");
|
||
- goto PrecodeError;
|
||
- }
|
||
- if (!br_check(rar, 2))
|
||
- goto PrecodeError;
|
||
- n = (uint8_t)br_bits(rar, 2) + 3;
|
||
- for (j = 0; j < n && i < count; i++, j++) {
|
||
- uncomp_v2->lengthtable[i] = uncomp_v2->lengthtable[i - 1];
|
||
- }
|
||
- }
|
||
- else {
|
||
- if (val == 17) {
|
||
- if (!br_check(rar, 3))
|
||
- goto PrecodeError;
|
||
- n = (uint8_t)br_bits(rar, 3) + 3;
|
||
- }
|
||
- else {
|
||
- if (!br_check(rar, 7))
|
||
- goto PrecodeError;
|
||
- n = (uint8_t)br_bits(rar, 7) + 11;
|
||
- }
|
||
- for (j = 0; j < n && i < count; i++, j++) {
|
||
- uncomp_v2->lengthtable[i] = 0;
|
||
- }
|
||
- }
|
||
- }
|
||
- ok = true;
|
||
-PrecodeError:
|
||
- rar_free_code(&precode);
|
||
- if (!ok)
|
||
- return false;
|
||
-
|
||
- if (uncomp_v2->audioblock) {
|
||
- for (i = 0; i < uncomp_v2->numchannels; i++) {
|
||
- if (!rar_create_code(&uncomp_v2->audiocode[i], uncomp_v2->lengthtable + i * 257, 257))
|
||
- return false;
|
||
- }
|
||
- }
|
||
- else {
|
||
- if (!rar_create_code(&uncomp_v2->maincode, uncomp_v2->lengthtable, MAINCODE_SIZE_20))
|
||
- return false;
|
||
- if (!rar_create_code(&uncomp_v2->offsetcode, uncomp_v2->lengthtable + MAINCODE_SIZE_20, OFFSETCODE_SIZE_20))
|
||
- return false;
|
||
- if (!rar_create_code(&uncomp_v2->lengthcode, uncomp_v2->lengthtable + MAINCODE_SIZE_20 + OFFSETCODE_SIZE_20, LENGTHCODE_SIZE_20))
|
||
- return false;
|
||
- }
|
||
-
|
||
- rar->uncomp.start_new_table = false;
|
||
- return true;
|
||
-}
|
||
-
|
||
-static uint8_t rar_decode_audio(struct AudioState *state, int8_t *channeldelta, int8_t delta)
|
||
-{
|
||
- uint8_t predbyte, byte;
|
||
- int prederror;
|
||
-
|
||
- state->delta[3] = state->delta[2];
|
||
- state->delta[2] = state->delta[1];
|
||
- state->delta[1] = state->lastdelta - state->delta[0];
|
||
- state->delta[0] = state->lastdelta;
|
||
-
|
||
- predbyte = ((8 * state->lastbyte + state->weight[0] * state->delta[0] + state->weight[1] * state->delta[1] + state->weight[2] * state->delta[2] + state->weight[3] * state->delta[3] + state->weight[4] * *channeldelta) >> 3) & 0xFF;
|
||
- byte = (predbyte - delta) & 0xFF;
|
||
-
|
||
- prederror = delta << 3;
|
||
- state->error[0] += abs(prederror);
|
||
- state->error[1] += abs(prederror - state->delta[0]); state->error[2] += abs(prederror + state->delta[0]);
|
||
- state->error[3] += abs(prederror - state->delta[1]); state->error[4] += abs(prederror + state->delta[1]);
|
||
- state->error[5] += abs(prederror - state->delta[2]); state->error[6] += abs(prederror + state->delta[2]);
|
||
- state->error[7] += abs(prederror - state->delta[3]); state->error[8] += abs(prederror + state->delta[3]);
|
||
- state->error[9] += abs(prederror - *channeldelta); state->error[10] += abs(prederror + *channeldelta);
|
||
-
|
||
- *channeldelta = state->lastdelta = (int8_t)(byte - state->lastbyte);
|
||
- state->lastbyte = byte;
|
||
-
|
||
- if (!(++state->count & 0x1F)) {
|
||
- uint8_t i, idx = 0;
|
||
- for (i = 1; i < 11; i++) {
|
||
- if (state->error[i] < state->error[idx])
|
||
- idx = i;
|
||
- }
|
||
- memset(state->error, 0, sizeof(state->error));
|
||
-
|
||
- switch (idx) {
|
||
- case 1: if (state->weight[0] >= -16) state->weight[0]--; break;
|
||
- case 2: if (state->weight[0] < 16) state->weight[0]++; break;
|
||
- case 3: if (state->weight[1] >= -16) state->weight[1]--; break;
|
||
- case 4: if (state->weight[1] < 16) state->weight[1]++; break;
|
||
- case 5: if (state->weight[2] >= -16) state->weight[2]--; break;
|
||
- case 6: if (state->weight[2] < 16) state->weight[2]++; break;
|
||
- case 7: if (state->weight[3] >= -16) state->weight[3]--; break;
|
||
- case 8: if (state->weight[3] < 16) state->weight[3]++; break;
|
||
- case 9: if (state->weight[4] >= -16) state->weight[4]--; break;
|
||
- case 10: if (state->weight[4] < 16) state->weight[4]++; break;
|
||
- }
|
||
- }
|
||
-
|
||
- return byte;
|
||
-}
|
||
-
|
||
-static int64_t rar_expand_v2(ar_archive_rar *rar, int64_t end)
|
||
-{
|
||
- static const uint8_t lengthbases[] =
|
||
- { 0, 1, 2, 3, 4, 5, 6,
|
||
- 7, 8, 10, 12, 14, 16, 20,
|
||
- 24, 28, 32, 40, 48, 56, 64,
|
||
- 80, 96, 112, 128, 160, 192, 224 };
|
||
- static const uint8_t lengthbits[] =
|
||
- { 0, 0, 0, 0, 0, 0, 0,
|
||
- 0, 1, 1, 1, 1, 2, 2,
|
||
- 2, 2, 3, 3, 3, 3, 4,
|
||
- 4, 4, 4, 5, 5, 5, 5 };
|
||
- static const int32_t offsetbases[] =
|
||
- { 0, 1, 2, 3, 4, 6,
|
||
- 8, 12, 16, 24, 32, 48,
|
||
- 64, 96, 128, 192, 256, 384,
|
||
- 512, 768, 1024, 1536, 2048, 3072,
|
||
- 4096, 6144, 8192, 12288, 16384, 24576,
|
||
- 32768, 49152, 65536, 98304, 131072, 196608,
|
||
- 262144, 327680, 393216, 458752, 524288, 589824,
|
||
- 655360, 720896, 786432, 851968, 917504, 983040 };
|
||
- static const uint8_t offsetbits[] =
|
||
- { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4,
|
||
- 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10,
|
||
- 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16,
|
||
- 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 };
|
||
- static const uint8_t shortbases[] =
|
||
- { 0, 4, 8, 16, 32, 64, 128, 192 };
|
||
- static const uint8_t shortbits[] =
|
||
- { 2, 2, 3, 4, 5, 6, 6, 6 };
|
||
-
|
||
- struct ar_archive_rar_uncomp_v2 *uncomp_v2 = &rar->uncomp.state.v2;
|
||
- LZSS *lzss = &rar->uncomp.lzss;
|
||
- int symbol, offs, len;
|
||
-
|
||
- if ((uint64_t)end > rar->super.entry_size_uncompressed + rar->solid.size_total)
|
||
- end = rar->super.entry_size_uncompressed + rar->solid.size_total;
|
||
-
|
||
- for (;;) {
|
||
- if (lzss_position(lzss) >= end)
|
||
- return end;
|
||
-
|
||
- if (uncomp_v2->audioblock) {
|
||
- uint8_t byte;
|
||
- symbol = rar_read_next_symbol(rar, &uncomp_v2->audiocode[uncomp_v2->channel]);
|
||
- if (symbol < 0)
|
||
- return -1;
|
||
- if (symbol == 256) {
|
||
- rar->uncomp.start_new_table = true;
|
||
- return lzss_position(lzss);
|
||
- }
|
||
- byte = rar_decode_audio(&uncomp_v2->audiostate[uncomp_v2->channel], &uncomp_v2->channeldelta, (int8_t)(uint8_t)symbol);
|
||
- uncomp_v2->channel++;
|
||
- if (uncomp_v2->channel == uncomp_v2->numchannels)
|
||
- uncomp_v2->channel = 0;
|
||
- lzss_emit_literal(lzss, byte);
|
||
- continue;
|
||
- }
|
||
-
|
||
- symbol = rar_read_next_symbol(rar, &uncomp_v2->maincode);
|
||
- if (symbol < 0)
|
||
- return -1;
|
||
- if (symbol < 256) {
|
||
- lzss_emit_literal(lzss, (uint8_t)symbol);
|
||
- continue;
|
||
- }
|
||
- if (symbol == 256) {
|
||
- offs = uncomp_v2->lastoffset;
|
||
- len = uncomp_v2->lastlength;
|
||
- }
|
||
- else if (symbol <= 260) {
|
||
- int idx = symbol - 256;
|
||
- int lensymbol = rar_read_next_symbol(rar, &uncomp_v2->lengthcode);
|
||
- offs = uncomp_v2->oldoffset[(uncomp_v2->oldoffsetindex - idx) & 0x03];
|
||
- if (lensymbol < 0 || lensymbol > (int)(sizeof(lengthbases) / sizeof(lengthbases[0])) || lensymbol > (int)(sizeof(lengthbits) / sizeof(lengthbits[0]))) {
|
||
- warn("Invalid data in bitstream");
|
||
- return -1;
|
||
- }
|
||
- len = lengthbases[lensymbol] + 2;
|
||
- if (lengthbits[lensymbol] > 0) {
|
||
- if (!br_check(rar, lengthbits[lensymbol]))
|
||
- return -1;
|
||
- len += (uint8_t)br_bits(rar, lengthbits[lensymbol]);
|
||
- }
|
||
- if (offs >= 0x40000)
|
||
- len++;
|
||
- if (offs >= 0x2000)
|
||
- len++;
|
||
- if (offs >= 0x101)
|
||
- len++;
|
||
- }
|
||
- else if (symbol <= 268) {
|
||
- int idx = symbol - 261;
|
||
- offs = shortbases[idx] + 1;
|
||
- if (shortbits[idx] > 0) {
|
||
- if (!br_check(rar, shortbits[idx]))
|
||
- return -1;
|
||
- offs += (uint8_t)br_bits(rar, shortbits[idx]);
|
||
- }
|
||
- len = 2;
|
||
- }
|
||
- else if (symbol == 269) {
|
||
- rar->uncomp.start_new_table = true;
|
||
- return lzss_position(lzss);
|
||
- }
|
||
- else {
|
||
- int idx = symbol - 270;
|
||
- int offssymbol;
|
||
- if (idx > (int)(sizeof(lengthbases) / sizeof(lengthbases[0])) || idx > (int)(sizeof(lengthbits) / sizeof(lengthbits[0]))) {
|
||
- warn("Invalid data in bitstream");
|
||
- return -1;
|
||
- }
|
||
- len = lengthbases[idx] + 3;
|
||
- if (lengthbits[idx] > 0) {
|
||
- if (!br_check(rar, lengthbits[idx]))
|
||
- return -1;
|
||
- len += (uint8_t)br_bits(rar, lengthbits[idx]);
|
||
- }
|
||
- offssymbol = rar_read_next_symbol(rar, &uncomp_v2->offsetcode);
|
||
- if (offssymbol < 0 || offssymbol > (int)(sizeof(offsetbases) / sizeof(offsetbases[0])) || offssymbol > (int)(sizeof(offsetbits) / sizeof(offsetbits[0]))) {
|
||
- warn("Invalid data in bitstream");
|
||
- return -1;
|
||
- }
|
||
- offs = offsetbases[offssymbol] + 1;
|
||
- if (offsetbits[offssymbol] > 0) {
|
||
- if (!br_check(rar, offsetbits[offssymbol]))
|
||
- return -1;
|
||
- offs += (int)br_bits(rar, offsetbits[offssymbol]);
|
||
- }
|
||
- if (offs >= 0x40000)
|
||
- len++;
|
||
- if (offs >= 0x2000)
|
||
- len++;
|
||
- }
|
||
-
|
||
- uncomp_v2->lastoffset = uncomp_v2->oldoffset[uncomp_v2->oldoffsetindex++ & 0x03] = offs;
|
||
- uncomp_v2->lastlength = len;
|
||
-
|
||
- lzss_emit_match(lzss, offs, len);
|
||
- }
|
||
-}
|
||
-
|
||
-/***** RAR version 3 decompression *****/
|
||
-
|
||
-static void rar_free_codes(struct ar_archive_rar_uncomp *uncomp)
|
||
-{
|
||
- struct ar_archive_rar_uncomp_v3 *uncomp_v3 = &uncomp->state.v3;
|
||
-
|
||
- if (uncomp->version == 2) {
|
||
- rar_free_codes_v2(&uncomp->state.v2);
|
||
- return;
|
||
- }
|
||
-
|
||
- rar_free_code(&uncomp_v3->maincode);
|
||
- rar_free_code(&uncomp_v3->offsetcode);
|
||
- rar_free_code(&uncomp_v3->lowoffsetcode);
|
||
- rar_free_code(&uncomp_v3->lengthcode);
|
||
-}
|
||
-
|
||
-static bool rar_parse_codes(ar_archive_rar *rar)
|
||
-{
|
||
- struct ar_archive_rar_uncomp_v3 *uncomp_v3 = &rar->uncomp.state.v3;
|
||
-
|
||
- if (rar->uncomp.version == 2)
|
||
- return rar_parse_codes_v2(rar);
|
||
-
|
||
- rar_free_codes(&rar->uncomp);
|
||
-
|
||
- br_clear_leftover_bits(&rar->uncomp);
|
||
-
|
||
- if (!br_check(rar, 1))
|
||
- return false;
|
||
- uncomp_v3->is_ppmd_block = br_bits(rar, 1) != 0;
|
||
- if (uncomp_v3->is_ppmd_block) {
|
||
- uint8_t ppmd_flags;
|
||
- uint32_t max_alloc = 0;
|
||
-
|
||
- if (!br_check(rar, 7))
|
||
- return false;
|
||
- ppmd_flags = (uint8_t)br_bits(rar, 7);
|
||
- if ((ppmd_flags & 0x20)) {
|
||
- if (!br_check(rar, 8))
|
||
- return false;
|
||
- max_alloc = ((uint8_t)br_bits(rar, 8) + 1) << 20;
|
||
- }
|
||
- if ((ppmd_flags & 0x40)) {
|
||
- if (!br_check(rar, 8))
|
||
- return false;
|
||
- uncomp_v3->ppmd_escape = (uint8_t)br_bits(rar, 8);
|
||
- }
|
||
- if ((ppmd_flags & 0x20)) {
|
||
- uint32_t maxorder = (ppmd_flags & 0x1F) + 1;
|
||
- if (maxorder == 1)
|
||
- return false;
|
||
- if (maxorder > 16)
|
||
- maxorder = 16 + (maxorder - 16) * 3;
|
||
-
|
||
- Ppmd7_Free(&uncomp_v3->ppmd7_context, &gSzAlloc);
|
||
- Ppmd7_Construct(&uncomp_v3->ppmd7_context);
|
||
- if (!Ppmd7_Alloc(&uncomp_v3->ppmd7_context, max_alloc, &gSzAlloc)) {
|
||
- warn("OOM during decompression");
|
||
- return false;
|
||
- }
|
||
- ByteIn_CreateVTable(&uncomp_v3->bytein, rar);
|
||
- PpmdRAR_RangeDec_CreateVTable(&uncomp_v3->range_dec, &uncomp_v3->bytein.super);
|
||
- PpmdRAR_RangeDec_Init(&uncomp_v3->range_dec);
|
||
- Ppmd7_Init(&uncomp_v3->ppmd7_context, maxorder);
|
||
- }
|
||
- else {
|
||
- if (!Ppmd7_WasAllocated(&uncomp_v3->ppmd7_context)) {
|
||
- warn("Invalid data in bitstream"); /* invalid PPMd sequence */
|
||
- return false;
|
||
- }
|
||
- PpmdRAR_RangeDec_Init(&uncomp_v3->range_dec);
|
||
- }
|
||
- }
|
||
- else {
|
||
- struct huffman_code precode;
|
||
- uint8_t bitlengths[20];
|
||
- uint8_t zerocount;
|
||
- int i, j, val, n;
|
||
- bool ok = false;
|
||
-
|
||
- if (!br_check(rar, 1))
|
||
- return false;
|
||
- if (!br_bits(rar, 1))
|
||
- memset(uncomp_v3->lengthtable, 0, sizeof(uncomp_v3->lengthtable));
|
||
- memset(&bitlengths, 0, sizeof(bitlengths));
|
||
- for (i = 0; i < sizeof(bitlengths); i++) {
|
||
- if (!br_check(rar, 4))
|
||
- return false;
|
||
- bitlengths[i] = (uint8_t)br_bits(rar, 4);
|
||
- if (bitlengths[i] == 0x0F) {
|
||
- if (!br_check(rar, 4))
|
||
- return false;
|
||
- zerocount = (uint8_t)br_bits(rar, 4);
|
||
- if (zerocount) {
|
||
- for (j = 0; j < zerocount + 2 && i < sizeof(bitlengths); j++) {
|
||
- bitlengths[i++] = 0;
|
||
- }
|
||
- i--;
|
||
- }
|
||
- }
|
||
- }
|
||
-
|
||
- memset(&precode, 0, sizeof(precode));
|
||
- if (!rar_create_code(&precode, bitlengths, sizeof(bitlengths)))
|
||
- goto PrecodeError;
|
||
- for (i = 0; i < HUFFMAN_TABLE_SIZE; ) {
|
||
- val = rar_read_next_symbol(rar, &precode);
|
||
- if (val < 0)
|
||
- goto PrecodeError;
|
||
- if (val < 16) {
|
||
- uncomp_v3->lengthtable[i] = (uncomp_v3->lengthtable[i] + val) & 0x0F;
|
||
- i++;
|
||
- }
|
||
- else if (val < 18) {
|
||
- if (i == 0) {
|
||
- warn("Invalid data in bitstream");
|
||
- goto PrecodeError;
|
||
- }
|
||
- if (val == 16) {
|
||
- if (!br_check(rar, 3))
|
||
- goto PrecodeError;
|
||
- n = (uint8_t)br_bits(rar, 3) + 3;
|
||
- }
|
||
- else {
|
||
- if (!br_check(rar, 7))
|
||
- goto PrecodeError;
|
||
- n = (uint8_t)br_bits(rar, 7) + 11;
|
||
- }
|
||
- for (j = 0; j < n && i < HUFFMAN_TABLE_SIZE; i++, j++) {
|
||
- uncomp_v3->lengthtable[i] = uncomp_v3->lengthtable[i - 1];
|
||
- }
|
||
- }
|
||
- else {
|
||
- if (val == 18) {
|
||
- if (!br_check(rar, 3))
|
||
- goto PrecodeError;
|
||
- n = (uint8_t)br_bits(rar, 3) + 3;
|
||
- }
|
||
- else {
|
||
- if (!br_check(rar, 7))
|
||
- goto PrecodeError;
|
||
- n = (uint8_t)br_bits(rar, 7) + 11;
|
||
- }
|
||
- for (j = 0; j < n && i < HUFFMAN_TABLE_SIZE; i++, j++) {
|
||
- uncomp_v3->lengthtable[i] = 0;
|
||
- }
|
||
- }
|
||
- }
|
||
- ok = true;
|
||
-PrecodeError:
|
||
- rar_free_code(&precode);
|
||
- if (!ok)
|
||
- return false;
|
||
-
|
||
- if (!rar_create_code(&uncomp_v3->maincode, uncomp_v3->lengthtable, MAINCODE_SIZE))
|
||
- return false;
|
||
- if (!rar_create_code(&uncomp_v3->offsetcode, uncomp_v3->lengthtable + MAINCODE_SIZE, OFFSETCODE_SIZE))
|
||
- return false;
|
||
- if (!rar_create_code(&uncomp_v3->lowoffsetcode, uncomp_v3->lengthtable + MAINCODE_SIZE + OFFSETCODE_SIZE, LOWOFFSETCODE_SIZE))
|
||
- return false;
|
||
- if (!rar_create_code(&uncomp_v3->lengthcode, uncomp_v3->lengthtable + MAINCODE_SIZE + OFFSETCODE_SIZE + LOWOFFSETCODE_SIZE, LENGTHCODE_SIZE))
|
||
- return false;
|
||
- }
|
||
-
|
||
- rar->uncomp.start_new_table = false;
|
||
- return true;
|
||
-}
|
||
-
|
||
-static bool rar_read_filter(ar_archive_rar *rar, bool (* decode_byte)(ar_archive_rar *rar, uint8_t *byte), int64_t *end)
|
||
-{
|
||
- uint8_t flags, val, *code;
|
||
- uint16_t length, i;
|
||
-
|
||
- if (!decode_byte(rar, &flags))
|
||
- return false;
|
||
- length = (flags & 0x07) + 1;
|
||
- if (length == 7) {
|
||
- if (!decode_byte(rar, &val))
|
||
- return false;
|
||
- length = val + 7;
|
||
- }
|
||
- else if (length == 8) {
|
||
- if (!decode_byte(rar, &val))
|
||
- return false;
|
||
- length = val << 8;
|
||
- if (!decode_byte(rar, &val))
|
||
- return false;
|
||
- length |= val;
|
||
- }
|
||
-
|
||
- code = malloc(length);
|
||
- if (!code) {
|
||
- warn("OOM during decompression");
|
||
- return false;
|
||
- }
|
||
- for (i = 0; i < length; i++) {
|
||
- if (!decode_byte(rar, &code[i])) {
|
||
- free(code);
|
||
- return false;
|
||
- }
|
||
- }
|
||
- if (!rar_parse_filter(rar, code, length, flags)) {
|
||
- free(code);
|
||
- return false;
|
||
- }
|
||
- free(code);
|
||
-
|
||
- if (rar->uncomp.state.v3.filters.filterstart < (size_t)*end)
|
||
- *end = rar->uncomp.state.v3.filters.filterstart;
|
||
-
|
||
- return true;
|
||
-}
|
||
-
|
||
-static inline bool rar_decode_ppmd7_symbol(struct ar_archive_rar_uncomp_v3 *uncomp_v3, Byte *symbol)
|
||
-{
|
||
- int value = Ppmd7z_DecodeSymbol(&uncomp_v3->ppmd7_context);
|
||
- if (value < 0) {
|
||
- warn("Invalid data in bitstream"); /* invalid PPMd symbol */
|
||
- return false;
|
||
- }
|
||
- *symbol = (Byte)value;
|
||
- return true;
|
||
-}
|
||
-
|
||
-static bool rar_decode_byte(ar_archive_rar *rar, uint8_t *byte)
|
||
-{
|
||
- if (!br_check(rar, 8))
|
||
- return false;
|
||
- *byte = (uint8_t)br_bits(rar, 8);
|
||
- return true;
|
||
-}
|
||
-
|
||
-static bool rar_decode_ppmd7_byte(ar_archive_rar *rar, uint8_t *byte)
|
||
-{
|
||
- return rar_decode_ppmd7_symbol(&rar->uncomp.state.v3, byte);
|
||
-}
|
||
-
|
||
-static bool rar_handle_ppmd_sequence(ar_archive_rar *rar, int64_t *end)
|
||
-{
|
||
- struct ar_archive_rar_uncomp_v3 *uncomp_v3 = &rar->uncomp.state.v3;
|
||
- LZSS *lzss = &rar->uncomp.lzss;
|
||
- Byte sym, code, length;
|
||
- int lzss_offset;
|
||
-
|
||
- if (!rar_decode_ppmd7_symbol(uncomp_v3, &sym))
|
||
- return false;
|
||
- if (sym != uncomp_v3->ppmd_escape) {
|
||
- lzss_emit_literal(lzss, sym);
|
||
- return true;
|
||
- }
|
||
-
|
||
- if (!rar_decode_ppmd7_symbol(uncomp_v3, &code))
|
||
- return false;
|
||
- switch (code) {
|
||
- case 0:
|
||
- return rar_parse_codes(rar);
|
||
-
|
||
- case 2:
|
||
- rar->uncomp.start_new_table = true;
|
||
- return true;
|
||
-
|
||
- case 3:
|
||
- return rar_read_filter(rar, rar_decode_ppmd7_byte, end);
|
||
-
|
||
- case 4:
|
||
- if (!rar_decode_ppmd7_symbol(uncomp_v3, &code))
|
||
- return false;
|
||
- lzss_offset = code << 16;
|
||
- if (!rar_decode_ppmd7_symbol(uncomp_v3, &code))
|
||
- return false;
|
||
- lzss_offset |= code << 8;
|
||
- if (!rar_decode_ppmd7_symbol(uncomp_v3, &code))
|
||
- return false;
|
||
- lzss_offset |= code;
|
||
- if (!rar_decode_ppmd7_symbol(uncomp_v3, &length))
|
||
- return false;
|
||
- lzss_emit_match(lzss, lzss_offset + 2, length + 32);
|
||
- return true;
|
||
-
|
||
- case 5:
|
||
- if (!rar_decode_ppmd7_symbol(uncomp_v3, &length))
|
||
- return false;
|
||
- lzss_emit_match(lzss, 1, length + 4);
|
||
- return true;
|
||
-
|
||
- default:
|
||
- lzss_emit_literal(lzss, sym);
|
||
- return true;
|
||
- }
|
||
-}
|
||
-
|
||
-int64_t rar_expand(ar_archive_rar *rar, int64_t end)
|
||
-{
|
||
- static const uint8_t lengthbases[] =
|
||
- { 0, 1, 2, 3, 4, 5, 6,
|
||
- 7, 8, 10, 12, 14, 16, 20,
|
||
- 24, 28, 32, 40, 48, 56, 64,
|
||
- 80, 96, 112, 128, 160, 192, 224 };
|
||
- static const uint8_t lengthbits[] =
|
||
- { 0, 0, 0, 0, 0, 0, 0,
|
||
- 0, 1, 1, 1, 1, 2, 2,
|
||
- 2, 2, 3, 3, 3, 3, 4,
|
||
- 4, 4, 4, 5, 5, 5, 5 };
|
||
- static const int32_t offsetbases[] =
|
||
- { 0, 1, 2, 3, 4, 6,
|
||
- 8, 12, 16, 24, 32, 48,
|
||
- 64, 96, 128, 192, 256, 384,
|
||
- 512, 768, 1024, 1536, 2048, 3072,
|
||
- 4096, 6144, 8192, 12288, 16384, 24576,
|
||
- 32768, 49152, 65536, 98304, 131072, 196608,
|
||
- 262144, 327680, 393216, 458752, 524288, 589824,
|
||
- 655360, 720896, 786432, 851968, 917504, 983040,
|
||
- 1048576, 1310720, 1572864, 1835008, 2097152, 2359296,
|
||
- 2621440, 2883584, 3145728, 3407872, 3670016, 3932160 };
|
||
- static const uint8_t offsetbits[] =
|
||
- { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4,
|
||
- 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10,
|
||
- 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16,
|
||
- 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||
- 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18 };
|
||
- static const uint8_t shortbases[] =
|
||
- { 0, 4, 8, 16, 32, 64, 128, 192 };
|
||
- static const uint8_t shortbits[] =
|
||
- { 2, 2, 3, 4, 5, 6, 6, 6 };
|
||
-
|
||
- struct ar_archive_rar_uncomp_v3 *uncomp_v3 = &rar->uncomp.state.v3;
|
||
- LZSS *lzss = &rar->uncomp.lzss;
|
||
- int symbol, offs, len, i;
|
||
-
|
||
- if (rar->uncomp.version == 2)
|
||
- return rar_expand_v2(rar, end);
|
||
-
|
||
- for (;;) {
|
||
- if (lzss_position(lzss) >= end)
|
||
- return end;
|
||
-
|
||
- if (uncomp_v3->is_ppmd_block) {
|
||
- if (!rar_handle_ppmd_sequence(rar, &end))
|
||
- return -1;
|
||
- if (rar->uncomp.start_new_table)
|
||
- return lzss_position(lzss);
|
||
- continue;
|
||
- }
|
||
-
|
||
- symbol = rar_read_next_symbol(rar, &uncomp_v3->maincode);
|
||
- if (symbol < 0)
|
||
- return -1;
|
||
- if (symbol < 256) {
|
||
- lzss_emit_literal(lzss, (uint8_t)symbol);
|
||
- continue;
|
||
- }
|
||
- if (symbol == 256) {
|
||
- if (!br_check(rar, 1))
|
||
- return -1;
|
||
- if (!br_bits(rar, 1)) {
|
||
- if (!br_check(rar, 1))
|
||
- return -1;
|
||
- rar->uncomp.start_new_table = br_bits(rar, 1) != 0;
|
||
- return lzss_position(lzss);
|
||
- }
|
||
- if (!rar_parse_codes(rar))
|
||
- return -1;
|
||
- continue;
|
||
- }
|
||
- if (symbol == 257) {
|
||
- if (!rar_read_filter(rar, rar_decode_byte, &end))
|
||
- return -1;
|
||
- continue;
|
||
- }
|
||
- if (symbol == 258) {
|
||
- if (uncomp_v3->lastlength == 0)
|
||
- continue;
|
||
- offs = uncomp_v3->lastoffset;
|
||
- len = uncomp_v3->lastlength;
|
||
- }
|
||
- else if (symbol <= 262) {
|
||
- int idx = symbol - 259;
|
||
- int lensymbol = rar_read_next_symbol(rar, &uncomp_v3->lengthcode);
|
||
- offs = uncomp_v3->oldoffset[idx];
|
||
- if (lensymbol < 0 || lensymbol > (int)(sizeof(lengthbases) / sizeof(lengthbases[0])) || lensymbol > (int)(sizeof(lengthbits) / sizeof(lengthbits[0]))) {
|
||
- warn("Invalid data in bitstream");
|
||
- return -1;
|
||
- }
|
||
- len = lengthbases[lensymbol] + 2;
|
||
- if (lengthbits[lensymbol] > 0) {
|
||
- if (!br_check(rar, lengthbits[lensymbol]))
|
||
- return -1;
|
||
- len += (uint8_t)br_bits(rar, lengthbits[lensymbol]);
|
||
- }
|
||
- for (i = idx; i > 0; i--)
|
||
- uncomp_v3->oldoffset[i] = uncomp_v3->oldoffset[i - 1];
|
||
- uncomp_v3->oldoffset[0] = offs;
|
||
- }
|
||
- else if (symbol <= 270) {
|
||
- int idx = symbol - 263;
|
||
- offs = shortbases[idx] + 1;
|
||
- if (shortbits[idx] > 0) {
|
||
- if (!br_check(rar, shortbits[idx]))
|
||
- return -1;
|
||
- offs += (uint8_t)br_bits(rar, shortbits[idx]);
|
||
- }
|
||
- len = 2;
|
||
- for (i = 3; i > 0; i--)
|
||
- uncomp_v3->oldoffset[i] = uncomp_v3->oldoffset[i - 1];
|
||
- uncomp_v3->oldoffset[0] = offs;
|
||
- }
|
||
- else {
|
||
- int idx = symbol - 271;
|
||
- int offssymbol;
|
||
- if (idx > (int)(sizeof(lengthbases) / sizeof(lengthbases[0])) || idx > (int)(sizeof(lengthbits) / sizeof(lengthbits[0]))) {
|
||
- warn("Invalid data in bitstream");
|
||
- return -1;
|
||
- }
|
||
- len = lengthbases[idx] + 3;
|
||
- if (lengthbits[idx] > 0) {
|
||
- if (!br_check(rar, lengthbits[idx]))
|
||
- return -1;
|
||
- len += (uint8_t)br_bits(rar, lengthbits[idx]);
|
||
- }
|
||
- offssymbol = rar_read_next_symbol(rar, &uncomp_v3->offsetcode);
|
||
- if (offssymbol < 0 || offssymbol > (int)(sizeof(offsetbases) / sizeof(offsetbases[0])) || offssymbol > (int)(sizeof(offsetbits) / sizeof(offsetbits[0]))) {
|
||
- warn("Invalid data in bitstream");
|
||
- return -1;
|
||
- }
|
||
- offs = offsetbases[offssymbol] + 1;
|
||
- if (offsetbits[offssymbol] > 0) {
|
||
- if (offssymbol > 9) {
|
||
- if (offsetbits[offssymbol] > 4) {
|
||
- if (!br_check(rar, offsetbits[offssymbol] - 4))
|
||
- return -1;
|
||
- offs += (int)br_bits(rar, offsetbits[offssymbol] - 4) << 4;
|
||
- }
|
||
- if (uncomp_v3->numlowoffsetrepeats > 0) {
|
||
- uncomp_v3->numlowoffsetrepeats--;
|
||
- offs += uncomp_v3->lastlowoffset;
|
||
- }
|
||
- else {
|
||
- int lowoffsetsymbol = rar_read_next_symbol(rar, &uncomp_v3->lowoffsetcode);
|
||
- if (lowoffsetsymbol < 0)
|
||
- return -1;
|
||
- if (lowoffsetsymbol == 16) {
|
||
- uncomp_v3->numlowoffsetrepeats = 15;
|
||
- offs += uncomp_v3->lastlowoffset;
|
||
- }
|
||
- else {
|
||
- offs += lowoffsetsymbol;
|
||
- uncomp_v3->lastlowoffset = lowoffsetsymbol;
|
||
- }
|
||
- }
|
||
- }
|
||
- else {
|
||
- if (!br_check(rar, offsetbits[offssymbol]))
|
||
- return -1;
|
||
- offs += (int)br_bits(rar, offsetbits[offssymbol]);
|
||
- }
|
||
- }
|
||
-
|
||
- if (offs >= 0x40000)
|
||
- len++;
|
||
- if (offs >= 0x2000)
|
||
- len++;
|
||
-
|
||
- for (i = 3; i > 0; i--)
|
||
- uncomp_v3->oldoffset[i] = uncomp_v3->oldoffset[i - 1];
|
||
- uncomp_v3->oldoffset[0] = offs;
|
||
- }
|
||
-
|
||
- uncomp_v3->lastoffset = offs;
|
||
- uncomp_v3->lastlength = len;
|
||
-
|
||
- lzss_emit_match(lzss, offs, len);
|
||
- }
|
||
-}
|
||
-
|
||
-bool rar_uncompress_part(ar_archive_rar *rar, void *buffer, size_t buffer_size)
|
||
-{
|
||
- struct ar_archive_rar_uncomp *uncomp = &rar->uncomp;
|
||
- struct ar_archive_rar_uncomp_v3 *uncomp_v3 = NULL;
|
||
- size_t end;
|
||
-
|
||
- if (!rar_init_uncompress(uncomp, rar->entry.version))
|
||
- return false;
|
||
- if (uncomp->version == 3)
|
||
- uncomp_v3 = &uncomp->state.v3;
|
||
-
|
||
- for (;;) {
|
||
- if (uncomp_v3 && uncomp_v3->filters.bytes_ready > 0) {
|
||
- size_t count = smin(uncomp_v3->filters.bytes_ready, buffer_size);
|
||
- memcpy(buffer, uncomp_v3->filters.bytes, count);
|
||
- uncomp_v3->filters.bytes_ready -= count;
|
||
- uncomp_v3->filters.bytes += count;
|
||
- rar->progress.bytes_done += count;
|
||
- buffer_size -= count;
|
||
- buffer = (uint8_t *)buffer + count;
|
||
- if (rar->progress.bytes_done == rar->super.entry_size_uncompressed)
|
||
- goto FinishBlock;
|
||
- }
|
||
- else if (uncomp->bytes_ready > 0) {
|
||
- int count = (int)smin(uncomp->bytes_ready, buffer_size);
|
||
- lzss_copy_bytes_from_window(&uncomp->lzss, buffer, rar->progress.bytes_done + rar->solid.size_total, count);
|
||
- uncomp->bytes_ready -= count;
|
||
- rar->progress.bytes_done += count;
|
||
- buffer_size -= count;
|
||
- buffer = (uint8_t *)buffer + count;
|
||
- }
|
||
- if (buffer_size == 0)
|
||
- return true;
|
||
-
|
||
- if (uncomp->br.at_eof)
|
||
- return false;
|
||
-
|
||
- if (uncomp_v3 && uncomp_v3->filters.lastend == uncomp_v3->filters.filterstart) {
|
||
- if (!rar_run_filters(rar))
|
||
- return false;
|
||
- continue;
|
||
- }
|
||
-
|
||
-FinishBlock:
|
||
- if (uncomp->start_new_table && !rar_parse_codes(rar))
|
||
- return false;
|
||
-
|
||
- end = rar->progress.bytes_done + rar->solid.size_total + LZSS_WINDOW_SIZE - LZSS_OVERFLOW_SIZE;
|
||
- if (uncomp_v3 && uncomp_v3->filters.filterstart < end)
|
||
- end = uncomp_v3->filters.filterstart;
|
||
- end = (size_t)rar_expand(rar, end);
|
||
- if (end == (size_t)-1 || end < rar->progress.bytes_done + rar->solid.size_total)
|
||
- return false;
|
||
- uncomp->bytes_ready = end - rar->progress.bytes_done - rar->solid.size_total;
|
||
- if (uncomp_v3)
|
||
- uncomp_v3->filters.lastend = end;
|
||
-
|
||
- if (uncomp_v3 && uncomp_v3->is_ppmd_block && uncomp->start_new_table)
|
||
- goto FinishBlock;
|
||
- }
|
||
-}
|
||
diff --git a/cut-n-paste/unarr/unarr.h b/cut-n-paste/unarr/unarr.h
|
||
deleted file mode 100644
|
||
index cf3538d8..00000000
|
||
--- a/cut-n-paste/unarr/unarr.h
|
||
+++ /dev/null
|
||
@@ -1,103 +0,0 @@
|
||
-/* Copyright 2015 the unarr project authors (see AUTHORS file).
|
||
- License: LGPLv3 */
|
||
-
|
||
-#ifndef unarr_h
|
||
-#define unarr_h
|
||
-
|
||
-#include <stddef.h>
|
||
-#include <stdint.h>
|
||
-#include <stdbool.h>
|
||
-typedef int64_t off64_t;
|
||
-typedef int64_t time64_t;
|
||
-
|
||
-#define UNARR_API_VERSION 100
|
||
-
|
||
-typedef enum {
|
||
- AR_ARCHIVE_ERROR_NONE,
|
||
- AR_ARCHIVE_ERROR_UNKNOWN,
|
||
- AR_ARCHIVE_ERROR_RAR5,
|
||
- AR_ARCHIVE_ERROR_OLDRAR,
|
||
- AR_ARCHIVE_ERROR_SFX
|
||
-} ArArchiveError;
|
||
-
|
||
-/***** common/stream *****/
|
||
-
|
||
-typedef struct ar_stream_s ar_stream;
|
||
-
|
||
-/* opens a read-only stream for the given file path; returns NULL on error */
|
||
-ar_stream *ar_open_file(const char *path);
|
||
-#ifdef _WIN32
|
||
-ar_stream *ar_open_file_w(const wchar_t *path);
|
||
-#endif
|
||
-/* opens a read-only stream for the given chunk of memory; the pointer must be valid until ar_close is called */
|
||
-ar_stream *ar_open_memory(const void *data, size_t datalen);
|
||
-#ifdef _WIN32
|
||
-typedef struct IStream IStream;
|
||
-/* opens a read-only stream based on the given IStream */
|
||
-ar_stream *ar_open_istream(IStream *stream);
|
||
-#endif
|
||
-
|
||
-/* closes the stream and releases underlying resources */
|
||
-void ar_close(ar_stream *stream);
|
||
-/* tries to read 'count' bytes into buffer, advancing the read offset pointer; returns the actual number of bytes read */
|
||
-size_t ar_read(ar_stream *stream, void *buffer, size_t count);
|
||
-/* moves the read offset pointer (same as fseek); returns false on failure */
|
||
-bool ar_seek(ar_stream *stream, off64_t offset, int origin);
|
||
-/* shortcut for ar_seek(stream, count, SEEK_CUR); returns false on failure */
|
||
-bool ar_skip(ar_stream *stream, off64_t count);
|
||
-/* returns the current read offset (or 0 on error) */
|
||
-off64_t ar_tell(ar_stream *stream);
|
||
-
|
||
-/***** common/unarr *****/
|
||
-
|
||
-typedef struct ar_archive_s ar_archive;
|
||
-
|
||
-/* frees all data stored for the given archive; does not close the underlying stream */
|
||
-void ar_close_archive(ar_archive *ar);
|
||
-/* reads the next archive entry; returns false on error or at the end of the file (use ar_at_eof to distinguish the two cases) */
|
||
-bool ar_parse_entry(ar_archive *ar);
|
||
-/* reads the archive entry at the given offset as returned by ar_entry_get_offset (offset 0 always restarts at the first entry); should always succeed */
|
||
-bool ar_parse_entry_at(ar_archive *ar, off64_t offset);
|
||
-/* reads the (first) archive entry associated with the given name; returns false if the entry couldn't be found */
|
||
-bool ar_parse_entry_for(ar_archive *ar, const char *entry_name);
|
||
-/* returns whether the last ar_parse_entry call has reached the file's expected end */
|
||
-bool ar_at_eof(ar_archive *ar);
|
||
-
|
||
-/* returns the name of the current entry as UTF-8 string; this pointer is only valid until the next call to ar_parse_entry; returns NULL on failure */
|
||
-const char *ar_entry_get_name(ar_archive *ar);
|
||
-/* returns the stream offset of the current entry for use with ar_parse_entry_at */
|
||
-off64_t ar_entry_get_offset(ar_archive *ar);
|
||
-/* returns the total size of uncompressed data of the current entry; read exactly that many bytes using ar_entry_uncompress */
|
||
-size_t ar_entry_get_size(ar_archive *ar);
|
||
-/* returns the stored modification date of the current entry in 100ns since 1601/01/01 */
|
||
-time64_t ar_entry_get_filetime(ar_archive *ar);
|
||
-/* WARNING: don't manually seek in the stream between ar_parse_entry and the last corresponding ar_entry_uncompress call! */
|
||
-/* uncompresses the next 'count' bytes of the current entry into buffer; returns false on error */
|
||
-bool ar_entry_uncompress(ar_archive *ar, void *buffer, size_t count);
|
||
-
|
||
-/* copies at most 'count' bytes of the archive's global comment (if any) into buffer; returns the actual amout of bytes copied (or, if 'buffer' is NULL, the required buffer size) */
|
||
-size_t ar_get_global_comment(ar_archive *ar, void *buffer, size_t count);
|
||
-
|
||
-/***** rar/rar *****/
|
||
-
|
||
-/* checks whether 'stream' could contain RAR data and prepares for archive listing/extraction; returns NULL on failure */
|
||
-ar_archive *ar_open_rar_archive(ar_stream *stream);
|
||
-ar_archive *ar_open_rar_archive_with_error(ar_stream *stream, ArArchiveError *error_code);
|
||
-
|
||
-/***** tar/tar *****/
|
||
-
|
||
-/* checks whether 'stream' could contain TAR data and prepares for archive listing/extraction; returns NULL on failure */
|
||
-ar_archive *ar_open_tar_archive(ar_stream *stream);
|
||
-
|
||
-/***** zip/zip *****/
|
||
-
|
||
-/* checks whether 'stream' could contain ZIP data and prepares for archive listing/extraction; returns NULL on failure */
|
||
-/* set deflatedonly for extracting XPS, EPUB, etc. documents where non-Deflate compression methods are not supported by specification */
|
||
-ar_archive *ar_open_zip_archive(ar_stream *stream, bool deflatedonly);
|
||
-
|
||
-/***** _7z/_7z *****/
|
||
-
|
||
-/* checks whether 'stream' could contain 7Z data and prepares for archive listing/extraction; returns NULL on failure */
|
||
-ar_archive *ar_open_7z_archive(ar_stream *stream);
|
||
-
|
||
-#endif
|
||
diff --git a/po/POTFILES.skip b/po/POTFILES.skip
|
||
index 6d14dc5c..a96b4629 100644
|
||
--- a/po/POTFILES.skip
|
||
+++ b/po/POTFILES.skip
|
||
@@ -30,7 +30,6 @@ backend/tiff/tiffdocument.evince-backend.desktop.in
|
||
backend/xps/evince-xpsdocument.metainfo.xml.in
|
||
backend/xps/xpsdocument.evince-backend.desktop.in
|
||
cut-n-paste/libdazzle/dzl-file-manager.c
|
||
-cut-n-paste/unarr/common/conv.c
|
||
data/org.gnome.Evince.desktop.in
|
||
data/org.gnome.Evince-previewer.desktop.in
|
||
data/org.gnome.evince.Daemon.service.in
|
||
--
|
||
2.35.1
|
||
|