^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* Lzma decompressor for Linux kernel. Shamelessly snarfed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) *from busybox 1.1.1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *Linux kernel adaptation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *Copyright (C) 2006 Alain < alain@knaff.lu >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *Based on small lzma deflate implementation/Small range coder
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *implementation for lzma.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *Copyright (C) 2006 Aurelien Jacobs < aurel@gnuage.org >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) *Based on LzmaDecode.c from the LZMA SDK 4.22 (https://www.7-zip.org/)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *Copyright (C) 1999-2005 Igor Pavlov
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) *Copyrights of the parts, see headers below.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) *This program is free software; you can redistribute it and/or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) *modify it under the terms of the GNU Lesser General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) *License as published by the Free Software Foundation; either
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) *version 2.1 of the License, or (at your option) any later version.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) *This program is distributed in the hope that it will be useful,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) *but WITHOUT ANY WARRANTY; without even the implied warranty of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) *Lesser General Public License for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) *You should have received a copy of the GNU Lesser General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) *License along with this library; if not, write to the Free Software
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) *Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #ifdef STATIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define PREBOOT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/decompress/unlzma.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #endif /* STATIC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/decompress/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define MIN(a, b) (((a) < (b)) ? (a) : (b))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) static long long INIT read_int(unsigned char *ptr, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) long long ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) for (i = 0; i < size; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) ret = (ret << 8) | ptr[size-i-1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define ENDIAN_CONVERT(x) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) x = (typeof(x))read_int((unsigned char *)&x, sizeof(x))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) /* Small range coder implementation for lzma.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) *Copyright (C) 2006 Aurelien Jacobs < aurel@gnuage.org >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) *Based on LzmaDecode.c from the LZMA SDK 4.22 (https://www.7-zip.org/)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) *Copyright (c) 1999-2005 Igor Pavlov
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #include <linux/compiler.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define LZMA_IOBUF_SIZE 0x10000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) struct rc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) long (*fill)(void*, unsigned long);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) uint8_t *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) uint8_t *buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) uint8_t *buffer_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) long buffer_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) uint32_t code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) uint32_t range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) uint32_t bound;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) void (*error)(char *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define RC_TOP_BITS 24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define RC_MOVE_BITS 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define RC_MODEL_TOTAL_BITS 11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) static long INIT nofill(void *buffer, unsigned long len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) /* Called twice: once at startup and once in rc_normalize() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) static void INIT rc_read(struct rc *rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) rc->buffer_size = rc->fill((char *)rc->buffer, LZMA_IOBUF_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) if (rc->buffer_size <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) rc->error("unexpected EOF");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) rc->ptr = rc->buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) rc->buffer_end = rc->buffer + rc->buffer_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) /* Called once */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) static inline void INIT rc_init(struct rc *rc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) long (*fill)(void*, unsigned long),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) char *buffer, long buffer_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (fill)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) rc->fill = fill;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) rc->fill = nofill;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) rc->buffer = (uint8_t *)buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) rc->buffer_size = buffer_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) rc->buffer_end = rc->buffer + rc->buffer_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) rc->ptr = rc->buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) rc->code = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) rc->range = 0xFFFFFFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) static inline void INIT rc_init_code(struct rc *rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) for (i = 0; i < 5; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) if (rc->ptr >= rc->buffer_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) rc_read(rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) rc->code = (rc->code << 8) | *rc->ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /* Called twice, but one callsite is in inline'd rc_is_bit_0_helper() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static void INIT rc_do_normalize(struct rc *rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if (rc->ptr >= rc->buffer_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) rc_read(rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) rc->range <<= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) rc->code = (rc->code << 8) | *rc->ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) static inline void INIT rc_normalize(struct rc *rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) if (rc->range < (1 << RC_TOP_BITS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) rc_do_normalize(rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) /* Called 9 times */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) /* Why rc_is_bit_0_helper exists?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) *Because we want to always expose (rc->code < rc->bound) to optimizer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) static inline uint32_t INIT rc_is_bit_0_helper(struct rc *rc, uint16_t *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) rc_normalize(rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) rc->bound = *p * (rc->range >> RC_MODEL_TOTAL_BITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return rc->bound;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) static inline int INIT rc_is_bit_0(struct rc *rc, uint16_t *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) uint32_t t = rc_is_bit_0_helper(rc, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) return rc->code < t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /* Called ~10 times, but very small, thus inlined */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) static inline void INIT rc_update_bit_0(struct rc *rc, uint16_t *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) rc->range = rc->bound;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) *p += ((1 << RC_MODEL_TOTAL_BITS) - *p) >> RC_MOVE_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) static inline void INIT rc_update_bit_1(struct rc *rc, uint16_t *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) rc->range -= rc->bound;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) rc->code -= rc->bound;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) *p -= *p >> RC_MOVE_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) /* Called 4 times in unlzma loop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) static int INIT rc_get_bit(struct rc *rc, uint16_t *p, int *symbol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) if (rc_is_bit_0(rc, p)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) rc_update_bit_0(rc, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) *symbol *= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) rc_update_bit_1(rc, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) *symbol = *symbol * 2 + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) /* Called once */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) static inline int INIT rc_direct_bit(struct rc *rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) rc_normalize(rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) rc->range >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (rc->code >= rc->range) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) rc->code -= rc->range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) /* Called twice */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) static inline void INIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) rc_bit_tree_decode(struct rc *rc, uint16_t *p, int num_levels, int *symbol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) int i = num_levels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) *symbol = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) while (i--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) rc_get_bit(rc, p + *symbol, symbol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) *symbol -= 1 << num_levels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) * Small lzma deflate implementation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) * Copyright (C) 2006 Aurelien Jacobs < aurel@gnuage.org >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) * Based on LzmaDecode.c from the LZMA SDK 4.22 (https://www.7-zip.org/)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) * Copyright (C) 1999-2005 Igor Pavlov
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) struct lzma_header {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) uint8_t pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) uint32_t dict_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) uint64_t dst_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) } __attribute__ ((packed)) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) #define LZMA_BASE_SIZE 1846
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) #define LZMA_LIT_SIZE 768
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) #define LZMA_NUM_POS_BITS_MAX 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) #define LZMA_LEN_NUM_LOW_BITS 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) #define LZMA_LEN_NUM_MID_BITS 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) #define LZMA_LEN_NUM_HIGH_BITS 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) #define LZMA_LEN_CHOICE 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) #define LZMA_LEN_CHOICE_2 (LZMA_LEN_CHOICE + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) #define LZMA_LEN_LOW (LZMA_LEN_CHOICE_2 + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) #define LZMA_LEN_MID (LZMA_LEN_LOW \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) + (1 << (LZMA_NUM_POS_BITS_MAX + LZMA_LEN_NUM_LOW_BITS)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) #define LZMA_LEN_HIGH (LZMA_LEN_MID \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) +(1 << (LZMA_NUM_POS_BITS_MAX + LZMA_LEN_NUM_MID_BITS)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) #define LZMA_NUM_LEN_PROBS (LZMA_LEN_HIGH + (1 << LZMA_LEN_NUM_HIGH_BITS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) #define LZMA_NUM_STATES 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) #define LZMA_NUM_LIT_STATES 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) #define LZMA_START_POS_MODEL_INDEX 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) #define LZMA_END_POS_MODEL_INDEX 14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) #define LZMA_NUM_FULL_DISTANCES (1 << (LZMA_END_POS_MODEL_INDEX >> 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) #define LZMA_NUM_POS_SLOT_BITS 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) #define LZMA_NUM_LEN_TO_POS_STATES 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) #define LZMA_NUM_ALIGN_BITS 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) #define LZMA_MATCH_MIN_LEN 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) #define LZMA_IS_MATCH 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) #define LZMA_IS_REP (LZMA_IS_MATCH + (LZMA_NUM_STATES << LZMA_NUM_POS_BITS_MAX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) #define LZMA_IS_REP_G0 (LZMA_IS_REP + LZMA_NUM_STATES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) #define LZMA_IS_REP_G1 (LZMA_IS_REP_G0 + LZMA_NUM_STATES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) #define LZMA_IS_REP_G2 (LZMA_IS_REP_G1 + LZMA_NUM_STATES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) #define LZMA_IS_REP_0_LONG (LZMA_IS_REP_G2 + LZMA_NUM_STATES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) #define LZMA_POS_SLOT (LZMA_IS_REP_0_LONG \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) + (LZMA_NUM_STATES << LZMA_NUM_POS_BITS_MAX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) #define LZMA_SPEC_POS (LZMA_POS_SLOT \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) +(LZMA_NUM_LEN_TO_POS_STATES << LZMA_NUM_POS_SLOT_BITS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) #define LZMA_ALIGN (LZMA_SPEC_POS \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) + LZMA_NUM_FULL_DISTANCES - LZMA_END_POS_MODEL_INDEX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) #define LZMA_LEN_CODER (LZMA_ALIGN + (1 << LZMA_NUM_ALIGN_BITS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) #define LZMA_REP_LEN_CODER (LZMA_LEN_CODER + LZMA_NUM_LEN_PROBS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) #define LZMA_LITERAL (LZMA_REP_LEN_CODER + LZMA_NUM_LEN_PROBS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) struct writer {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) uint8_t *buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) uint8_t previous_byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) size_t buffer_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) int bufsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) size_t global_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) long (*flush)(void*, unsigned long);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) struct lzma_header *header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) struct cstate {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) int state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) uint32_t rep0, rep1, rep2, rep3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) static inline size_t INIT get_pos(struct writer *wr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) wr->global_pos + wr->buffer_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) static inline uint8_t INIT peek_old_byte(struct writer *wr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) uint32_t offs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) if (!wr->flush) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) int32_t pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) while (offs > wr->header->dict_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) offs -= wr->header->dict_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) pos = wr->buffer_pos - offs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) return wr->buffer[pos];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) uint32_t pos = wr->buffer_pos - offs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) while (pos >= wr->header->dict_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) pos += wr->header->dict_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) return wr->buffer[pos];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) static inline int INIT write_byte(struct writer *wr, uint8_t byte)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) wr->buffer[wr->buffer_pos++] = wr->previous_byte = byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) if (wr->flush && wr->buffer_pos == wr->header->dict_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) wr->buffer_pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) wr->global_pos += wr->header->dict_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if (wr->flush((char *)wr->buffer, wr->header->dict_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) != wr->header->dict_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) static inline int INIT copy_byte(struct writer *wr, uint32_t offs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) return write_byte(wr, peek_old_byte(wr, offs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) static inline int INIT copy_bytes(struct writer *wr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) uint32_t rep0, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (copy_byte(wr, rep0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) len--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) } while (len != 0 && wr->buffer_pos < wr->header->dst_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) static inline int INIT process_bit0(struct writer *wr, struct rc *rc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) struct cstate *cst, uint16_t *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) int pos_state, uint16_t *prob,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) int lc, uint32_t literal_pos_mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) int mi = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) rc_update_bit_0(rc, prob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) prob = (p + LZMA_LITERAL +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) (LZMA_LIT_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) * (((get_pos(wr) & literal_pos_mask) << lc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) + (wr->previous_byte >> (8 - lc))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) if (cst->state >= LZMA_NUM_LIT_STATES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) int match_byte = peek_old_byte(wr, cst->rep0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) int bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) uint16_t *prob_lit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) match_byte <<= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) bit = match_byte & 0x100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) prob_lit = prob + 0x100 + bit + mi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) if (rc_get_bit(rc, prob_lit, &mi)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) if (!bit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) if (bit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) } while (mi < 0x100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) while (mi < 0x100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) uint16_t *prob_lit = prob + mi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) rc_get_bit(rc, prob_lit, &mi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (cst->state < 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) cst->state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) else if (cst->state < 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) cst->state -= 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) cst->state -= 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) return write_byte(wr, mi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) static inline int INIT process_bit1(struct writer *wr, struct rc *rc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) struct cstate *cst, uint16_t *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) int pos_state, uint16_t *prob) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) int offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) uint16_t *prob_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) int num_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) rc_update_bit_1(rc, prob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) prob = p + LZMA_IS_REP + cst->state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) if (rc_is_bit_0(rc, prob)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) rc_update_bit_0(rc, prob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) cst->rep3 = cst->rep2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) cst->rep2 = cst->rep1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) cst->rep1 = cst->rep0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) cst->state = cst->state < LZMA_NUM_LIT_STATES ? 0 : 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) prob = p + LZMA_LEN_CODER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) rc_update_bit_1(rc, prob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) prob = p + LZMA_IS_REP_G0 + cst->state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) if (rc_is_bit_0(rc, prob)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) rc_update_bit_0(rc, prob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) prob = (p + LZMA_IS_REP_0_LONG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) + (cst->state <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) LZMA_NUM_POS_BITS_MAX) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) pos_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) if (rc_is_bit_0(rc, prob)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) rc_update_bit_0(rc, prob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) cst->state = cst->state < LZMA_NUM_LIT_STATES ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 9 : 11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) return copy_byte(wr, cst->rep0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) rc_update_bit_1(rc, prob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) uint32_t distance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) rc_update_bit_1(rc, prob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) prob = p + LZMA_IS_REP_G1 + cst->state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) if (rc_is_bit_0(rc, prob)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) rc_update_bit_0(rc, prob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) distance = cst->rep1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) rc_update_bit_1(rc, prob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) prob = p + LZMA_IS_REP_G2 + cst->state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) if (rc_is_bit_0(rc, prob)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) rc_update_bit_0(rc, prob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) distance = cst->rep2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) rc_update_bit_1(rc, prob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) distance = cst->rep3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) cst->rep3 = cst->rep2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) cst->rep2 = cst->rep1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) cst->rep1 = cst->rep0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) cst->rep0 = distance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) cst->state = cst->state < LZMA_NUM_LIT_STATES ? 8 : 11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) prob = p + LZMA_REP_LEN_CODER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) prob_len = prob + LZMA_LEN_CHOICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) if (rc_is_bit_0(rc, prob_len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) rc_update_bit_0(rc, prob_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) prob_len = (prob + LZMA_LEN_LOW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) + (pos_state <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) LZMA_LEN_NUM_LOW_BITS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) num_bits = LZMA_LEN_NUM_LOW_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) rc_update_bit_1(rc, prob_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) prob_len = prob + LZMA_LEN_CHOICE_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) if (rc_is_bit_0(rc, prob_len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) rc_update_bit_0(rc, prob_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) prob_len = (prob + LZMA_LEN_MID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) + (pos_state <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) LZMA_LEN_NUM_MID_BITS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) offset = 1 << LZMA_LEN_NUM_LOW_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) num_bits = LZMA_LEN_NUM_MID_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) rc_update_bit_1(rc, prob_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) prob_len = prob + LZMA_LEN_HIGH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) offset = ((1 << LZMA_LEN_NUM_LOW_BITS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) + (1 << LZMA_LEN_NUM_MID_BITS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) num_bits = LZMA_LEN_NUM_HIGH_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) rc_bit_tree_decode(rc, prob_len, num_bits, &len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) len += offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) if (cst->state < 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) int pos_slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) cst->state += LZMA_NUM_LIT_STATES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) prob =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) p + LZMA_POS_SLOT +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) ((len <
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) LZMA_NUM_LEN_TO_POS_STATES ? len :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) LZMA_NUM_LEN_TO_POS_STATES - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) << LZMA_NUM_POS_SLOT_BITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) rc_bit_tree_decode(rc, prob,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) LZMA_NUM_POS_SLOT_BITS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) &pos_slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) if (pos_slot >= LZMA_START_POS_MODEL_INDEX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) int i, mi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) num_bits = (pos_slot >> 1) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) cst->rep0 = 2 | (pos_slot & 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) if (pos_slot < LZMA_END_POS_MODEL_INDEX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) cst->rep0 <<= num_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) prob = p + LZMA_SPEC_POS +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) cst->rep0 - pos_slot - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) num_bits -= LZMA_NUM_ALIGN_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) while (num_bits--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) cst->rep0 = (cst->rep0 << 1) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) rc_direct_bit(rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) prob = p + LZMA_ALIGN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) cst->rep0 <<= LZMA_NUM_ALIGN_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) num_bits = LZMA_NUM_ALIGN_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) i = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) mi = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) while (num_bits--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) if (rc_get_bit(rc, prob + mi, &mi))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) cst->rep0 |= i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) i <<= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) cst->rep0 = pos_slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) if (++(cst->rep0) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) if (cst->rep0 > wr->header->dict_size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) || cst->rep0 > get_pos(wr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) len += LZMA_MATCH_MIN_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) return copy_bytes(wr, cst->rep0, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) STATIC inline int INIT unlzma(unsigned char *buf, long in_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) long (*fill)(void*, unsigned long),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) long (*flush)(void*, unsigned long),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) unsigned char *output,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) long *posp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) void(*error)(char *x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) struct lzma_header header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) int lc, pb, lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) uint32_t pos_state_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) uint32_t literal_pos_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) uint16_t *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) int num_probs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) struct rc rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) int i, mi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) struct writer wr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) struct cstate cst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) unsigned char *inbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) int ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) rc.error = error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) if (buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) inbuf = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) inbuf = malloc(LZMA_IOBUF_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) if (!inbuf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) error("Could not allocate input buffer");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) goto exit_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) cst.state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) cst.rep0 = cst.rep1 = cst.rep2 = cst.rep3 = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) wr.header = &header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) wr.flush = flush;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) wr.global_pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) wr.previous_byte = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) wr.buffer_pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) rc_init(&rc, fill, inbuf, in_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) for (i = 0; i < sizeof(header); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) if (rc.ptr >= rc.buffer_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) rc_read(&rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) ((unsigned char *)&header)[i] = *rc.ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) if (header.pos >= (9 * 5 * 5)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) error("bad header");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) goto exit_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) mi = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) lc = header.pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) while (lc >= 9) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) mi++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) lc -= 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) pb = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) lp = mi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) while (lp >= 5) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) pb++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) lp -= 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) pos_state_mask = (1 << pb) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) literal_pos_mask = (1 << lp) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) ENDIAN_CONVERT(header.dict_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) ENDIAN_CONVERT(header.dst_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) if (header.dict_size == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) header.dict_size = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) if (output)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) wr.buffer = output;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) wr.bufsize = MIN(header.dst_size, header.dict_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) wr.buffer = large_malloc(wr.bufsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) if (wr.buffer == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) goto exit_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) num_probs = LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) p = (uint16_t *) large_malloc(num_probs * sizeof(*p));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) if (p == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) goto exit_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) num_probs = LZMA_LITERAL + (LZMA_LIT_SIZE << (lc + lp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) for (i = 0; i < num_probs; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) p[i] = (1 << RC_MODEL_TOTAL_BITS) >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) rc_init_code(&rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) while (get_pos(&wr) < header.dst_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) int pos_state = get_pos(&wr) & pos_state_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) uint16_t *prob = p + LZMA_IS_MATCH +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) (cst.state << LZMA_NUM_POS_BITS_MAX) + pos_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) if (rc_is_bit_0(&rc, prob)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) if (process_bit0(&wr, &rc, &cst, p, pos_state, prob,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) lc, literal_pos_mask)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) error("LZMA data is corrupt");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) goto exit_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) if (process_bit1(&wr, &rc, &cst, p, pos_state, prob)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) error("LZMA data is corrupt");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) goto exit_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) if (cst.rep0 == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) if (rc.buffer_size <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) goto exit_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) if (posp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) *posp = rc.ptr-rc.buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) if (!wr.flush || wr.flush(wr.buffer, wr.buffer_pos) == wr.buffer_pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) exit_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) large_free(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) exit_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) if (!output)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) large_free(wr.buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) exit_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) free(inbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) exit_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) #ifdef PREBOOT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) STATIC int INIT __decompress(unsigned char *buf, long in_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) long (*fill)(void*, unsigned long),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) long (*flush)(void*, unsigned long),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) unsigned char *output, long out_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) long *posp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) void (*error)(char *x))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) return unlzma(buf, in_len - 4, fill, flush, output, posp, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) #endif