├── .editorconfig ├── .gitignore ├── .gitmodules ├── LICENSE ├── Makefile ├── README.md ├── release-linux.sh ├── release-linux32.sh ├── release-win32.sh └── src ├── enc ├── aplib.c ├── apultra │ ├── apultra.c │ ├── divsufsort.c │ ├── divsufsort.h │ ├── divsufsort_config.h │ ├── divsufsort_private.h │ ├── expand.c │ ├── expand.h │ ├── format.h │ ├── libapultra.h │ ├── matchfinder.c │ ├── matchfinder.h │ ├── shrink.c │ ├── shrink.h │ ├── shrink_context.c │ ├── sssort.c │ └── trsort.c ├── enc.h ├── lzo.c ├── lzo │ ├── config1x.h │ ├── lzo1_d.ch │ ├── lzo1x.h │ ├── lzo1x_1.c │ ├── lzo1x_9x.c │ ├── lzo1x_c.ch │ ├── lzo1x_d.ch │ ├── lzo1x_d1.c │ ├── lzo1x_d2.c │ ├── lzo1x_d3.c │ ├── lzo_conf.h │ ├── lzo_dict.h │ ├── lzo_func.h │ ├── lzo_mchw.ch │ ├── lzo_ptr.c │ ├── lzo_ptr.h │ ├── lzo_supp.h │ ├── lzo_swd.ch │ ├── lzoconf.h │ └── lzodefs.h ├── stretchy_buffer.h ├── ucl.c ├── ucl │ ├── comp │ │ ├── n2_99.ch │ │ ├── n2b_99.c │ │ ├── ucl_mchw.ch │ │ └── ucl_swd.ch │ ├── getbit.h │ ├── n2b_d.c │ ├── ucl.h │ ├── ucl_conf.h │ └── uclconf.h ├── yar.c ├── yar.h ├── yaz.c ├── zlib.c ├── zx7.c └── zx7 │ ├── compress.c │ ├── dzx7.c │ ├── optimize.c │ ├── zx7.c │ └── zx7.h ├── main.c ├── n64crc.c ├── n64crc.h ├── rom.c ├── rom.h ├── sha1.c ├── sha1.h ├── wow.c ├── wow.h └── wow_dirent.h /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | insert_final_newline = true 6 | 7 | # Matches multiple files with brace expansion notation 8 | [*.{c,h,ch}] 9 | charset = utf-8 10 | indent_style = tab 11 | indent_size = 3 12 | trim_trailing_whitespace = false 13 | 14 | [*.md] 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | o/ 3 | z64compress 4 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "src/enc/libdeflate"] 2 | path = src/enc/libdeflate 3 | url = https://github.com/ebiggers/libdeflate 4 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | CC := gcc 2 | CFLAGS := -DNDEBUG -s -Os -flto -Wall -Wextra 3 | 4 | # Target platform, specify with TARGET= on the command line, linux64 is default. 5 | # Currently supported: linux64, linux32, win32 6 | TARGET ?= linux64 7 | 8 | ifeq ($(TARGET),linux32) 9 | TARGET_CFLAGS := -m32 10 | else ifeq ($(TARGET),win32) 11 | # If using a cross compiler, specify the compiler executable on the command line. 12 | # make TARGET=win32 CC=~/c/mxe/usr/bin/i686-w64-mingw32.static-gcc 13 | TARGET_LIBS := -mconsole -municode 14 | else ifneq ($(TARGET),linux64) 15 | $(error Supported targets: linux64, linux32, win32) 16 | endif 17 | 18 | # Whether to use native optimizations, specify with NATIVE_OPT=0/1 on the command line, default is 0. 19 | # This is not supported by all compilers which is particularly an issue on Mac, and may inhibit tests. 20 | NATIVE_OPT ?= 0 21 | ifeq ($(NATIVE_OPT),1) 22 | TARGET_CFLAGS += -march=native -mtune=native 23 | endif 24 | 25 | OBJ_DIR := o/$(TARGET) 26 | 27 | $(OBJ_DIR)/src/enc/%.o: CFLAGS := -DNDEBUG -s -Ofast -flto -Wall -Isrc/enc/libdeflate 28 | 29 | SRC_DIRS := $(shell find src -type d) 30 | C_DIRS := $(shell find src -type d -not -path "src/enc/libdeflate/*") 31 | C_FILES := $(foreach dir,$(C_DIRS),$(wildcard $(dir)/*.c)) 32 | C_FILES += src/enc/libdeflate/lib/deflate_compress.c src/enc/libdeflate/lib/utils.c 33 | O_FILES := $(foreach f,$(C_FILES:.c=.o),$(OBJ_DIR)/$f) 34 | 35 | # Make build directories 36 | $(shell mkdir -p $(foreach dir,$(SRC_DIRS),$(OBJ_DIR)/$(dir))) 37 | 38 | .PHONY: all clean 39 | 40 | all: z64compress 41 | 42 | z64compress: $(O_FILES) 43 | $(CC) $(TARGET_CFLAGS) $(CFLAGS) $(O_FILES) -lm -lpthread -lz $(TARGET_LIBS) -o z64compress 44 | 45 | $(OBJ_DIR)/%.o: %.c 46 | $(CC) -c $(TARGET_CFLAGS) $(CFLAGS) $< -o $@ 47 | 48 | clean: 49 | $(RM) -rf z64compress bin o 50 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # z64compress 2 | 3 | `z64compress` is a program for compressing Zelda 64 roms: be they retail, hacked traditionally, or custom-built from the [`Ocarina of Time`](https://github.com/zeldaret/oot) or [`Majora's Mask`](https://github.com/zeldaret/mm) reverse engineering projects. It is written in highly efficient C and leverages the power of multithreading to make compression as fast as possible. To reduce overhead on subsequent compressions, an optional cache directory can be specified. 4 | 5 | In addition to the default `yaz`, it supports some faster and more compact algorithms such as `DEFLATE`, `lzo`, `ucl`, and `aplib`. In order to use these, grab patches or code from my [`z64enc` repository](https://github.com/z64me/z64enc). 6 | 7 | If you add an algorithm, please make sure `valgrind` reports no memory leaks or other errors before making a pull request. Thank you! 8 | 9 | (By the way, `valgrind` works better without the `-march=native -mtune=native` optimizations, so turn those off when testing `valgrind`.) 10 | 11 | ## Usage 12 | This is a command line application. Learn from these common examples and adapt the arguments to your needs: 13 | ``` 14 | compressing oot debug 15 | --in "path/to/in.z64" 16 | --out "path/to/out.z64" 17 | --mb 32 18 | --codec yaz 19 | --cache "path/to/cache" 20 | --dma "0x12F70,1548" 21 | --compress "9-14,28-END" 22 | --threads 4 23 | 24 | compressing oot ntsc 1.0 25 | --in "path/to/in.z64" 26 | --out "path/to/out.z64" 27 | --mb 32 28 | --codec yaz 29 | --cache "path/to/cache" 30 | --dma "0x7430,1526" 31 | --compress "10-14,27-END" 32 | --threads 4 33 | 34 | compressing mm usa 35 | --in "path/to/in.z64" 36 | --out "path/to/out.z64" 37 | --mb 32 38 | --codec yaz 39 | --cache "path/to/cache" 40 | --dma "0x1A500,1568" 41 | --compress "10-14,23,24,31-END" 42 | --skip "1127" 43 | --repack "15-20,22" 44 | --threads 4 45 | ``` 46 | 47 | ## Arguments 48 | ``` 49 | --in uncompressed input rom 50 | 51 | --out compressed output rom 52 | 53 | --matching attempt matching compression at the cost of 54 | some optimizations and reduced performance 55 | 56 | --mb how many mb the compressed rom should be 57 | 58 | --codec currently supported codecs 59 | yaz 60 | ucl 61 | lzo 62 | zlib 63 | aplib 64 | * to use non-yaz codecs, find patches 65 | and code on my z64enc repo 66 | 67 | --cache is optional and won't be created if 68 | no path is specified (having a cache 69 | makes subsequent compressions faster) 70 | * pro-tip: linux users who don't want a 71 | cache to persist across power cycles 72 | can use the path "/tmp/z64compress" 73 | 74 | --dma specify dmadata address and count 75 | 76 | --compress enable compression on specified files 77 | 78 | --skip disable compression on specified files 79 | 80 | --repack handles Majora's Mask archives 81 | 82 | --threads optional multithreading; 83 | exclude this argument to disable it 84 | 85 | --only-stdout reserve stderr for errors and print 86 | everything else to stdout 87 | 88 | arguments are executed as they 89 | are parsed, so order matters! 90 | ``` 91 | 92 | ## Building 93 | First, clone the repository and initialize its submodules: 94 | ``` 95 | git clone https://github.com/z64me/z64compress.git 96 | cd z64compress 97 | git submodule update --init 98 | ``` 99 | 100 | A Makefile-based build system is provided. Choose the target platform with `make TARGET=linux64|linux32|win32`, default is linux64. If building for windows with a cross compiler, specify the compiler executable with `make TARGET=win32 CC=/path/to/executable`. 101 | 102 | Alternatively, I have included shell scripts for building Linux and Windows binaries. Windows binaries are built using a cross compiler ([I recommend `MXE`](https://mxe.cc/)). 103 | -------------------------------------------------------------------------------- /release-linux.sh: -------------------------------------------------------------------------------- 1 | # build compression functions (slow) 2 | gcc -DNDEBUG -s -Ofast -flto -lm -c -Wall -march=native -mtune=native src/enc/*.c src/enc/lzo/*.c src/enc/ucl/comp/*.c src/enc/apultra/*.c 3 | mkdir -p o 4 | mv *.o o 5 | 6 | # build everything else 7 | gcc -o z64compress -DNDEBUG src/*.c o/*.o src/enc/libdeflate/lib/deflate_compress.c src/enc/libdeflate/lib/utils.c -Isrc/enc/libdeflate -Wall -Wextra -s -Os -flto -lpthread -lz -march=native -mtune=native 8 | 9 | # move to bin directory 10 | mkdir -p bin/linux64 11 | mv z64compress bin/linux64 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /release-linux32.sh: -------------------------------------------------------------------------------- 1 | # build compression functions (slow) 2 | gcc -m32 -DNDEBUG -s -Ofast -flto -lm -c -Wall -march=native -mtune=native src/enc/*.c src/enc/lzo/*.c src/enc/ucl/comp/*.c src/enc/apultra/*.c 3 | mkdir -p o 4 | mv *.o o 5 | 6 | # build everything else 7 | gcc -m32 -o z64compress -DNDEBUG src/*.c o/*.o src/enc/libdeflate/lib/deflate_compress.c src/enc/libdeflate/lib/utils.c -Isrc/enc/libdeflate -Wall -Wextra -s -Os -flto -lpthread -lz -march=native -mtune=native 8 | 9 | # move to bin directory 10 | mkdir -p bin/linux32 11 | mv z64compress bin/linux32 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /release-win32.sh: -------------------------------------------------------------------------------- 1 | # build compression functions (slow) 2 | i686-w64-mingw32.static-gcc -DNDEBUG -s -Ofast -flto -lm -c -Wall src/enc/*.c src/enc/lzo/*.c src/enc/ucl/comp/*.c src/enc/apultra/*.c 3 | mkdir -p o 4 | mv *.o o 5 | 6 | # build everything else 7 | i686-w64-mingw32.static-gcc -o z64compress.exe -DNDEBUG src/*.c o/*.o src/enc/libdeflate/lib/deflate_compress.c src/enc/libdeflate/lib/utils.c -Isrc/enc/libdeflate -Wall -Wextra -s -Os -flto -lpthread -lz -mconsole -municode 8 | 9 | # move to bin directory 10 | mkdir -p bin/win32 11 | mv z64compress.exe bin/win32 12 | 13 | -------------------------------------------------------------------------------- /src/enc/aplib.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "apultra/libapultra.h" 5 | 6 | static void compression_progress(long long nOriginalSize, long long nCompressedSize) { 7 | /* do nothing */ 8 | } 9 | 10 | int 11 | aplenc( 12 | void *_src 13 | , unsigned src_sz 14 | , void *_dst 15 | , unsigned *dst_sz 16 | , void *_ctx 17 | ) 18 | { 19 | unsigned char *src = _src; 20 | unsigned char *dst = _dst; 21 | int nMaxCompressedSize = apultra_get_max_compressed_size(src_sz); 22 | apultra_stats stats; 23 | 24 | extern int g_hlen; /* header length */ 25 | memset(dst, 0, g_hlen); 26 | memcpy(dst, "APL0", 4); 27 | dst[4] = (src_sz >> 24); 28 | dst[5] = (src_sz >> 16); 29 | dst[6] = (src_sz >> 8); 30 | dst[7] = (src_sz >> 0); 31 | 32 | *dst_sz = apultra_compress( 33 | src 34 | , dst + g_hlen 35 | , src_sz 36 | , nMaxCompressedSize 37 | , 0 /* flags */ 38 | , 0 /* nMaxWindowSize */ 39 | , 0 /* nDictionarySize */ 40 | , compression_progress 41 | , &stats 42 | ); 43 | 44 | *dst_sz = *dst_sz + g_hlen; 45 | 46 | return 0; 47 | } 48 | 49 | -------------------------------------------------------------------------------- /src/enc/apultra/apultra.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/z64utils/z64compress/718d2a1556f2e98af9c0c0d45ce332956d3e72e3/src/enc/apultra/apultra.c -------------------------------------------------------------------------------- /src/enc/apultra/divsufsort.h: -------------------------------------------------------------------------------- 1 | /* 2 | * divsufsort.h for libdivsufsort 3 | * Copyright (c) 2003-2008 Yuta Mori All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person 6 | * obtaining a copy of this software and associated documentation 7 | * files (the "Software"), to deal in the Software without 8 | * restriction, including without limitation the rights to use, 9 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the 11 | * Software is furnished to do so, subject to the following 12 | * conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be 15 | * included in all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 19 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 | * OTHER DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | #ifndef _DIVSUFSORT_H 28 | #define _DIVSUFSORT_H 1 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif /* __cplusplus */ 33 | 34 | #define DIVSUFSORT_API 35 | 36 | /*- Datatypes -*/ 37 | #ifndef SAUCHAR_T 38 | #define SAUCHAR_T 39 | typedef unsigned char sauchar_t; 40 | #endif /* SAUCHAR_T */ 41 | #ifndef SAINT_T 42 | #define SAINT_T 43 | typedef int saint_t; 44 | #endif /* SAINT_T */ 45 | #ifndef SAIDX_T 46 | #define SAIDX_T 47 | typedef int saidx_t; 48 | #endif /* SAIDX_T */ 49 | #ifndef PRIdSAIDX_T 50 | #define PRIdSAIDX_T "d" 51 | #endif 52 | 53 | /*- divsufsort context */ 54 | typedef struct _divsufsort_ctx_t { 55 | saidx_t *bucket_A; 56 | saidx_t *bucket_B; 57 | } divsufsort_ctx_t; 58 | 59 | /*- Prototypes -*/ 60 | 61 | /** 62 | * Initialize suffix array context 63 | * 64 | * @return 0 for success, or non-zero in case of an error 65 | */ 66 | int divsufsort_init(divsufsort_ctx_t *ctx); 67 | 68 | /** 69 | * Destroy suffix array context 70 | * 71 | * @param ctx suffix array context to destroy 72 | */ 73 | void divsufsort_destroy(divsufsort_ctx_t *ctx); 74 | 75 | /** 76 | * Constructs the suffix array of a given string. 77 | * @param ctx suffix array context 78 | * @param T[0..n-1] The input string. 79 | * @param SA[0..n-1] The output array of suffixes. 80 | * @param n The length of the given string. 81 | * @return 0 if no error occurred, -1 or -2 otherwise. 82 | */ 83 | DIVSUFSORT_API 84 | saint_t divsufsort_build_array(divsufsort_ctx_t *ctx, const sauchar_t *T, saidx_t *SA, saidx_t n); 85 | 86 | #if 0 87 | /** 88 | * Constructs the burrows-wheeler transformed string of a given string. 89 | * @param T[0..n-1] The input string. 90 | * @param U[0..n-1] The output string. (can be T) 91 | * @param A[0..n-1] The temporary array. (can be NULL) 92 | * @param n The length of the given string. 93 | * @return The primary index if no error occurred, -1 or -2 otherwise. 94 | */ 95 | DIVSUFSORT_API 96 | saidx_t 97 | divbwt(const sauchar_t *T, sauchar_t *U, saidx_t *A, saidx_t n); 98 | 99 | /** 100 | * Returns the version of the divsufsort library. 101 | * @return The version number string. 102 | */ 103 | DIVSUFSORT_API 104 | const char * 105 | divsufsort_version(void); 106 | 107 | 108 | /** 109 | * Constructs the burrows-wheeler transformed string of a given string and suffix array. 110 | * @param T[0..n-1] The input string. 111 | * @param U[0..n-1] The output string. (can be T) 112 | * @param SA[0..n-1] The suffix array. (can be NULL) 113 | * @param n The length of the given string. 114 | * @param idx The output primary index. 115 | * @return 0 if no error occurred, -1 or -2 otherwise. 116 | */ 117 | DIVSUFSORT_API 118 | saint_t 119 | bw_transform(const sauchar_t *T, sauchar_t *U, 120 | saidx_t *SA /* can NULL */, 121 | saidx_t n, saidx_t *idx); 122 | 123 | /** 124 | * Inverse BW-transforms a given BWTed string. 125 | * @param T[0..n-1] The input string. 126 | * @param U[0..n-1] The output string. (can be T) 127 | * @param A[0..n-1] The temporary array. (can be NULL) 128 | * @param n The length of the given string. 129 | * @param idx The primary index. 130 | * @return 0 if no error occurred, -1 or -2 otherwise. 131 | */ 132 | DIVSUFSORT_API 133 | saint_t 134 | inverse_bw_transform(const sauchar_t *T, sauchar_t *U, 135 | saidx_t *A /* can NULL */, 136 | saidx_t n, saidx_t idx); 137 | 138 | /** 139 | * Checks the correctness of a given suffix array. 140 | * @param T[0..n-1] The input string. 141 | * @param SA[0..n-1] The input suffix array. 142 | * @param n The length of the given string. 143 | * @param verbose The verbose mode. 144 | * @return 0 if no error occurred. 145 | */ 146 | DIVSUFSORT_API 147 | saint_t 148 | sufcheck(const sauchar_t *T, const saidx_t *SA, saidx_t n, saint_t verbose); 149 | 150 | /** 151 | * Search for the pattern P in the string T. 152 | * @param T[0..Tsize-1] The input string. 153 | * @param Tsize The length of the given string. 154 | * @param P[0..Psize-1] The input pattern string. 155 | * @param Psize The length of the given pattern string. 156 | * @param SA[0..SAsize-1] The input suffix array. 157 | * @param SAsize The length of the given suffix array. 158 | * @param idx The output index. 159 | * @return The count of matches if no error occurred, -1 otherwise. 160 | */ 161 | DIVSUFSORT_API 162 | saidx_t 163 | sa_search(const sauchar_t *T, saidx_t Tsize, 164 | const sauchar_t *P, saidx_t Psize, 165 | const saidx_t *SA, saidx_t SAsize, 166 | saidx_t *left); 167 | 168 | /** 169 | * Search for the character c in the string T. 170 | * @param T[0..Tsize-1] The input string. 171 | * @param Tsize The length of the given string. 172 | * @param SA[0..SAsize-1] The input suffix array. 173 | * @param SAsize The length of the given suffix array. 174 | * @param c The input character. 175 | * @param idx The output index. 176 | * @return The count of matches if no error occurred, -1 otherwise. 177 | */ 178 | DIVSUFSORT_API 179 | saidx_t 180 | sa_simplesearch(const sauchar_t *T, saidx_t Tsize, 181 | const saidx_t *SA, saidx_t SAsize, 182 | saint_t c, saidx_t *left); 183 | #endif 184 | 185 | saint_t 186 | divsufsort(const sauchar_t *T, saidx_t *SA, saidx_t n); 187 | 188 | #ifdef __cplusplus 189 | } /* extern "C" */ 190 | #endif /* __cplusplus */ 191 | 192 | #endif /* _DIVSUFSORT_H */ 193 | -------------------------------------------------------------------------------- /src/enc/apultra/divsufsort_config.h: -------------------------------------------------------------------------------- 1 | #define HAVE_STRING_H 1 2 | #define HAVE_STDLIB_H 1 3 | #define HAVE_MEMORY_H 1 4 | #define HAVE_STDINT_H 1 5 | #define INLINE inline 6 | 7 | #ifdef _MSC_VER 8 | #pragma warning( disable : 4244 ) 9 | #endif /* _MSC_VER */ 10 | -------------------------------------------------------------------------------- /src/enc/apultra/divsufsort_private.h: -------------------------------------------------------------------------------- 1 | /* 2 | * divsufsort_private.h for libdivsufsort 3 | * Copyright (c) 2003-2008 Yuta Mori All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person 6 | * obtaining a copy of this software and associated documentation 7 | * files (the "Software"), to deal in the Software without 8 | * restriction, including without limitation the rights to use, 9 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the 11 | * Software is furnished to do so, subject to the following 12 | * conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be 15 | * included in all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 19 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 | * OTHER DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | #ifndef _DIVSUFSORT_PRIVATE_H 28 | #define _DIVSUFSORT_PRIVATE_H 1 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif /* __cplusplus */ 33 | 34 | #include "divsufsort_config.h" 35 | #include 36 | #include 37 | #if HAVE_STRING_H 38 | # include 39 | #endif 40 | #if HAVE_STDLIB_H 41 | # include 42 | #endif 43 | #if HAVE_MEMORY_H 44 | # include 45 | #endif 46 | #if HAVE_STDDEF_H 47 | # include 48 | #endif 49 | #if HAVE_STRINGS_H 50 | # include 51 | #endif 52 | #if HAVE_INTTYPES_H 53 | # include 54 | #else 55 | # if HAVE_STDINT_H 56 | # include 57 | # endif 58 | #endif 59 | #if defined(BUILD_DIVSUFSORT64) 60 | # include "divsufsort64.h" 61 | # ifndef SAIDX_T 62 | # define SAIDX_T 63 | # define saidx_t saidx64_t 64 | # endif /* SAIDX_T */ 65 | # ifndef PRIdSAIDX_T 66 | # define PRIdSAIDX_T PRIdSAIDX64_T 67 | # endif /* PRIdSAIDX_T */ 68 | # define divsufsort divsufsort64 69 | # define divbwt divbwt64 70 | # define divsufsort_version divsufsort64_version 71 | # define bw_transform bw_transform64 72 | # define inverse_bw_transform inverse_bw_transform64 73 | # define sufcheck sufcheck64 74 | # define sa_search sa_search64 75 | # define sa_simplesearch sa_simplesearch64 76 | # define sssort sssort64 77 | # define trsort trsort64 78 | #else 79 | # include "divsufsort.h" 80 | #endif 81 | 82 | 83 | /*- Constants -*/ 84 | #if !defined(UINT8_MAX) 85 | # define UINT8_MAX (255) 86 | #endif /* UINT8_MAX */ 87 | #if defined(ALPHABET_SIZE) && (ALPHABET_SIZE < 1) 88 | # undef ALPHABET_SIZE 89 | #endif 90 | #if !defined(ALPHABET_SIZE) 91 | # define ALPHABET_SIZE (UINT8_MAX + 1) 92 | #endif 93 | /* for divsufsort.c */ 94 | #define BUCKET_A_SIZE (ALPHABET_SIZE) 95 | #define BUCKET_B_SIZE (ALPHABET_SIZE * ALPHABET_SIZE) 96 | /* for sssort.c */ 97 | #if defined(SS_INSERTIONSORT_THRESHOLD) 98 | # if SS_INSERTIONSORT_THRESHOLD < 1 99 | # undef SS_INSERTIONSORT_THRESHOLD 100 | # define SS_INSERTIONSORT_THRESHOLD (1) 101 | # endif 102 | #else 103 | # define SS_INSERTIONSORT_THRESHOLD (8) 104 | #endif 105 | #if defined(SS_BLOCKSIZE) 106 | # if SS_BLOCKSIZE < 0 107 | # undef SS_BLOCKSIZE 108 | # define SS_BLOCKSIZE (0) 109 | # elif 32768 <= SS_BLOCKSIZE 110 | # undef SS_BLOCKSIZE 111 | # define SS_BLOCKSIZE (32767) 112 | # endif 113 | #else 114 | # define SS_BLOCKSIZE (1024) 115 | #endif 116 | /* minstacksize = log(SS_BLOCKSIZE) / log(3) * 2 */ 117 | #if SS_BLOCKSIZE == 0 118 | # if defined(BUILD_DIVSUFSORT64) 119 | # define SS_MISORT_STACKSIZE (96) 120 | # else 121 | # define SS_MISORT_STACKSIZE (64) 122 | # endif 123 | #elif SS_BLOCKSIZE <= 4096 124 | # define SS_MISORT_STACKSIZE (16) 125 | #else 126 | # define SS_MISORT_STACKSIZE (24) 127 | #endif 128 | #if defined(BUILD_DIVSUFSORT64) 129 | # define SS_SMERGE_STACKSIZE (64) 130 | #else 131 | # define SS_SMERGE_STACKSIZE (32) 132 | #endif 133 | /* for trsort.c */ 134 | #define TR_INSERTIONSORT_THRESHOLD (8) 135 | #if defined(BUILD_DIVSUFSORT64) 136 | # define TR_STACKSIZE (96) 137 | #else 138 | # define TR_STACKSIZE (64) 139 | #endif 140 | 141 | 142 | /*- Macros -*/ 143 | #ifndef SWAP 144 | # define SWAP(_a, _b) do { t = (_a); (_a) = (_b); (_b) = t; } while(0) 145 | #endif /* SWAP */ 146 | #ifndef MIN 147 | # define MIN(_a, _b) (((_a) < (_b)) ? (_a) : (_b)) 148 | #endif /* MIN */ 149 | #ifndef MAX 150 | # define MAX(_a, _b) (((_a) > (_b)) ? (_a) : (_b)) 151 | #endif /* MAX */ 152 | #define STACK_PUSH(_a, _b, _c, _d)\ 153 | do {\ 154 | assert(ssize < STACK_SIZE);\ 155 | stack[ssize].a = (_a), stack[ssize].b = (_b),\ 156 | stack[ssize].c = (_c), stack[ssize++].d = (_d);\ 157 | } while(0) 158 | #define STACK_PUSH5(_a, _b, _c, _d, _e)\ 159 | do {\ 160 | assert(ssize < STACK_SIZE);\ 161 | stack[ssize].a = (_a), stack[ssize].b = (_b),\ 162 | stack[ssize].c = (_c), stack[ssize].d = (_d), stack[ssize++].e = (_e);\ 163 | } while(0) 164 | #define STACK_POP(_a, _b, _c, _d)\ 165 | do {\ 166 | assert(0 <= ssize);\ 167 | if(ssize == 0) { return; }\ 168 | (_a) = stack[--ssize].a, (_b) = stack[ssize].b,\ 169 | (_c) = stack[ssize].c, (_d) = stack[ssize].d;\ 170 | } while(0) 171 | #define STACK_POP5(_a, _b, _c, _d, _e)\ 172 | do {\ 173 | assert(0 <= ssize);\ 174 | if(ssize == 0) { return; }\ 175 | (_a) = stack[--ssize].a, (_b) = stack[ssize].b,\ 176 | (_c) = stack[ssize].c, (_d) = stack[ssize].d, (_e) = stack[ssize].e;\ 177 | } while(0) 178 | /* for divsufsort.c */ 179 | #define BUCKET_A(_c0) bucket_A[(_c0)] 180 | #if ALPHABET_SIZE == 256 181 | #define BUCKET_B(_c0, _c1) (bucket_B[((_c1) << 8) | (_c0)]) 182 | #define BUCKET_BSTAR(_c0, _c1) (bucket_B[((_c0) << 8) | (_c1)]) 183 | #else 184 | #define BUCKET_B(_c0, _c1) (bucket_B[(_c1) * ALPHABET_SIZE + (_c0)]) 185 | #define BUCKET_BSTAR(_c0, _c1) (bucket_B[(_c0) * ALPHABET_SIZE + (_c1)]) 186 | #endif 187 | 188 | 189 | /*- Private Prototypes -*/ 190 | /* sssort.c */ 191 | void 192 | sssort(const sauchar_t *Td, const saidx_t *PA, 193 | saidx_t *first, saidx_t *last, 194 | saidx_t *buf, saidx_t bufsize, 195 | saidx_t depth, saidx_t n, saint_t lastsuffix); 196 | /* trsort.c */ 197 | void 198 | trsort(saidx_t *ISA, saidx_t *SA, saidx_t n, saidx_t depth); 199 | 200 | 201 | #ifdef __cplusplus 202 | } /* extern "C" */ 203 | #endif /* __cplusplus */ 204 | 205 | #endif /* _DIVSUFSORT_PRIVATE_H */ 206 | -------------------------------------------------------------------------------- /src/enc/apultra/expand.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/z64utils/z64compress/718d2a1556f2e98af9c0c0d45ce332956d3e72e3/src/enc/apultra/expand.c -------------------------------------------------------------------------------- /src/enc/apultra/expand.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/z64utils/z64compress/718d2a1556f2e98af9c0c0d45ce332956d3e72e3/src/enc/apultra/expand.h -------------------------------------------------------------------------------- /src/enc/apultra/format.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/z64utils/z64compress/718d2a1556f2e98af9c0c0d45ce332956d3e72e3/src/enc/apultra/format.h -------------------------------------------------------------------------------- /src/enc/apultra/libapultra.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/z64utils/z64compress/718d2a1556f2e98af9c0c0d45ce332956d3e72e3/src/enc/apultra/libapultra.h -------------------------------------------------------------------------------- /src/enc/apultra/matchfinder.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/z64utils/z64compress/718d2a1556f2e98af9c0c0d45ce332956d3e72e3/src/enc/apultra/matchfinder.c -------------------------------------------------------------------------------- /src/enc/apultra/matchfinder.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/z64utils/z64compress/718d2a1556f2e98af9c0c0d45ce332956d3e72e3/src/enc/apultra/matchfinder.h -------------------------------------------------------------------------------- /src/enc/apultra/shrink.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/z64utils/z64compress/718d2a1556f2e98af9c0c0d45ce332956d3e72e3/src/enc/apultra/shrink.c -------------------------------------------------------------------------------- /src/enc/apultra/shrink.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/z64utils/z64compress/718d2a1556f2e98af9c0c0d45ce332956d3e72e3/src/enc/apultra/shrink.h -------------------------------------------------------------------------------- /src/enc/apultra/shrink_context.c: -------------------------------------------------------------------------------- 1 | /* 2 | * shrink_context.c - compression context implementation 3 | * 4 | * Copyright (C) 2019 Emmanuel Marty 5 | * 6 | * This software is provided 'as-is', without any express or implied 7 | * warranty. In no event will the authors be held liable for any damages 8 | * arising from the use of this software. 9 | * 10 | * Permission is granted to anyone to use this software for any purpose, 11 | * including commercial applications, and to alter it and redistribute it 12 | * freely, subject to the following restrictions: 13 | * 14 | * 1. The origin of this software must not be misrepresented; you must not 15 | * claim that you wrote the original software. If you use this software 16 | * in a product, an acknowledgment in the product documentation would be 17 | * appreciated but is not required. 18 | * 2. Altered source versions must be plainly marked as such, and must not be 19 | * misrepresented as being the original software. 20 | * 3. This notice may not be removed or altered from any source distribution. 21 | */ 22 | 23 | /* 24 | * Uses the libdivsufsort library Copyright (c) 2003-2008 Yuta Mori 25 | * 26 | * Inspired by LZ4 by Yann Collet. https://github.com/lz4/lz4 27 | * With help, ideas, optimizations and speed measurements by spke 28 | * With ideas from Lizard by Przemyslaw Skibinski and Yann Collet. https://github.com/inikep/lizard 29 | * Also with ideas from smallz4 by Stephan Brumme. https://create.stephan-brumme.com/smallz4/ 30 | * 31 | */ 32 | 33 | #include 34 | #include 35 | //#include "shrink_context.h" 36 | //#include "shrink_block.h" 37 | #include "format.h" 38 | #include "matchfinder.h" 39 | //#include "lib.h" 40 | -------------------------------------------------------------------------------- /src/enc/enc.h: -------------------------------------------------------------------------------- 1 | #ifndef Z64COMPRESS_ENC_H_INCLUDED 2 | #define Z64COMPRESS_ENC_H_INCLUDED 3 | 4 | int yazenc( 5 | void *src 6 | , unsigned src_sz 7 | , void *dst 8 | , unsigned *dst_sz 9 | , void *_ctx 10 | ); 11 | void *yazCtx_new(void); 12 | void yazCtx_free(void *_ctx); 13 | int yazdec(void *_src, void *_dst, unsigned dstSz, unsigned *srcSz); 14 | 15 | int lzoenc( 16 | void *src 17 | , unsigned src_sz 18 | , void *dst 19 | , unsigned *dst_sz 20 | , void *_ctx 21 | ); 22 | void *lzoCtx_new(void); 23 | void lzoCtx_free(void *_ctx); 24 | 25 | int uclenc( 26 | void *src 27 | , unsigned src_sz 28 | , void *dst 29 | , unsigned *dst_sz 30 | , void *_ctx 31 | ); 32 | 33 | int zx7enc( 34 | void *src 35 | , unsigned src_sz 36 | , void *dst 37 | , unsigned *dst_sz 38 | , void *_ctx 39 | ); 40 | 41 | int 42 | zlibenc( 43 | void *_src 44 | , unsigned src_sz 45 | , void *_dst 46 | , unsigned *dst_sz 47 | , void *_ctx 48 | ); 49 | 50 | int aplenc( 51 | void *_src 52 | , unsigned src_sz 53 | , void *_dst 54 | , unsigned *dst_sz 55 | , void *_ctx 56 | ); 57 | 58 | #endif /* Z64COMPRESS_ENC_H_INCLUDED */ 59 | 60 | -------------------------------------------------------------------------------- /src/enc/lzo.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "lzo/lzoconf.h" 5 | #include "lzo/lzo1x.h" 6 | 7 | void 8 | lzoCtx_free(void *_ctx) 9 | { 10 | if (!_ctx) 11 | return; 12 | 13 | free(_ctx); 14 | } 15 | 16 | void * 17 | lzoCtx_new(void) 18 | { 19 | return malloc(LZO1X_999_MEM_COMPRESS); 20 | } 21 | 22 | int 23 | lzoenc( 24 | void *_src 25 | , unsigned src_sz 26 | , void *_dst 27 | , unsigned *dst_sz 28 | , void *_ctx 29 | ) 30 | { 31 | unsigned char *src = _src; 32 | unsigned char *dst = _dst; 33 | unsigned char *wrkmem = _ctx; 34 | lzo_uint result_sz = 0; 35 | 36 | extern int g_hlen; /* header length */ 37 | memset(dst, 0, g_hlen); 38 | memcpy(dst, "LZO0", 4); 39 | dst[4] = (src_sz >> 24); 40 | dst[5] = (src_sz >> 16); 41 | dst[6] = (src_sz >> 8); 42 | dst[7] = (src_sz >> 0); 43 | 44 | if (!wrkmem) 45 | return 1; 46 | 47 | memset(wrkmem, 0, LZO1X_999_MEM_COMPRESS); 48 | 49 | lzo1x_999_compress(src, src_sz, dst + g_hlen, &result_sz, wrkmem); 50 | 51 | *dst_sz = result_sz + g_hlen; 52 | 53 | return 0; 54 | } 55 | 56 | -------------------------------------------------------------------------------- /src/enc/lzo/config1x.h: -------------------------------------------------------------------------------- 1 | /* config1x.h -- configuration for the LZO1X algorithm 2 | 3 | This file is part of the LZO real-time data compression library. 4 | 5 | Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer 6 | All Rights Reserved. 7 | 8 | The LZO library is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of 11 | the License, or (at your option) any later version. 12 | 13 | The LZO library is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with the LZO library; see the file COPYING. 20 | If not, write to the Free Software Foundation, Inc., 21 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 22 | 23 | Markus F.X.J. Oberhumer 24 | 25 | http://www.oberhumer.com/opensource/lzo/ 26 | */ 27 | 28 | 29 | /* WARNING: this file should *not* be used by applications. It is 30 | part of the implementation of the library and is subject 31 | to change. 32 | */ 33 | 34 | 35 | #ifndef __LZO_CONFIG1X_H 36 | #define __LZO_CONFIG1X_H 1 37 | 38 | #if !defined(LZO1X) && !defined(LZO1Y) && !defined(LZO1Z) 39 | # define LZO1X 1 40 | #endif 41 | 42 | #include "lzo_conf.h" 43 | #if !defined(__LZO_IN_MINILZO) 44 | #include "lzo1x.h" 45 | #endif 46 | 47 | 48 | /*********************************************************************** 49 | // 50 | ************************************************************************/ 51 | 52 | #ifndef LZO_EOF_CODE 53 | #define LZO_EOF_CODE 1 54 | #endif 55 | #undef LZO_DETERMINISTIC 56 | 57 | #define M1_MAX_OFFSET 0x0400 58 | #ifndef M2_MAX_OFFSET 59 | #define M2_MAX_OFFSET 0x0800 60 | #endif 61 | #define M3_MAX_OFFSET 0x4000 62 | #define M4_MAX_OFFSET 0xbfff 63 | 64 | #define MX_MAX_OFFSET (M1_MAX_OFFSET + M2_MAX_OFFSET) 65 | 66 | #define M1_MIN_LEN 2 67 | #define M1_MAX_LEN 2 68 | #define M2_MIN_LEN 3 69 | #ifndef M2_MAX_LEN 70 | #define M2_MAX_LEN 8 71 | #endif 72 | #define M3_MIN_LEN 3 73 | #define M3_MAX_LEN 33 74 | #define M4_MIN_LEN 3 75 | #define M4_MAX_LEN 9 76 | 77 | #define M1_MARKER 0 78 | #define M2_MARKER 64 79 | #define M3_MARKER 32 80 | #define M4_MARKER 16 81 | 82 | 83 | /*********************************************************************** 84 | // 85 | ************************************************************************/ 86 | 87 | #ifndef MIN_LOOKAHEAD 88 | #define MIN_LOOKAHEAD (M2_MAX_LEN + 1) 89 | #endif 90 | 91 | #if defined(LZO_NEED_DICT_H) 92 | 93 | #ifndef LZO_HASH 94 | #define LZO_HASH LZO_HASH_LZO_INCREMENTAL_B 95 | #endif 96 | #define DL_MIN_LEN M2_MIN_LEN 97 | #include "lzo_dict.h" 98 | 99 | #endif 100 | 101 | 102 | 103 | #endif /* already included */ 104 | 105 | 106 | /* vim:set ts=4 sw=4 et: */ 107 | -------------------------------------------------------------------------------- /src/enc/lzo/lzo1_d.ch: -------------------------------------------------------------------------------- 1 | /* lzo1_d.ch -- common decompression stuff 2 | 3 | This file is part of the LZO real-time data compression library. 4 | 5 | Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer 6 | All Rights Reserved. 7 | 8 | The LZO library is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of 11 | the License, or (at your option) any later version. 12 | 13 | The LZO library is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with the LZO library; see the file COPYING. 20 | If not, write to the Free Software Foundation, Inc., 21 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 22 | 23 | Markus F.X.J. Oberhumer 24 | 25 | http://www.oberhumer.com/opensource/lzo/ 26 | */ 27 | 28 | 29 | 30 | #if defined(LZO_TEST_OVERRUN) 31 | # if !defined(LZO_TEST_OVERRUN_INPUT) 32 | # define LZO_TEST_OVERRUN_INPUT 2 33 | # endif 34 | # if !defined(LZO_TEST_OVERRUN_OUTPUT) 35 | # define LZO_TEST_OVERRUN_OUTPUT 2 36 | # endif 37 | # if !defined(LZO_TEST_OVERRUN_LOOKBEHIND) 38 | # define LZO_TEST_OVERRUN_LOOKBEHIND 1 39 | # endif 40 | #endif 41 | 42 | 43 | /*********************************************************************** 44 | // Overrun detection is internally handled by these macros: 45 | // 46 | // TEST_IP test input overrun at loop begin 47 | // NEED_IP test input overrun at every input byte 48 | // 49 | // TEST_OP test output overrun at loop begin 50 | // NEED_OP test output overrun at every output byte 51 | // 52 | // TEST_LB test match position 53 | // 54 | // The fastest decompressor results when testing for no overruns 55 | // and using LZO_EOF_CODE. 56 | ************************************************************************/ 57 | 58 | #undef TEST_IP 59 | #undef TEST_OP 60 | #undef TEST_IP_AND_TEST_OP 61 | #undef TEST_LB 62 | #undef TEST_LBO 63 | #undef NEED_IP 64 | #undef NEED_OP 65 | #undef TEST_IV 66 | #undef TEST_OV 67 | #undef HAVE_TEST_IP 68 | #undef HAVE_TEST_OP 69 | #undef HAVE_NEED_IP 70 | #undef HAVE_NEED_OP 71 | #undef HAVE_ANY_IP 72 | #undef HAVE_ANY_OP 73 | 74 | 75 | #if defined(LZO_TEST_OVERRUN_INPUT) 76 | # if (LZO_TEST_OVERRUN_INPUT >= 1) 77 | # define TEST_IP (ip < ip_end) 78 | # endif 79 | # if (LZO_TEST_OVERRUN_INPUT >= 2) 80 | # define NEED_IP(x) \ 81 | if ((lzo_uint)(ip_end - ip) < (lzo_uint)(x)) goto input_overrun 82 | # define TEST_IV(x) if ((x) > (lzo_uint)0 - (511)) goto input_overrun 83 | # endif 84 | #endif 85 | 86 | #if defined(LZO_TEST_OVERRUN_OUTPUT) 87 | # if (LZO_TEST_OVERRUN_OUTPUT >= 1) 88 | # define TEST_OP (op <= op_end) 89 | # endif 90 | # if (LZO_TEST_OVERRUN_OUTPUT >= 2) 91 | # undef TEST_OP /* don't need both of the tests here */ 92 | # define NEED_OP(x) \ 93 | if ((lzo_uint)(op_end - op) < (lzo_uint)(x)) goto output_overrun 94 | # define TEST_OV(x) if ((x) > (lzo_uint)0 - (511)) goto output_overrun 95 | # endif 96 | #endif 97 | 98 | #if defined(LZO_TEST_OVERRUN_LOOKBEHIND) 99 | # define TEST_LB(m_pos) if (PTR_LT(m_pos,out) || PTR_GE(m_pos,op)) goto lookbehind_overrun 100 | # define TEST_LBO(m_pos,o) if (PTR_LT(m_pos,out) || PTR_GE(m_pos,op-(o))) goto lookbehind_overrun 101 | #else 102 | # define TEST_LB(m_pos) ((void) 0) 103 | # define TEST_LBO(m_pos,o) ((void) 0) 104 | #endif 105 | 106 | 107 | #if !defined(LZO_EOF_CODE) && !defined(TEST_IP) 108 | /* if we have no EOF code, we have to test for the end of the input */ 109 | # define TEST_IP (ip < ip_end) 110 | #endif 111 | 112 | 113 | #if defined(TEST_IP) 114 | # define HAVE_TEST_IP 1 115 | #else 116 | # define TEST_IP 1 117 | #endif 118 | #if defined(TEST_OP) 119 | # define HAVE_TEST_OP 1 120 | #else 121 | # define TEST_OP 1 122 | #endif 123 | 124 | #if defined(HAVE_TEST_IP) && defined(HAVE_TEST_OP) 125 | # define TEST_IP_AND_TEST_OP (TEST_IP && TEST_OP) 126 | #elif defined(HAVE_TEST_IP) 127 | # define TEST_IP_AND_TEST_OP TEST_IP 128 | #elif defined(HAVE_TEST_OP) 129 | # define TEST_IP_AND_TEST_OP TEST_OP 130 | #else 131 | # define TEST_IP_AND_TEST_OP 1 132 | #endif 133 | 134 | #if defined(NEED_IP) 135 | # define HAVE_NEED_IP 1 136 | #else 137 | # define NEED_IP(x) ((void) 0) 138 | # define TEST_IV(x) ((void) 0) 139 | #endif 140 | #if defined(NEED_OP) 141 | # define HAVE_NEED_OP 1 142 | #else 143 | # define NEED_OP(x) ((void) 0) 144 | # define TEST_OV(x) ((void) 0) 145 | #endif 146 | 147 | 148 | #if defined(HAVE_TEST_IP) || defined(HAVE_NEED_IP) 149 | # define HAVE_ANY_IP 1 150 | #endif 151 | #if defined(HAVE_TEST_OP) || defined(HAVE_NEED_OP) 152 | # define HAVE_ANY_OP 1 153 | #endif 154 | 155 | 156 | /* vim:set ts=4 sw=4 et: */ 157 | -------------------------------------------------------------------------------- /src/enc/lzo/lzo1x.h: -------------------------------------------------------------------------------- 1 | /* lzo1x.h -- public interface of the LZO1X compression algorithm 2 | 3 | This file is part of the LZO real-time data compression library. 4 | 5 | Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer 6 | All Rights Reserved. 7 | 8 | The LZO library is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of 11 | the License, or (at your option) any later version. 12 | 13 | The LZO library is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with the LZO library; see the file COPYING. 20 | If not, write to the Free Software Foundation, Inc., 21 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 22 | 23 | Markus F.X.J. Oberhumer 24 | 25 | http://www.oberhumer.com/opensource/lzo/ 26 | */ 27 | 28 | 29 | #ifndef __LZO1X_H_INCLUDED 30 | #define __LZO1X_H_INCLUDED 1 31 | 32 | #ifndef __LZOCONF_H_INCLUDED 33 | #include 34 | #endif 35 | 36 | #ifdef __cplusplus 37 | extern "C" { 38 | #endif 39 | 40 | 41 | /*********************************************************************** 42 | // 43 | ************************************************************************/ 44 | 45 | /* Memory required for the wrkmem parameter. 46 | * When the required size is 0, you can also pass a NULL pointer. 47 | */ 48 | 49 | #define LZO1X_MEM_COMPRESS LZO1X_1_MEM_COMPRESS 50 | #define LZO1X_MEM_DECOMPRESS (0) 51 | #define LZO1X_MEM_OPTIMIZE (0) 52 | 53 | 54 | /* decompression */ 55 | LZO_EXTERN(int) 56 | lzo1x_decompress ( const lzo_bytep src, lzo_uint src_len, 57 | lzo_bytep dst, lzo_uintp dst_len, 58 | lzo_voidp wrkmem /* NOT USED */ ); 59 | 60 | /* safe decompression with overrun testing */ 61 | LZO_EXTERN(int) 62 | lzo1x_decompress_safe ( const lzo_bytep src, lzo_uint src_len, 63 | lzo_bytep dst, lzo_uintp dst_len, 64 | lzo_voidp wrkmem /* NOT USED */ ); 65 | 66 | 67 | /*********************************************************************** 68 | // 69 | ************************************************************************/ 70 | 71 | #define LZO1X_1_MEM_COMPRESS ((lzo_uint32_t) (16384L * lzo_sizeof_dict_t)) 72 | 73 | LZO_EXTERN(int) 74 | lzo1x_1_compress ( const lzo_bytep src, lzo_uint src_len, 75 | lzo_bytep dst, lzo_uintp dst_len, 76 | lzo_voidp wrkmem ); 77 | 78 | 79 | /*********************************************************************** 80 | // special compressor versions 81 | ************************************************************************/ 82 | 83 | /* this version needs only 8 KiB work memory */ 84 | #define LZO1X_1_11_MEM_COMPRESS ((lzo_uint32_t) (2048L * lzo_sizeof_dict_t)) 85 | 86 | LZO_EXTERN(int) 87 | lzo1x_1_11_compress ( const lzo_bytep src, lzo_uint src_len, 88 | lzo_bytep dst, lzo_uintp dst_len, 89 | lzo_voidp wrkmem ); 90 | 91 | 92 | /* this version needs 16 KiB work memory */ 93 | #define LZO1X_1_12_MEM_COMPRESS ((lzo_uint32_t) (4096L * lzo_sizeof_dict_t)) 94 | 95 | LZO_EXTERN(int) 96 | lzo1x_1_12_compress ( const lzo_bytep src, lzo_uint src_len, 97 | lzo_bytep dst, lzo_uintp dst_len, 98 | lzo_voidp wrkmem ); 99 | 100 | 101 | /* use this version if you need a little more compression speed */ 102 | #define LZO1X_1_15_MEM_COMPRESS ((lzo_uint32_t) (32768L * lzo_sizeof_dict_t)) 103 | 104 | LZO_EXTERN(int) 105 | lzo1x_1_15_compress ( const lzo_bytep src, lzo_uint src_len, 106 | lzo_bytep dst, lzo_uintp dst_len, 107 | lzo_voidp wrkmem ); 108 | 109 | 110 | /*********************************************************************** 111 | // better compression ratio at the cost of more memory and time 112 | ************************************************************************/ 113 | 114 | #define LZO1X_999_MEM_COMPRESS ((lzo_uint32_t) (14 * 16384L * sizeof(short))) 115 | 116 | LZO_EXTERN(int) 117 | lzo1x_999_compress ( const lzo_bytep src, lzo_uint src_len, 118 | lzo_bytep dst, lzo_uintp dst_len, 119 | lzo_voidp wrkmem ); 120 | 121 | 122 | /*********************************************************************** 123 | // 124 | ************************************************************************/ 125 | 126 | LZO_EXTERN(int) 127 | lzo1x_999_compress_dict ( const lzo_bytep src, lzo_uint src_len, 128 | lzo_bytep dst, lzo_uintp dst_len, 129 | lzo_voidp wrkmem, 130 | const lzo_bytep dict, lzo_uint dict_len ); 131 | 132 | LZO_EXTERN(int) 133 | lzo1x_999_compress_level ( const lzo_bytep src, lzo_uint src_len, 134 | lzo_bytep dst, lzo_uintp dst_len, 135 | lzo_voidp wrkmem, 136 | const lzo_bytep dict, lzo_uint dict_len, 137 | lzo_callback_p cb, 138 | int compression_level ); 139 | 140 | LZO_EXTERN(int) 141 | lzo1x_decompress_dict_safe ( const lzo_bytep src, lzo_uint src_len, 142 | lzo_bytep dst, lzo_uintp dst_len, 143 | lzo_voidp wrkmem /* NOT USED */, 144 | const lzo_bytep dict, lzo_uint dict_len ); 145 | 146 | 147 | /*********************************************************************** 148 | // optimize a compressed data block 149 | ************************************************************************/ 150 | 151 | LZO_EXTERN(int) 152 | lzo1x_optimize ( lzo_bytep src, lzo_uint src_len, 153 | lzo_bytep dst, lzo_uintp dst_len, 154 | lzo_voidp wrkmem /* NOT USED */ ); 155 | 156 | 157 | 158 | #ifdef __cplusplus 159 | } /* extern "C" */ 160 | #endif 161 | 162 | #endif /* already included */ 163 | 164 | 165 | /* vim:set ts=4 sw=4 et: */ 166 | -------------------------------------------------------------------------------- /src/enc/lzo/lzo1x_1.c: -------------------------------------------------------------------------------- 1 | /* lzo1x_1.c -- LZO1X-1 compression 2 | 3 | This file is part of the LZO real-time data compression library. 4 | 5 | Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer 6 | All Rights Reserved. 7 | 8 | The LZO library is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of 11 | the License, or (at your option) any later version. 12 | 13 | The LZO library is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with the LZO library; see the file COPYING. 20 | If not, write to the Free Software Foundation, Inc., 21 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 22 | 23 | Markus F.X.J. Oberhumer 24 | 25 | http://www.oberhumer.com/opensource/lzo/ 26 | */ 27 | 28 | 29 | #include "lzo_conf.h" 30 | #if 1 && defined(UA_GET_LE32) 31 | #undef LZO_DICT_USE_PTR 32 | #define LZO_DICT_USE_PTR 0 33 | #undef lzo_dict_t 34 | #define lzo_dict_t lzo_uint16_t 35 | #endif 36 | 37 | #define LZO_NEED_DICT_H 1 38 | #ifndef D_BITS 39 | #define D_BITS 14 40 | #endif 41 | #define D_INDEX1(d,p) d = DM(DMUL(0x21,DX3(p,5,5,6)) >> 5) 42 | #define D_INDEX2(d,p) d = (d & (D_MASK & 0x7ff)) ^ (D_HIGH | 0x1f) 43 | #if 1 44 | #define DINDEX(dv,p) DM(((DMUL(0x1824429d,dv)) >> (32-D_BITS))) 45 | #else 46 | #define DINDEX(dv,p) DM((dv) + ((dv) >> (32-D_BITS))) 47 | #endif 48 | #include "config1x.h" 49 | #define LZO_DETERMINISTIC !(LZO_DICT_USE_PTR) 50 | 51 | #ifndef DO_COMPRESS 52 | #define DO_COMPRESS lzo1x_1_compress 53 | #endif 54 | 55 | #include "lzo1x_c.ch" 56 | 57 | /* vim:set ts=4 sw=4 et: */ 58 | -------------------------------------------------------------------------------- /src/enc/lzo/lzo1x_d1.c: -------------------------------------------------------------------------------- 1 | /* lzo1x_d1.c -- LZO1X decompression 2 | 3 | This file is part of the LZO real-time data compression library. 4 | 5 | Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer 6 | All Rights Reserved. 7 | 8 | The LZO library is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of 11 | the License, or (at your option) any later version. 12 | 13 | The LZO library is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with the LZO library; see the file COPYING. 20 | If not, write to the Free Software Foundation, Inc., 21 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 22 | 23 | Markus F.X.J. Oberhumer 24 | 25 | http://www.oberhumer.com/opensource/lzo/ 26 | */ 27 | 28 | 29 | #include "config1x.h" 30 | 31 | #undef LZO_TEST_OVERRUN 32 | #define DO_DECOMPRESS lzo1x_decompress 33 | 34 | #include "lzo1x_d.ch" 35 | 36 | /* vim:set ts=4 sw=4 et: */ 37 | -------------------------------------------------------------------------------- /src/enc/lzo/lzo1x_d2.c: -------------------------------------------------------------------------------- 1 | /* lzo1x_d2.c -- LZO1X decompression with overrun testing 2 | 3 | This file is part of the LZO real-time data compression library. 4 | 5 | Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer 6 | All Rights Reserved. 7 | 8 | The LZO library is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of 11 | the License, or (at your option) any later version. 12 | 13 | The LZO library is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with the LZO library; see the file COPYING. 20 | If not, write to the Free Software Foundation, Inc., 21 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 22 | 23 | Markus F.X.J. Oberhumer 24 | 25 | http://www.oberhumer.com/opensource/lzo/ 26 | */ 27 | 28 | 29 | #include "config1x.h" 30 | 31 | #define LZO_TEST_OVERRUN 1 32 | #define DO_DECOMPRESS lzo1x_decompress_safe 33 | 34 | #include "lzo1x_d.ch" 35 | 36 | #if defined(LZO_ARCH_I386) && defined(LZO_USE_ASM) 37 | LZO_EXTERN(int) lzo1x_decompress_asm_safe 38 | (const lzo_bytep src, lzo_uint src_len, 39 | lzo_bytep dst, lzo_uintp dst_len, 40 | lzo_voidp wrkmem); 41 | LZO_PUBLIC(int) lzo1x_decompress_asm_safe 42 | (const lzo_bytep src, lzo_uint src_len, 43 | lzo_bytep dst, lzo_uintp dst_len, 44 | lzo_voidp wrkmem) 45 | { 46 | return lzo1x_decompress_safe(src, src_len, dst, dst_len, wrkmem); 47 | } 48 | LZO_EXTERN(int) lzo1x_decompress_asm_fast_safe 49 | (const lzo_bytep src, lzo_uint src_len, 50 | lzo_bytep dst, lzo_uintp dst_len, 51 | lzo_voidp wrkmem); 52 | LZO_PUBLIC(int) lzo1x_decompress_asm_fast_safe 53 | (const lzo_bytep src, lzo_uint src_len, 54 | lzo_bytep dst, lzo_uintp dst_len, 55 | lzo_voidp wrkmem) 56 | { 57 | return lzo1x_decompress_safe(src, src_len, dst, dst_len, wrkmem); 58 | } 59 | #endif 60 | 61 | /* vim:set ts=4 sw=4 et: */ 62 | -------------------------------------------------------------------------------- /src/enc/lzo/lzo1x_d3.c: -------------------------------------------------------------------------------- 1 | /* lzo1x_d3.c -- LZO1X decompression with preset dictionary 2 | 3 | This file is part of the LZO real-time data compression library. 4 | 5 | Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer 6 | All Rights Reserved. 7 | 8 | The LZO library is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of 11 | the License, or (at your option) any later version. 12 | 13 | The LZO library is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with the LZO library; see the file COPYING. 20 | If not, write to the Free Software Foundation, Inc., 21 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 22 | 23 | Markus F.X.J. Oberhumer 24 | 25 | http://www.oberhumer.com/opensource/lzo/ 26 | */ 27 | 28 | 29 | #include "config1x.h" 30 | 31 | #define LZO_TEST_OVERRUN 1 32 | 33 | 34 | #define SLOW_MEMCPY(a,b,l) { do *a++ = *b++; while (--l > 0); } 35 | #define FAST_MEMCPY(a,b,l) { lzo_memcpy(a,b,l); a += l; } 36 | 37 | #if 1 && defined(FAST_MEMCPY) 38 | # define DICT_MEMMOVE(op,m_pos,m_len,m_off) \ 39 | if (m_off >= (m_len)) \ 40 | FAST_MEMCPY(op,m_pos,m_len) \ 41 | else \ 42 | SLOW_MEMCPY(op,m_pos,m_len) 43 | #else 44 | # define DICT_MEMMOVE(op,m_pos,m_len,m_off) \ 45 | SLOW_MEMCPY(op,m_pos,m_len) 46 | #endif 47 | 48 | #if !defined(FAST_MEMCPY) 49 | # define FAST_MEMCPY SLOW_MEMCPY 50 | #endif 51 | 52 | 53 | #define COPY_DICT_DICT(m_len,m_off) \ 54 | { \ 55 | const lzo_bytep m_pos; \ 56 | m_off -= pd(op, out); assert(m_off > 0); \ 57 | if (m_off > dict_len) goto lookbehind_overrun; \ 58 | m_pos = dict_end - m_off; \ 59 | if (m_len > m_off) \ 60 | { \ 61 | m_len -= m_off; \ 62 | FAST_MEMCPY(op,m_pos,m_off) \ 63 | m_pos = out; \ 64 | SLOW_MEMCPY(op,m_pos,m_len) \ 65 | } \ 66 | else \ 67 | FAST_MEMCPY(op,m_pos,m_len) \ 68 | } 69 | 70 | #define COPY_DICT(m_len,m_off) \ 71 | assert(m_len >= 2); assert(m_off > 0); assert(op > out); \ 72 | if (m_off <= pd(op, out)) \ 73 | { \ 74 | const lzo_bytep m_pos = op - m_off; \ 75 | DICT_MEMMOVE(op,m_pos,m_len,m_off) \ 76 | } \ 77 | else \ 78 | COPY_DICT_DICT(m_len,m_off) 79 | 80 | 81 | 82 | 83 | LZO_PUBLIC(int) 84 | lzo1x_decompress_dict_safe ( const lzo_bytep in, lzo_uint in_len, 85 | lzo_bytep out, lzo_uintp out_len, 86 | lzo_voidp wrkmem /* NOT USED */, 87 | const lzo_bytep dict, lzo_uint dict_len) 88 | 89 | 90 | #include "lzo1x_d.ch" 91 | 92 | 93 | /* vim:set ts=4 sw=4 et: */ 94 | -------------------------------------------------------------------------------- /src/enc/lzo/lzo_conf.h: -------------------------------------------------------------------------------- 1 | /* lzo_conf.h -- main internal configuration file for the the LZO library 2 | 3 | This file is part of the LZO real-time data compression library. 4 | 5 | Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer 6 | All Rights Reserved. 7 | 8 | The LZO library is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of 11 | the License, or (at your option) any later version. 12 | 13 | The LZO library is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with the LZO library; see the file COPYING. 20 | If not, write to the Free Software Foundation, Inc., 21 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 22 | 23 | Markus F.X.J. Oberhumer 24 | 25 | http://www.oberhumer.com/opensource/lzo/ 26 | */ 27 | 28 | 29 | /* WARNING: this file should *not* be used by applications. It is 30 | part of the implementation of the library and is subject 31 | to change. 32 | */ 33 | 34 | 35 | #ifndef __LZO_CONF_H 36 | #define __LZO_CONF_H 1 37 | 38 | #if !defined(__LZO_IN_MINILZO) 39 | #if defined(LZO_CFG_FREESTANDING) && (LZO_CFG_FREESTANDING) 40 | # define LZO_LIBC_FREESTANDING 1 41 | # define LZO_OS_FREESTANDING 1 42 | #endif 43 | #if defined(LZO_CFG_EXTRA_CONFIG_HEADER) 44 | # include LZO_CFG_EXTRA_CONFIG_HEADER 45 | #endif 46 | #if defined(__LZOCONF_H) || defined(__LZOCONF_H_INCLUDED) 47 | # error "include this file first" 48 | #endif 49 | #if defined(LZO_CFG_BUILD_DLL) && (LZO_CFG_BUILD_DLL+0) && !defined(__LZO_EXPORT1) && !defined(__LZO_EXPORT2) && 0 50 | /* idea: we could auto-define __LZO_EXPORT1 for DLL exports */ 51 | #ifndef __LZODEFS_H_INCLUDED 52 | #if defined(LZO_HAVE_CONFIG_H) 53 | # include 54 | #endif 55 | #include 56 | #include 57 | #include "lzodefs.h" 58 | #endif 59 | /* #define __LZO_EXPORT1 __attribute__((__visibility__("default"))) */ 60 | /* #define __LZO_EXPORT1 __declspec(dllexport) */ 61 | #endif 62 | #include "lzoconf.h" 63 | #if defined(LZO_CFG_EXTRA_CONFIG_HEADER2) 64 | # include LZO_CFG_EXTRA_CONFIG_HEADER2 65 | #endif 66 | #endif /* !defined(__LZO_IN_MINILZO) */ 67 | 68 | #if !defined(__LZOCONF_H_INCLUDED) || (LZO_VERSION+0 != 0x20a0) 69 | # error "version mismatch" 70 | #endif 71 | 72 | 73 | /*********************************************************************** 74 | // pragmas 75 | ************************************************************************/ 76 | 77 | #if (LZO_CC_MSC && (_MSC_VER >= 1000 && _MSC_VER < 1100)) 78 | /* disable bogus "unreachable code" warnings */ 79 | # pragma warning(disable: 4702) 80 | #endif 81 | #if (LZO_CC_MSC && (_MSC_VER >= 1000)) 82 | # pragma warning(disable: 4127 4701) 83 | /* disable warnings about inlining */ 84 | # pragma warning(disable: 4514 4710 4711) 85 | #endif 86 | #if (LZO_CC_MSC && (_MSC_VER >= 1300)) 87 | /* disable '-Wall' warnings in system header files */ 88 | # pragma warning(disable: 4820) 89 | #endif 90 | #if (LZO_CC_MSC && (_MSC_VER >= 1800)) 91 | /* disable '-Wall' warnings in system header files */ 92 | # pragma warning(disable: 4746) 93 | #endif 94 | #if (LZO_CC_INTELC && (__INTEL_COMPILER >= 900)) 95 | /* disable pedantic warnings in system header files */ 96 | # pragma warning(disable: 1684) 97 | #endif 98 | 99 | #if (LZO_CC_SUNPROC) 100 | #if !defined(__cplusplus) 101 | # pragma error_messages(off,E_END_OF_LOOP_CODE_NOT_REACHED) 102 | # pragma error_messages(off,E_LOOP_NOT_ENTERED_AT_TOP) 103 | # pragma error_messages(off,E_STATEMENT_NOT_REACHED) 104 | #endif 105 | #endif 106 | 107 | 108 | /*********************************************************************** 109 | // function types 110 | ************************************************************************/ 111 | 112 | #if !defined(__LZO_NOEXPORT1) 113 | # define __LZO_NOEXPORT1 /*empty*/ 114 | #endif 115 | #if !defined(__LZO_NOEXPORT2) 116 | # define __LZO_NOEXPORT2 /*empty*/ 117 | #endif 118 | 119 | #if 1 120 | # define LZO_PUBLIC_DECL(r) LZO_EXTERN(r) 121 | #endif 122 | #if 1 123 | # define LZO_PUBLIC_IMPL(r) LZO_PUBLIC(r) 124 | #endif 125 | #if !defined(LZO_LOCAL_DECL) 126 | # define LZO_LOCAL_DECL(r) __LZO_EXTERN_C LZO_LOCAL_IMPL(r) 127 | #endif 128 | #if !defined(LZO_LOCAL_IMPL) 129 | # define LZO_LOCAL_IMPL(r) __LZO_NOEXPORT1 r __LZO_NOEXPORT2 __LZO_CDECL 130 | #endif 131 | #if 1 132 | # define LZO_STATIC_DECL(r) LZO_PRIVATE(r) 133 | #endif 134 | #if 1 135 | # define LZO_STATIC_IMPL(r) LZO_PRIVATE(r) 136 | #endif 137 | 138 | 139 | /*********************************************************************** 140 | // 141 | ************************************************************************/ 142 | 143 | #if defined(__LZO_IN_MINILZO) || (LZO_CFG_FREESTANDING) 144 | #elif 1 145 | # include 146 | #else 147 | # define LZO_WANT_ACC_INCD_H 1 148 | #endif 149 | #if defined(LZO_HAVE_CONFIG_H) 150 | # define LZO_CFG_NO_CONFIG_HEADER 1 151 | #endif 152 | #include "lzo_supp.h" 153 | 154 | /* Integral types */ 155 | #if 1 || defined(lzo_int8_t) || defined(lzo_uint8_t) 156 | LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int8_t) == 1) 157 | LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint8_t) == 1) 158 | #endif 159 | #if 1 || defined(lzo_int16_t) || defined(lzo_uint16_t) 160 | LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int16_t) == 2) 161 | LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint16_t) == 2) 162 | #endif 163 | #if 1 || defined(lzo_int32_t) || defined(lzo_uint32_t) 164 | LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32_t) == 4) 165 | LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint32_t) == 4) 166 | #endif 167 | #if defined(lzo_int64_t) || defined(lzo_uint64_t) 168 | LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64_t) == 8) 169 | LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint64_t) == 8) 170 | #endif 171 | 172 | #if (LZO_CFG_FREESTANDING) 173 | # undef HAVE_MEMCMP 174 | # undef HAVE_MEMCPY 175 | # undef HAVE_MEMMOVE 176 | # undef HAVE_MEMSET 177 | #endif 178 | 179 | #if !(HAVE_MEMCMP) 180 | # undef memcmp 181 | # define memcmp(a,b,c) lzo_memcmp(a,b,c) 182 | #else 183 | # undef lzo_memcmp 184 | # define lzo_memcmp(a,b,c) memcmp(a,b,c) 185 | #endif 186 | #if !(HAVE_MEMCPY) 187 | # undef memcpy 188 | # define memcpy(a,b,c) lzo_memcpy(a,b,c) 189 | #else 190 | # undef lzo_memcpy 191 | # define lzo_memcpy(a,b,c) memcpy(a,b,c) 192 | #endif 193 | #if !(HAVE_MEMMOVE) 194 | # undef memmove 195 | # define memmove(a,b,c) lzo_memmove(a,b,c) 196 | #else 197 | # undef lzo_memmove 198 | # define lzo_memmove(a,b,c) memmove(a,b,c) 199 | #endif 200 | #if !(HAVE_MEMSET) 201 | # undef memset 202 | # define memset(a,b,c) lzo_memset(a,b,c) 203 | #else 204 | # undef lzo_memset 205 | # define lzo_memset(a,b,c) memset(a,b,c) 206 | #endif 207 | 208 | #undef NDEBUG 209 | #if (LZO_CFG_FREESTANDING) 210 | # undef LZO_DEBUG 211 | # define NDEBUG 1 212 | # undef assert 213 | # define assert(e) ((void)0) 214 | #else 215 | # if !defined(LZO_DEBUG) 216 | # define NDEBUG 1 217 | # endif 218 | # include 219 | #endif 220 | 221 | #if 0 && defined(__BOUNDS_CHECKING_ON) 222 | # include 223 | #else 224 | # define BOUNDS_CHECKING_OFF_DURING(stmt) stmt 225 | # define BOUNDS_CHECKING_OFF_IN_EXPR(expr) (expr) 226 | #endif 227 | 228 | #if (LZO_CFG_PGO) 229 | # undef __lzo_likely 230 | # undef __lzo_unlikely 231 | # define __lzo_likely(e) (e) 232 | # define __lzo_unlikely(e) (e) 233 | #endif 234 | 235 | #undef _ 236 | #undef __ 237 | #undef ___ 238 | #undef ____ 239 | #undef _p0 240 | #undef _p1 241 | #undef _p2 242 | #undef _p3 243 | #undef _p4 244 | #undef _s0 245 | #undef _s1 246 | #undef _s2 247 | #undef _s3 248 | #undef _s4 249 | #undef _ww 250 | 251 | 252 | /*********************************************************************** 253 | // 254 | ************************************************************************/ 255 | 256 | #if 1 257 | # define LZO_BYTE(x) ((unsigned char) (x)) 258 | #else 259 | # define LZO_BYTE(x) ((unsigned char) ((x) & 0xff)) 260 | #endif 261 | 262 | #define LZO_MAX(a,b) ((a) >= (b) ? (a) : (b)) 263 | #define LZO_MIN(a,b) ((a) <= (b) ? (a) : (b)) 264 | #define LZO_MAX3(a,b,c) ((a) >= (b) ? LZO_MAX(a,c) : LZO_MAX(b,c)) 265 | #define LZO_MIN3(a,b,c) ((a) <= (b) ? LZO_MIN(a,c) : LZO_MIN(b,c)) 266 | 267 | #define lzo_sizeof(type) ((lzo_uint) (sizeof(type))) 268 | 269 | #define LZO_HIGH(array) ((lzo_uint) (sizeof(array)/sizeof(*(array)))) 270 | 271 | /* this always fits into 32 bits */ 272 | #define LZO_SIZE(bits) (1u << (bits)) 273 | #define LZO_MASK(bits) (LZO_SIZE(bits) - 1) 274 | 275 | #define LZO_USIZE(bits) ((lzo_uint) 1 << (bits)) 276 | #define LZO_UMASK(bits) (LZO_USIZE(bits) - 1) 277 | 278 | #if !defined(DMUL) 279 | #if 0 280 | /* 32*32 multiplies may be faster than 64*64 on some 64-bit machines, 281 | * but then we need extra casts from unsigned<->size_t */ 282 | # define DMUL(a,b) ((lzo_xint) ((lzo_uint32_t)(a) * (lzo_uint32_t)(b))) 283 | #else 284 | # define DMUL(a,b) ((lzo_xint) ((a) * (b))) 285 | #endif 286 | #endif 287 | 288 | 289 | /*********************************************************************** 290 | // compiler and architecture specific stuff 291 | ************************************************************************/ 292 | 293 | /* Some defines that indicate if memory can be accessed at unaligned 294 | * memory addresses. You should also test that this is actually faster 295 | * even if it is allowed by your system. 296 | */ 297 | 298 | #include "lzo_func.h" 299 | 300 | #ifndef UA_SET1 301 | #define UA_SET1 LZO_MEMOPS_SET1 302 | #endif 303 | #ifndef UA_SET2 304 | #define UA_SET2 LZO_MEMOPS_SET2 305 | #endif 306 | #ifndef UA_SET3 307 | #define UA_SET3 LZO_MEMOPS_SET3 308 | #endif 309 | #ifndef UA_SET4 310 | #define UA_SET4 LZO_MEMOPS_SET4 311 | #endif 312 | #ifndef UA_MOVE1 313 | #define UA_MOVE1 LZO_MEMOPS_MOVE1 314 | #endif 315 | #ifndef UA_MOVE2 316 | #define UA_MOVE2 LZO_MEMOPS_MOVE2 317 | #endif 318 | #ifndef UA_MOVE3 319 | #define UA_MOVE3 LZO_MEMOPS_MOVE3 320 | #endif 321 | #ifndef UA_MOVE4 322 | #define UA_MOVE4 LZO_MEMOPS_MOVE4 323 | #endif 324 | #ifndef UA_MOVE8 325 | #define UA_MOVE8 LZO_MEMOPS_MOVE8 326 | #endif 327 | #ifndef UA_COPY1 328 | #define UA_COPY1 LZO_MEMOPS_COPY1 329 | #endif 330 | #ifndef UA_COPY2 331 | #define UA_COPY2 LZO_MEMOPS_COPY2 332 | #endif 333 | #ifndef UA_COPY3 334 | #define UA_COPY3 LZO_MEMOPS_COPY3 335 | #endif 336 | #ifndef UA_COPY4 337 | #define UA_COPY4 LZO_MEMOPS_COPY4 338 | #endif 339 | #ifndef UA_COPY8 340 | #define UA_COPY8 LZO_MEMOPS_COPY8 341 | #endif 342 | #ifndef UA_COPYN 343 | #define UA_COPYN LZO_MEMOPS_COPYN 344 | #endif 345 | #ifndef UA_COPYN_X 346 | #define UA_COPYN_X LZO_MEMOPS_COPYN 347 | #endif 348 | #ifndef UA_GET_LE16 349 | #define UA_GET_LE16 LZO_MEMOPS_GET_LE16 350 | #endif 351 | #ifndef UA_GET_LE32 352 | #define UA_GET_LE32 LZO_MEMOPS_GET_LE32 353 | #endif 354 | #ifdef LZO_MEMOPS_GET_LE64 355 | #ifndef UA_GET_LE64 356 | #define UA_GET_LE64 LZO_MEMOPS_GET_LE64 357 | #endif 358 | #endif 359 | #ifndef UA_GET_NE16 360 | #define UA_GET_NE16 LZO_MEMOPS_GET_NE16 361 | #endif 362 | #ifndef UA_GET_NE32 363 | #define UA_GET_NE32 LZO_MEMOPS_GET_NE32 364 | #endif 365 | #ifdef LZO_MEMOPS_GET_NE64 366 | #ifndef UA_GET_NE64 367 | #define UA_GET_NE64 LZO_MEMOPS_GET_NE64 368 | #endif 369 | #endif 370 | #ifndef UA_PUT_LE16 371 | #define UA_PUT_LE16 LZO_MEMOPS_PUT_LE16 372 | #endif 373 | #ifndef UA_PUT_LE32 374 | #define UA_PUT_LE32 LZO_MEMOPS_PUT_LE32 375 | #endif 376 | #ifndef UA_PUT_NE16 377 | #define UA_PUT_NE16 LZO_MEMOPS_PUT_NE16 378 | #endif 379 | #ifndef UA_PUT_NE32 380 | #define UA_PUT_NE32 LZO_MEMOPS_PUT_NE32 381 | #endif 382 | 383 | 384 | /* Fast memcpy that copies multiples of 8 byte chunks. 385 | * len is the number of bytes. 386 | * note: all parameters must be lvalues, len >= 8 387 | * dest and src advance, len is undefined afterwards 388 | */ 389 | 390 | #define MEMCPY8_DS(dest,src,len) \ 391 | lzo_memcpy(dest,src,len); dest += len; src += len 392 | 393 | #define BZERO8_PTR(s,l,n) \ 394 | lzo_memset((lzo_voidp)(s),0,(lzo_uint)(l)*(n)) 395 | 396 | #define MEMCPY_DS(dest,src,len) \ 397 | do *dest++ = *src++; while (--len > 0) 398 | 399 | 400 | /*********************************************************************** 401 | // 402 | ************************************************************************/ 403 | 404 | LZO_EXTERN(const lzo_bytep) lzo_copyright(void); 405 | 406 | #include "lzo_ptr.h" 407 | 408 | /* Generate compressed data in a deterministic way. 409 | * This is fully portable, and compression can be faster as well. 410 | * A reason NOT to be deterministic is when the block size is 411 | * very small (e.g. 8kB) or the dictionary is big, because 412 | * then the initialization of the dictionary becomes a relevant 413 | * magnitude for compression speed. 414 | */ 415 | #ifndef LZO_DETERMINISTIC 416 | #define LZO_DETERMINISTIC 1 417 | #endif 418 | 419 | 420 | #ifndef LZO_DICT_USE_PTR 421 | #define LZO_DICT_USE_PTR 1 422 | #endif 423 | 424 | #if (LZO_DICT_USE_PTR) 425 | # define lzo_dict_t const lzo_bytep 426 | # define lzo_dict_p lzo_dict_t * 427 | #else 428 | # define lzo_dict_t lzo_uint 429 | # define lzo_dict_p lzo_dict_t * 430 | #endif 431 | 432 | 433 | #endif /* already included */ 434 | 435 | 436 | /* vim:set ts=4 sw=4 et: */ 437 | -------------------------------------------------------------------------------- /src/enc/lzo/lzo_dict.h: -------------------------------------------------------------------------------- 1 | /* lzo_dict.h -- dictionary definitions for the the LZO library 2 | 3 | This file is part of the LZO real-time data compression library. 4 | 5 | Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer 6 | All Rights Reserved. 7 | 8 | The LZO library is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of 11 | the License, or (at your option) any later version. 12 | 13 | The LZO library is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with the LZO library; see the file COPYING. 20 | If not, write to the Free Software Foundation, Inc., 21 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 22 | 23 | Markus F.X.J. Oberhumer 24 | 25 | http://www.oberhumer.com/opensource/lzo/ 26 | */ 27 | 28 | 29 | /* WARNING: this file should *not* be used by applications. It is 30 | part of the implementation of the library and is subject 31 | to change. 32 | */ 33 | 34 | 35 | #ifndef __LZO_DICT_H 36 | #define __LZO_DICT_H 1 37 | 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | 42 | 43 | 44 | /*********************************************************************** 45 | // dictionary size 46 | ************************************************************************/ 47 | 48 | /* dictionary needed for compression */ 49 | #if !defined(D_BITS) && defined(DBITS) 50 | # define D_BITS DBITS 51 | #endif 52 | #if !defined(D_BITS) 53 | # error "D_BITS is not defined" 54 | #endif 55 | #if (D_BITS < 16) 56 | # define D_SIZE LZO_SIZE(D_BITS) 57 | # define D_MASK LZO_MASK(D_BITS) 58 | #else 59 | # define D_SIZE LZO_USIZE(D_BITS) 60 | # define D_MASK LZO_UMASK(D_BITS) 61 | #endif 62 | #define D_HIGH ((D_MASK >> 1) + 1) 63 | 64 | 65 | /* dictionary depth */ 66 | #if !defined(DD_BITS) 67 | # define DD_BITS 0 68 | #endif 69 | #define DD_SIZE LZO_SIZE(DD_BITS) 70 | #define DD_MASK LZO_MASK(DD_BITS) 71 | 72 | /* dictionary length */ 73 | #if !defined(DL_BITS) 74 | # define DL_BITS (D_BITS - DD_BITS) 75 | #endif 76 | #if (DL_BITS < 16) 77 | # define DL_SIZE LZO_SIZE(DL_BITS) 78 | # define DL_MASK LZO_MASK(DL_BITS) 79 | #else 80 | # define DL_SIZE LZO_USIZE(DL_BITS) 81 | # define DL_MASK LZO_UMASK(DL_BITS) 82 | #endif 83 | 84 | 85 | #if (D_BITS != DL_BITS + DD_BITS) 86 | # error "D_BITS does not match" 87 | #endif 88 | #if (D_BITS < 6 || D_BITS > 18) 89 | # error "invalid D_BITS" 90 | #endif 91 | #if (DL_BITS < 6 || DL_BITS > 20) 92 | # error "invalid DL_BITS" 93 | #endif 94 | #if (DD_BITS < 0 || DD_BITS > 6) 95 | # error "invalid DD_BITS" 96 | #endif 97 | 98 | 99 | #if !defined(DL_MIN_LEN) 100 | # define DL_MIN_LEN 3 101 | #endif 102 | #if !defined(DL_SHIFT) 103 | # define DL_SHIFT ((DL_BITS + (DL_MIN_LEN - 1)) / DL_MIN_LEN) 104 | #endif 105 | 106 | 107 | 108 | /*********************************************************************** 109 | // dictionary access 110 | ************************************************************************/ 111 | 112 | #define LZO_HASH_GZIP 1 113 | #define LZO_HASH_GZIP_INCREMENTAL 2 114 | #define LZO_HASH_LZO_INCREMENTAL_A 3 115 | #define LZO_HASH_LZO_INCREMENTAL_B 4 116 | 117 | #if !defined(LZO_HASH) 118 | # error "choose a hashing strategy" 119 | #endif 120 | 121 | #undef DM 122 | #undef DX 123 | 124 | #if (DL_MIN_LEN == 3) 125 | # define _DV2_A(p,shift1,shift2) \ 126 | (((( (lzo_xint)((p)[0]) << shift1) ^ (p)[1]) << shift2) ^ (p)[2]) 127 | # define _DV2_B(p,shift1,shift2) \ 128 | (((( (lzo_xint)((p)[2]) << shift1) ^ (p)[1]) << shift2) ^ (p)[0]) 129 | # define _DV3_B(p,shift1,shift2,shift3) \ 130 | ((_DV2_B((p)+1,shift1,shift2) << (shift3)) ^ (p)[0]) 131 | #elif (DL_MIN_LEN == 2) 132 | # define _DV2_A(p,shift1,shift2) \ 133 | (( (lzo_xint)(p[0]) << shift1) ^ p[1]) 134 | # define _DV2_B(p,shift1,shift2) \ 135 | (( (lzo_xint)(p[1]) << shift1) ^ p[2]) 136 | #else 137 | # error "invalid DL_MIN_LEN" 138 | #endif 139 | #define _DV_A(p,shift) _DV2_A(p,shift,shift) 140 | #define _DV_B(p,shift) _DV2_B(p,shift,shift) 141 | #define DA2(p,s1,s2) \ 142 | (((((lzo_xint)((p)[2]) << (s2)) + (p)[1]) << (s1)) + (p)[0]) 143 | #define DS2(p,s1,s2) \ 144 | (((((lzo_xint)((p)[2]) << (s2)) - (p)[1]) << (s1)) - (p)[0]) 145 | #define DX2(p,s1,s2) \ 146 | (((((lzo_xint)((p)[2]) << (s2)) ^ (p)[1]) << (s1)) ^ (p)[0]) 147 | #define DA3(p,s1,s2,s3) ((DA2((p)+1,s2,s3) << (s1)) + (p)[0]) 148 | #define DS3(p,s1,s2,s3) ((DS2((p)+1,s2,s3) << (s1)) - (p)[0]) 149 | #define DX3(p,s1,s2,s3) ((DX2((p)+1,s2,s3) << (s1)) ^ (p)[0]) 150 | #define DMS(v,s) ((lzo_uint) (((v) & (D_MASK >> (s))) << (s))) 151 | #define DM(v) DMS(v,0) 152 | 153 | 154 | #if (LZO_HASH == LZO_HASH_GZIP) 155 | /* hash function like in gzip/zlib (deflate) */ 156 | # define _DINDEX(dv,p) (_DV_A((p),DL_SHIFT)) 157 | 158 | #elif (LZO_HASH == LZO_HASH_GZIP_INCREMENTAL) 159 | /* incremental hash like in gzip/zlib (deflate) */ 160 | # define __LZO_HASH_INCREMENTAL 1 161 | # define DVAL_FIRST(dv,p) dv = _DV_A((p),DL_SHIFT) 162 | # define DVAL_NEXT(dv,p) dv = (((dv) << DL_SHIFT) ^ p[2]) 163 | # define _DINDEX(dv,p) (dv) 164 | # define DVAL_LOOKAHEAD DL_MIN_LEN 165 | 166 | #elif (LZO_HASH == LZO_HASH_LZO_INCREMENTAL_A) 167 | /* incremental LZO hash version A */ 168 | # define __LZO_HASH_INCREMENTAL 1 169 | # define DVAL_FIRST(dv,p) dv = _DV_A((p),5) 170 | # define DVAL_NEXT(dv,p) \ 171 | dv ^= (lzo_xint)(p[-1]) << (2*5); dv = (((dv) << 5) ^ p[2]) 172 | # define _DINDEX(dv,p) ((DMUL(0x9f5f,dv)) >> 5) 173 | # define DVAL_LOOKAHEAD DL_MIN_LEN 174 | 175 | #elif (LZO_HASH == LZO_HASH_LZO_INCREMENTAL_B) 176 | /* incremental LZO hash version B */ 177 | # define __LZO_HASH_INCREMENTAL 1 178 | # define DVAL_FIRST(dv,p) dv = _DV_B((p),5) 179 | # define DVAL_NEXT(dv,p) \ 180 | dv ^= p[-1]; dv = (((dv) >> 5) ^ ((lzo_xint)(p[2]) << (2*5))) 181 | # define _DINDEX(dv,p) ((DMUL(0x9f5f,dv)) >> 5) 182 | # define DVAL_LOOKAHEAD DL_MIN_LEN 183 | 184 | #else 185 | # error "choose a hashing strategy" 186 | #endif 187 | 188 | 189 | #ifndef DINDEX 190 | #define DINDEX(dv,p) ((lzo_uint)((_DINDEX(dv,p)) & DL_MASK) << DD_BITS) 191 | #endif 192 | #if !defined(DINDEX1) && defined(D_INDEX1) 193 | #define DINDEX1 D_INDEX1 194 | #endif 195 | #if !defined(DINDEX2) && defined(D_INDEX2) 196 | #define DINDEX2 D_INDEX2 197 | #endif 198 | 199 | 200 | 201 | #if !defined(__LZO_HASH_INCREMENTAL) 202 | # define DVAL_FIRST(dv,p) ((void) 0) 203 | # define DVAL_NEXT(dv,p) ((void) 0) 204 | # define DVAL_LOOKAHEAD 0 205 | #endif 206 | 207 | 208 | #if !defined(DVAL_ASSERT) 209 | #if defined(__LZO_HASH_INCREMENTAL) && !defined(NDEBUG) 210 | #if 1 && (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || (LZO_CC_GNUC >= 0x020700ul) || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) 211 | static void __attribute__((__unused__)) 212 | #else 213 | static void 214 | #endif 215 | DVAL_ASSERT(lzo_xint dv, const lzo_bytep p) 216 | { 217 | lzo_xint df; 218 | DVAL_FIRST(df,(p)); 219 | assert(DINDEX(dv,p) == DINDEX(df,p)); 220 | } 221 | #else 222 | # define DVAL_ASSERT(dv,p) ((void) 0) 223 | #endif 224 | #endif 225 | 226 | 227 | 228 | /*********************************************************************** 229 | // dictionary updating 230 | ************************************************************************/ 231 | 232 | #if (LZO_DICT_USE_PTR) 233 | # define DENTRY(p,in) (p) 234 | # define GINDEX(m_pos,m_off,dict,dindex,in) m_pos = dict[dindex] 235 | #else 236 | # define DENTRY(p,in) ((lzo_dict_t) pd(p, in)) 237 | # define GINDEX(m_pos,m_off,dict,dindex,in) m_off = dict[dindex] 238 | #endif 239 | 240 | 241 | #if (DD_BITS == 0) 242 | 243 | # define UPDATE_D(dict,drun,dv,p,in) dict[ DINDEX(dv,p) ] = DENTRY(p,in) 244 | # define UPDATE_I(dict,drun,index,p,in) dict[index] = DENTRY(p,in) 245 | # define UPDATE_P(ptr,drun,p,in) (ptr)[0] = DENTRY(p,in) 246 | 247 | #else 248 | 249 | # define UPDATE_D(dict,drun,dv,p,in) \ 250 | dict[ DINDEX(dv,p) + drun++ ] = DENTRY(p,in); drun &= DD_MASK 251 | # define UPDATE_I(dict,drun,index,p,in) \ 252 | dict[ (index) + drun++ ] = DENTRY(p,in); drun &= DD_MASK 253 | # define UPDATE_P(ptr,drun,p,in) \ 254 | (ptr) [ drun++ ] = DENTRY(p,in); drun &= DD_MASK 255 | 256 | #endif 257 | 258 | 259 | /*********************************************************************** 260 | // test for a match 261 | ************************************************************************/ 262 | 263 | #if (LZO_DICT_USE_PTR) 264 | 265 | /* m_pos is either NULL or a valid pointer */ 266 | #define LZO_CHECK_MPOS_DET(m_pos,m_off,in,ip,max_offset) \ 267 | (m_pos == NULL || (m_off = pd(ip, m_pos)) > max_offset) 268 | 269 | /* m_pos may point anywhere... */ 270 | #define LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,max_offset) \ 271 | (BOUNDS_CHECKING_OFF_IN_EXPR(( \ 272 | m_pos = ip - (lzo_uint) PTR_DIFF(ip,m_pos), \ 273 | PTR_LT(m_pos,in) || \ 274 | (m_off = (lzo_uint) PTR_DIFF(ip,m_pos)) == 0 || \ 275 | m_off > max_offset ))) 276 | 277 | #else 278 | 279 | #define LZO_CHECK_MPOS_DET(m_pos,m_off,in,ip,max_offset) \ 280 | (m_off == 0 || \ 281 | ((m_off = pd(ip, in) - m_off) > max_offset) || \ 282 | (m_pos = (ip) - (m_off), 0) ) 283 | 284 | #define LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,max_offset) \ 285 | (pd(ip, in) <= m_off || \ 286 | ((m_off = pd(ip, in) - m_off) > max_offset) || \ 287 | (m_pos = (ip) - (m_off), 0) ) 288 | 289 | #endif 290 | 291 | 292 | #if (LZO_DETERMINISTIC) 293 | # define LZO_CHECK_MPOS LZO_CHECK_MPOS_DET 294 | #else 295 | # define LZO_CHECK_MPOS LZO_CHECK_MPOS_NON_DET 296 | #endif 297 | 298 | 299 | 300 | #ifdef __cplusplus 301 | } /* extern "C" */ 302 | #endif 303 | 304 | #endif /* already included */ 305 | 306 | 307 | /* vim:set ts=4 sw=4 et: */ 308 | -------------------------------------------------------------------------------- /src/enc/lzo/lzo_mchw.ch: -------------------------------------------------------------------------------- 1 | /* lzo_mchw.ch -- matching functions using a window 2 | 3 | This file is part of the LZO real-time data compression library. 4 | 5 | Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer 6 | All Rights Reserved. 7 | 8 | The LZO library is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of 11 | the License, or (at your option) any later version. 12 | 13 | The LZO library is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with the LZO library; see the file COPYING. 20 | If not, write to the Free Software Foundation, Inc., 21 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 22 | 23 | Markus F.X.J. Oberhumer 24 | 25 | http://www.oberhumer.com/opensource/lzo/ 26 | */ 27 | 28 | 29 | /*********************************************************************** 30 | // 31 | ************************************************************************/ 32 | 33 | typedef struct 34 | { 35 | unsigned init; 36 | 37 | lzo_uint look; /* bytes in lookahead buffer */ 38 | 39 | lzo_uint m_len; 40 | lzo_uint m_off; 41 | 42 | lzo_uint last_m_len; 43 | lzo_uint last_m_off; 44 | 45 | const lzo_bytep bp; 46 | const lzo_bytep ip; 47 | const lzo_bytep in; 48 | const lzo_bytep in_end; 49 | lzo_bytep out; 50 | 51 | lzo_callback_p cb; 52 | 53 | lzo_uint textsize; /* text size counter */ 54 | lzo_uint codesize; /* code size counter */ 55 | lzo_uint printcount; /* counter for reporting progress every 1K bytes */ 56 | 57 | /* some stats */ 58 | lzo_uint lit_bytes; 59 | lzo_uint match_bytes; 60 | lzo_uint rep_bytes; 61 | lzo_uint lazy; 62 | 63 | #if defined(LZO1B) 64 | lzo_uint r1_m_len; 65 | 66 | /* some stats */ 67 | lzo_uint r1_r, m3_r, m2_m, m3_m; 68 | #endif 69 | 70 | #if defined(LZO1C) 71 | lzo_uint r1_m_len; 72 | lzo_bytep m3; 73 | 74 | /* some stats */ 75 | lzo_uint r1_r, m3_r, m2_m, m3_m; 76 | #endif 77 | 78 | #if defined(LZO1F) 79 | lzo_uint r1_lit; 80 | lzo_uint r1_m_len; 81 | 82 | /* some stats */ 83 | lzo_uint r1_r, m2_m, m3_m; 84 | #endif 85 | 86 | #if defined(LZO1X) || defined(LZO1Y) || defined(LZO1Z) 87 | lzo_uint r1_lit; 88 | lzo_uint r1_m_len; 89 | 90 | /* some stats */ 91 | lzo_uint m1a_m, m1b_m, m2_m, m3_m, m4_m; 92 | lzo_uint lit1_r, lit2_r, lit3_r; 93 | #endif 94 | 95 | #if defined(LZO2A) 96 | /* some stats */ 97 | lzo_uint m1, m2, m3, m4; 98 | #endif 99 | } 100 | LZO_COMPRESS_T; 101 | 102 | 103 | #define getbyte(c) ((c).ip < (c).in_end ? *((c).ip)++ : (-1)) 104 | 105 | #include "lzo_swd.ch" 106 | 107 | 108 | /*********************************************************************** 109 | // 110 | ************************************************************************/ 111 | 112 | static int 113 | init_match ( LZO_COMPRESS_T *c, lzo_swd_p s, 114 | const lzo_bytep dict, lzo_uint dict_len, 115 | lzo_uint32_t flags ) 116 | { 117 | int r; 118 | 119 | assert(!c->init); 120 | c->init = 1; 121 | 122 | s->c = c; 123 | 124 | c->last_m_len = c->last_m_off = 0; 125 | 126 | c->textsize = c->codesize = c->printcount = 0; 127 | c->lit_bytes = c->match_bytes = c->rep_bytes = 0; 128 | c->lazy = 0; 129 | 130 | r = swd_init(s,dict,dict_len); 131 | if (r != LZO_E_OK) 132 | { 133 | swd_exit(s); 134 | return r; 135 | } 136 | 137 | s->use_best_off = (flags & 1) ? 1 : 0; 138 | return LZO_E_OK; 139 | } 140 | 141 | 142 | /*********************************************************************** 143 | // 144 | ************************************************************************/ 145 | 146 | static int 147 | find_match ( LZO_COMPRESS_T *c, lzo_swd_p s, 148 | lzo_uint this_len, lzo_uint skip ) 149 | { 150 | assert(c->init); 151 | 152 | if (skip > 0) 153 | { 154 | assert(this_len >= skip); 155 | swd_accept(s, this_len - skip); 156 | c->textsize += this_len - skip + 1; 157 | } 158 | else 159 | { 160 | assert(this_len <= 1); 161 | c->textsize += this_len - skip; 162 | } 163 | 164 | s->m_len = SWD_THRESHOLD; 165 | s->m_off = 0; 166 | #ifdef SWD_BEST_OFF 167 | if (s->use_best_off) 168 | lzo_memset(s->best_pos,0,sizeof(s->best_pos)); 169 | #endif 170 | swd_findbest(s); 171 | c->m_len = s->m_len; 172 | c->m_off = s->m_off; 173 | 174 | swd_getbyte(s); 175 | 176 | if (s->b_char < 0) 177 | { 178 | c->look = 0; 179 | c->m_len = 0; 180 | swd_exit(s); 181 | } 182 | else 183 | { 184 | c->look = s->look + 1; 185 | } 186 | c->bp = c->ip - c->look; 187 | 188 | #if 0 189 | /* brute force match search */ 190 | if (c->m_len > SWD_THRESHOLD && c->m_len + 1 <= c->look) 191 | { 192 | const lzo_bytep ip = c->bp; 193 | const lzo_bytep m = c->bp - c->m_off; 194 | const lzo_bytep in = c->in; 195 | 196 | if (ip - in > s->swd_n) 197 | in = ip - s->swd_n; 198 | for (;;) 199 | { 200 | while (*in != *ip) 201 | in++; 202 | if (in == ip) 203 | break; 204 | if (in != m) 205 | if (lzo_memcmp(in,ip,c->m_len+1) == 0) 206 | printf("%p %p %p %5d\n",in,ip,m,c->m_len); 207 | in++; 208 | } 209 | } 210 | #endif 211 | 212 | if (c->cb && c->cb->nprogress && c->textsize > c->printcount) 213 | { 214 | (*c->cb->nprogress)(c->cb, c->textsize, c->codesize, 0); 215 | c->printcount += 1024; 216 | } 217 | 218 | return LZO_E_OK; 219 | } 220 | 221 | 222 | /* vim:set ts=4 sw=4 et: */ 223 | -------------------------------------------------------------------------------- /src/enc/lzo/lzo_ptr.c: -------------------------------------------------------------------------------- 1 | /* lzo_ptr.c -- low-level pointer constructs 2 | 3 | This file is part of the LZO real-time data compression library. 4 | 5 | Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer 6 | All Rights Reserved. 7 | 8 | The LZO library is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of 11 | the License, or (at your option) any later version. 12 | 13 | The LZO library is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with the LZO library; see the file COPYING. 20 | If not, write to the Free Software Foundation, Inc., 21 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 22 | 23 | Markus F.X.J. Oberhumer 24 | 25 | http://www.oberhumer.com/opensource/lzo/ 26 | */ 27 | 28 | 29 | #include "lzo_conf.h" 30 | 31 | 32 | /*********************************************************************** 33 | // 34 | ************************************************************************/ 35 | 36 | LZO_PUBLIC(lzo_uintptr_t) 37 | __lzo_ptr_linear(const lzo_voidp ptr) 38 | { 39 | lzo_uintptr_t p; 40 | 41 | #if (LZO_ARCH_I086) 42 | #error "LZO_ARCH_I086 is unsupported" 43 | #elif (LZO_MM_PVP) 44 | #error "LZO_MM_PVP is unsupported" 45 | #else 46 | p = (lzo_uintptr_t) PTR_LINEAR(ptr); 47 | #endif 48 | 49 | return p; 50 | } 51 | 52 | 53 | /*********************************************************************** 54 | // 55 | ************************************************************************/ 56 | 57 | LZO_PUBLIC(unsigned) 58 | __lzo_align_gap(const lzo_voidp ptr, lzo_uint size) 59 | { 60 | #if (__LZO_UINTPTR_T_IS_POINTER) 61 | #error "__LZO_UINTPTR_T_IS_POINTER is unsupported" 62 | #else 63 | lzo_uintptr_t p, n; 64 | if (size < 2) return 0; 65 | p = __lzo_ptr_linear(ptr); 66 | #if 0 67 | n = (((p + size - 1) / size) * size) - p; 68 | #else 69 | if ((size & (size - 1)) != 0) 70 | return 0; 71 | n = size; n = ((p + n - 1) & ~(n - 1)) - p; 72 | #endif 73 | #endif 74 | assert((long)n >= 0); 75 | assert(n <= size); 76 | return (unsigned)n; 77 | } 78 | 79 | 80 | /* vim:set ts=4 sw=4 et: */ 81 | -------------------------------------------------------------------------------- /src/enc/lzo/lzo_ptr.h: -------------------------------------------------------------------------------- 1 | /* lzo_ptr.h -- low-level pointer constructs 2 | 3 | This file is part of the LZO real-time data compression library. 4 | 5 | Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer 6 | All Rights Reserved. 7 | 8 | The LZO library is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of 11 | the License, or (at your option) any later version. 12 | 13 | The LZO library is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with the LZO library; see the file COPYING. 20 | If not, write to the Free Software Foundation, Inc., 21 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 22 | 23 | Markus F.X.J. Oberhumer 24 | 25 | http://www.oberhumer.com/opensource/lzo/ 26 | */ 27 | 28 | 29 | /* WARNING: this file should *not* be used by applications. It is 30 | part of the implementation of the library and is subject 31 | to change. 32 | */ 33 | 34 | 35 | #ifndef __LZO_PTR_H 36 | #define __LZO_PTR_H 1 37 | 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | 42 | 43 | /*********************************************************************** 44 | // 45 | ************************************************************************/ 46 | 47 | /* Always use the safe (=integral) version for pointer-comparisons. 48 | * The compiler should optimize away the additional casts anyway. 49 | * 50 | * Note that this only works if the representation and ordering 51 | * of the pointer and the integral is the same (at bit level). 52 | */ 53 | 54 | #if (LZO_ARCH_I086) 55 | #error "LZO_ARCH_I086 is unsupported" 56 | #elif (LZO_MM_PVP) 57 | #error "LZO_MM_PVP is unsupported" 58 | #else 59 | #define PTR(a) ((lzo_uintptr_t) (a)) 60 | #define PTR_LINEAR(a) PTR(a) 61 | #define PTR_ALIGNED_4(a) ((PTR_LINEAR(a) & 3) == 0) 62 | #define PTR_ALIGNED_8(a) ((PTR_LINEAR(a) & 7) == 0) 63 | #define PTR_ALIGNED2_4(a,b) (((PTR_LINEAR(a) | PTR_LINEAR(b)) & 3) == 0) 64 | #define PTR_ALIGNED2_8(a,b) (((PTR_LINEAR(a) | PTR_LINEAR(b)) & 7) == 0) 65 | #endif 66 | 67 | #define PTR_LT(a,b) (PTR(a) < PTR(b)) 68 | #define PTR_GE(a,b) (PTR(a) >= PTR(b)) 69 | #define PTR_DIFF(a,b) (PTR(a) - PTR(b)) 70 | #define pd(a,b) ((lzo_uint) ((a)-(b))) 71 | 72 | 73 | LZO_EXTERN(lzo_uintptr_t) 74 | __lzo_ptr_linear(const lzo_voidp ptr); 75 | 76 | 77 | typedef union 78 | { 79 | char a_char; 80 | unsigned char a_uchar; 81 | short a_short; 82 | unsigned short a_ushort; 83 | int a_int; 84 | unsigned int a_uint; 85 | long a_long; 86 | unsigned long a_ulong; 87 | lzo_int a_lzo_int; 88 | lzo_uint a_lzo_uint; 89 | lzo_xint a_lzo_xint; 90 | lzo_int16_t a_lzo_int16_t; 91 | lzo_uint16_t a_lzo_uint16_t; 92 | lzo_int32_t a_lzo_int32_t; 93 | lzo_uint32_t a_lzo_uint32_t; 94 | #if defined(lzo_uint64_t) 95 | lzo_int64_t a_lzo_int64_t; 96 | lzo_uint64_t a_lzo_uint64_t; 97 | #endif 98 | size_t a_size_t; 99 | ptrdiff_t a_ptrdiff_t; 100 | lzo_uintptr_t a_lzo_uintptr_t; 101 | void * a_void_p; 102 | char * a_char_p; 103 | unsigned char * a_uchar_p; 104 | const void * a_c_void_p; 105 | const char * a_c_char_p; 106 | const unsigned char * a_c_uchar_p; 107 | lzo_voidp a_lzo_voidp; 108 | lzo_bytep a_lzo_bytep; 109 | const lzo_voidp a_c_lzo_voidp; 110 | const lzo_bytep a_c_lzo_bytep; 111 | } 112 | lzo_full_align_t; 113 | 114 | 115 | 116 | #ifdef __cplusplus 117 | } /* extern "C" */ 118 | #endif 119 | 120 | #endif /* already included */ 121 | 122 | 123 | /* vim:set ts=4 sw=4 et: */ 124 | -------------------------------------------------------------------------------- /src/enc/stretchy_buffer.h: -------------------------------------------------------------------------------- 1 | // stretchy_buffer.h - v1.03 - public domain - nothings.org/stb 2 | // a vector<>-like dynamic array for C 3 | // 4 | // version history: 5 | // 1.03 - compile as C++ maybe 6 | // 1.02 - tweaks to syntax for no good reason 7 | // 1.01 - added a "common uses" documentation section 8 | // 1.0 - fixed bug in the version I posted prematurely 9 | // 0.9 - rewrite to try to avoid strict-aliasing optimization 10 | // issues, but won't compile as C++ 11 | // 12 | // Will probably not work correctly with strict-aliasing optimizations. 13 | // 14 | // The idea: 15 | // 16 | // This implements an approximation to C++ vector<> for C, in that it 17 | // provides a generic definition for dynamic arrays which you can 18 | // still access in a typesafe way using arr[i] or *(arr+i). However, 19 | // it is simply a convenience wrapper around the common idiom of 20 | // of keeping a set of variables (in a struct or globals) which store 21 | // - pointer to array 22 | // - the length of the "in-use" part of the array 23 | // - the current size of the allocated array 24 | // 25 | // I find it to be the single most useful non-built-in-structure when 26 | // programming in C (hash tables a close second), but to be clear 27 | // it lacks many of the capabilities of C++ vector<>: there is no 28 | // range checking, the object address isn't stable (see next section 29 | // for details), the set of methods available is small (although 30 | // the file stb.h has another implementation of stretchy buffers 31 | // called 'stb_arr' which provides more methods, e.g. for insertion 32 | // and deletion). 33 | // 34 | // How to use: 35 | // 36 | // Unlike other stb header file libraries, there is no need to 37 | // define an _IMPLEMENTATION symbol. Every #include creates as 38 | // much implementation is needed. 39 | // 40 | // stretchy_buffer.h does not define any types, so you do not 41 | // need to #include it to before defining data types that are 42 | // stretchy buffers, only in files that *manipulate* stretchy 43 | // buffers. 44 | // 45 | // If you want a stretchy buffer aka dynamic array containing 46 | // objects of TYPE, declare such an array as: 47 | // 48 | // TYPE *myarray = NULL; 49 | // 50 | // (There is no typesafe way to distinguish between stretchy 51 | // buffers and regular arrays/pointers; this is necessary to 52 | // make ordinary array indexing work on these objects.) 53 | // 54 | // Unlike C++ vector<>, the stretchy_buffer has the same 55 | // semantics as an object that you manually malloc and realloc. 56 | // The pointer may relocate every time you add a new object 57 | // to it, so you: 58 | // 59 | // 1. can't take long-term pointers to elements of the array 60 | // 2. have to return the pointer from functions which might expand it 61 | // (either as a return value or by storing it to a ptr-to-ptr) 62 | // 63 | // Now you can do the following things with this array: 64 | // 65 | // sb_free(TYPE *a) free the array 66 | // sb_count(TYPE *a) the number of elements in the array 67 | // sb_push(TYPE *a, TYPE v) adds v on the end of the array, a la push_back 68 | // sb_add(TYPE *a, int n) adds n uninitialized elements at end of array & returns pointer to first added 69 | // sb_last(TYPE *a) returns an lvalue of the last item in the array 70 | // a[n] access the nth (counting from 0) element of the array 71 | // 72 | // #define STRETCHY_BUFFER_NO_SHORT_NAMES to only export 73 | // names of the form 'stb_sb_' if you have a name that would 74 | // otherwise collide. 75 | // 76 | // Note that these are all macros and many of them evaluate 77 | // their arguments more than once, so the arguments should 78 | // be side-effect-free. 79 | // 80 | // Note that 'TYPE *a' in sb_push and sb_add must be lvalues 81 | // so that the library can overwrite the existing pointer if 82 | // the object has to be reallocated. 83 | // 84 | // In an out-of-memory condition, the code will try to 85 | // set up a null-pointer or otherwise-invalid-pointer 86 | // exception to happen later. It's possible optimizing 87 | // compilers could detect this write-to-null statically 88 | // and optimize away some of the code, but it should only 89 | // be along the failure path. Nevertheless, for more security 90 | // in the face of such compilers, #define STRETCHY_BUFFER_OUT_OF_MEMORY 91 | // to a statement such as assert(0) or exit(1) or something 92 | // to force a failure when out-of-memory occurs. 93 | // 94 | // Common use: 95 | // 96 | // The main application for this is when building a list of 97 | // things with an unknown quantity, either due to loading from 98 | // a file or through a process which produces an unpredictable 99 | // number. 100 | // 101 | // My most common idiom is something like: 102 | // 103 | // SomeStruct *arr = NULL; 104 | // while (something) 105 | // { 106 | // SomeStruct new_one; 107 | // new_one.whatever = whatever; 108 | // new_one.whatup = whatup; 109 | // new_one.foobar = barfoo; 110 | // sb_push(arr, new_one); 111 | // } 112 | // 113 | // and various closely-related factorings of that. For example, 114 | // you might have several functions to create/init new SomeStructs, 115 | // and if you use the above idiom, you might prefer to make them 116 | // return structs rather than take non-const-pointers-to-structs, 117 | // so you can do things like: 118 | // 119 | // SomeStruct *arr = NULL; 120 | // while (something) 121 | // { 122 | // if (case_A) { 123 | // sb_push(arr, some_func1()); 124 | // } else if (case_B) { 125 | // sb_push(arr, some_func2()); 126 | // } else { 127 | // sb_push(arr, some_func3()); 128 | // } 129 | // } 130 | // 131 | // Note that the above relies on the fact that sb_push doesn't 132 | // evaluate its second argument more than once. The macros do 133 | // evaluate the *array* argument multiple times, and numeric 134 | // arguments may be evaluated multiple times, but you can rely 135 | // on the second argument of sb_push being evaluated only once. 136 | // 137 | // Of course, you don't have to store bare objects in the array; 138 | // if you need the objects to have stable pointers, store an array 139 | // of pointers instead: 140 | // 141 | // SomeStruct **arr = NULL; 142 | // while (something) 143 | // { 144 | // SomeStruct *new_one = malloc(sizeof(*new_one)); 145 | // new_one->whatever = whatever; 146 | // new_one->whatup = whatup; 147 | // new_one->foobar = barfoo; 148 | // sb_push(arr, new_one); 149 | // } 150 | // 151 | // How it works: 152 | // 153 | // A long-standing tradition in things like malloc implementations 154 | // is to store extra data before the beginning of the block returned 155 | // to the user. The stretchy buffer implementation here uses the 156 | // same trick; the current-count and current-allocation-size are 157 | // stored before the beginning of the array returned to the user. 158 | // (This means you can't directly free() the pointer, because the 159 | // allocated pointer is different from the type-safe pointer provided 160 | // to the user.) 161 | // 162 | // The details are trivial and implementation is straightforward; 163 | // the main trick is in realizing in the first place that it's 164 | // possible to do this in a generic, type-safe way in C. 165 | // 166 | // Contributors: 167 | // 168 | // Timothy Wright (github:ZenToad) 169 | // 170 | // LICENSE 171 | // 172 | // See end of file for license information. 173 | 174 | #ifndef STB_STRETCHY_BUFFER_H_INCLUDED 175 | #define STB_STRETCHY_BUFFER_H_INCLUDED 176 | 177 | #ifndef NO_STRETCHY_BUFFER_SHORT_NAMES 178 | #define sb_free stb_sb_free 179 | #define sb_push stb_sb_push 180 | #define sb_count stb_sb_count 181 | #define sb_add stb_sb_add 182 | #define sb_last stb_sb_last 183 | #endif 184 | 185 | #define stb_sb_free(a) ((a) ? free(stb__sbraw(a)),0 : 0) 186 | #define stb_sb_push(a,v) (stb__sbmaybegrow(a,1), (a)[stb__sbn(a)++] = (v)) 187 | #define stb_sb_count(a) ((a) ? stb__sbn(a) : 0) 188 | #define stb_sb_add(a,n) (stb__sbmaybegrow(a,n), stb__sbn(a)+=(n), &(a)[stb__sbn(a)-(n)]) 189 | #define stb_sb_last(a) ((a)[stb__sbn(a)-1]) 190 | 191 | #define stb__sbraw(a) ((int *) (a) - 2) 192 | #define stb__sbm(a) stb__sbraw(a)[0] 193 | #define stb__sbn(a) stb__sbraw(a)[1] 194 | 195 | #define stb__sbneedgrow(a,n) ((a)==0 || stb__sbn(a)+(n) >= stb__sbm(a)) 196 | #define stb__sbmaybegrow(a,n) (stb__sbneedgrow(a,(n)) ? stb__sbgrow(a,n) : 0) 197 | #define stb__sbgrow(a,n) (*((void **)&(a)) = stb__sbgrowf((a), (n), sizeof(*(a)))) 198 | 199 | #include 200 | 201 | static void * stb__sbgrowf(void *arr, int increment, int itemsize) 202 | { 203 | int dbl_cur = arr ? 2*stb__sbm(arr) : 0; 204 | int min_needed = stb_sb_count(arr) + increment; 205 | int m = dbl_cur > min_needed ? dbl_cur : min_needed; 206 | int *p = (int *) realloc(arr ? stb__sbraw(arr) : 0, itemsize * m + sizeof(int)*2); 207 | if (p) { 208 | if (!arr) 209 | p[1] = 0; 210 | p[0] = m; 211 | return p+2; 212 | } else { 213 | #ifdef STRETCHY_BUFFER_OUT_OF_MEMORY 214 | STRETCHY_BUFFER_OUT_OF_MEMORY ; 215 | #endif 216 | return (void *) (2*sizeof(int)); // try to force a NULL pointer exception later 217 | } 218 | } 219 | #endif // STB_STRETCHY_BUFFER_H_INCLUDED 220 | 221 | 222 | /* 223 | ------------------------------------------------------------------------------ 224 | This software is available under 2 licenses -- choose whichever you prefer. 225 | ------------------------------------------------------------------------------ 226 | ALTERNATIVE A - MIT License 227 | Copyright (c) 2017 Sean Barrett 228 | Permission is hereby granted, free of charge, to any person obtaining a copy of 229 | this software and associated documentation files (the "Software"), to deal in 230 | the Software without restriction, including without limitation the rights to 231 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 232 | of the Software, and to permit persons to whom the Software is furnished to do 233 | so, subject to the following conditions: 234 | The above copyright notice and this permission notice shall be included in all 235 | copies or substantial portions of the Software. 236 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 237 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 238 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 239 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 240 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 241 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 242 | SOFTWARE. 243 | ------------------------------------------------------------------------------ 244 | ALTERNATIVE B - Public Domain (www.unlicense.org) 245 | This is free and unencumbered software released into the public domain. 246 | Anyone is free to copy, modify, publish, use, compile, sell, or distribute this 247 | software, either in source code form or as a compiled binary, for any purpose, 248 | commercial or non-commercial, and by any means. 249 | In jurisdictions that recognize copyright laws, the author or authors of this 250 | software dedicate any and all copyright interest in the software to the public 251 | domain. We make this dedication for the benefit of the public at large and to 252 | the detriment of our heirs and successors. We intend this dedication to be an 253 | overt act of relinquishment in perpetuity of all present and future rights to 254 | this software under copyright law. 255 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 256 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 257 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 258 | AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 259 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 260 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 261 | ------------------------------------------------------------------------------ 262 | */ 263 | -------------------------------------------------------------------------------- /src/enc/ucl.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "ucl/ucl.h" 5 | 6 | int 7 | uclenc( 8 | void *_src 9 | , unsigned src_sz 10 | , void *_dst 11 | , unsigned *dst_sz 12 | , void *_ctx 13 | ) 14 | { 15 | unsigned char *src = _src; 16 | unsigned char *dst = _dst; 17 | int r; 18 | int level = 10; 19 | ucl_uint result_sz; 20 | 21 | extern int g_hlen; /* header length */ 22 | memset(dst, 0, g_hlen); 23 | memcpy(dst, "UCL0", 4); 24 | dst[4] = (src_sz >> 24); 25 | dst[5] = (src_sz >> 16); 26 | dst[6] = (src_sz >> 8); 27 | dst[7] = (src_sz >> 0); 28 | 29 | r = ucl_nrv2b_99_compress( 30 | src /* in */ 31 | , src_sz /* in size */ 32 | , dst + g_hlen /* out */ 33 | , &result_sz /* out size */ 34 | , NULL /* callback */ 35 | , level /* level */ 36 | , NULL /* conf */ 37 | , NULL /* result */ 38 | ); 39 | 40 | if (r != UCL_E_OK) 41 | { 42 | fprintf(stderr, "[!] fatal compression error %d\n", r); 43 | exit(EXIT_FAILURE); 44 | } 45 | 46 | *dst_sz = result_sz + g_hlen; 47 | 48 | return 0; 49 | } 50 | 51 | -------------------------------------------------------------------------------- /src/enc/ucl/comp/n2b_99.c: -------------------------------------------------------------------------------- 1 | /* n2b_99.c -- implementation of the NRV2B-99 compression algorithm 2 | 3 | This file is part of the UCL data compression library. 4 | 5 | Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer 6 | All Rights Reserved. 7 | 8 | The UCL library is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of 11 | the License, or (at your option) any later version. 12 | 13 | The UCL library is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with the UCL library; see the file COPYING. 20 | If not, write to the Free Software Foundation, Inc., 21 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 22 | 23 | Markus F.X.J. Oberhumer 24 | 25 | http://www.oberhumer.com/opensource/ucl/ 26 | */ 27 | 28 | 29 | 30 | #define NRV2B 31 | #include "n2_99.ch" 32 | #undef NRV2B 33 | 34 | 35 | /* 36 | vi:ts=4:et 37 | */ 38 | 39 | -------------------------------------------------------------------------------- /src/enc/ucl/comp/ucl_mchw.ch: -------------------------------------------------------------------------------- 1 | /* ucl_mchw.ch -- matching functions using a window 2 | 3 | This file is part of the UCL data compression library. 4 | 5 | Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer 6 | All Rights Reserved. 7 | 8 | The UCL library is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of 11 | the License, or (at your option) any later version. 12 | 13 | The UCL library is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with the UCL library; see the file COPYING. 20 | If not, write to the Free Software Foundation, Inc., 21 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 22 | 23 | Markus F.X.J. Oberhumer 24 | 25 | http://www.oberhumer.com/opensource/ucl/ 26 | */ 27 | 28 | 29 | /*********************************************************************** 30 | // 31 | ************************************************************************/ 32 | 33 | typedef struct 34 | { 35 | int init; 36 | 37 | ucl_uint look; /* bytes in lookahead buffer */ 38 | 39 | ucl_uint m_len; 40 | ucl_uint m_off; 41 | 42 | ucl_uint last_m_len; 43 | ucl_uint last_m_off; 44 | 45 | const ucl_bytep bp; 46 | const ucl_bytep ip; 47 | const ucl_bytep in; 48 | const ucl_bytep in_end; 49 | ucl_bytep out; 50 | 51 | ucl_uint32 bb_b; 52 | unsigned bb_k; 53 | unsigned bb_c_endian; 54 | unsigned bb_c_s; 55 | unsigned bb_c_s8; 56 | ucl_bytep bb_p; 57 | ucl_bytep bb_op; 58 | 59 | struct ucl_compress_config_t conf; 60 | ucl_uintp result; 61 | 62 | ucl_progress_callback_p cb; 63 | 64 | ucl_uint textsize; /* text size counter */ 65 | ucl_uint codesize; /* code size counter */ 66 | ucl_uint printcount; /* counter for reporting progress every 1K bytes */ 67 | 68 | /* some stats */ 69 | unsigned long lit_bytes; 70 | unsigned long match_bytes; 71 | unsigned long rep_bytes; 72 | unsigned long lazy; 73 | } 74 | UCL_COMPRESS_T; 75 | 76 | 77 | 78 | #if (ACC_OS_TOS && (ACC_CC_PUREC || ACC_CC_TURBOC)) 79 | /* the cast is needed to work around a code generation bug */ 80 | #define getbyte(c) ((c).ip < (c).in_end ? (int) (unsigned) *((c).ip)++ : (-1)) 81 | #else 82 | #define getbyte(c) ((c).ip < (c).in_end ? *((c).ip)++ : (-1)) 83 | #endif 84 | 85 | #include "ucl_swd.ch" 86 | 87 | 88 | 89 | /*********************************************************************** 90 | // 91 | ************************************************************************/ 92 | 93 | static int 94 | init_match ( UCL_COMPRESS_T *c, ucl_swd_t *s, 95 | const ucl_bytep dict, ucl_uint dict_len, 96 | ucl_uint32 flags ) 97 | { 98 | int r; 99 | 100 | assert(!c->init); 101 | c->init = 1; 102 | 103 | s->c = c; 104 | 105 | c->last_m_len = c->last_m_off = 0; 106 | 107 | c->textsize = c->codesize = c->printcount = 0; 108 | c->lit_bytes = c->match_bytes = c->rep_bytes = 0; 109 | c->lazy = 0; 110 | 111 | r = swd_init(s,dict,dict_len); 112 | if (r != UCL_E_OK) 113 | { 114 | swd_exit(s); 115 | return r; 116 | } 117 | 118 | s->use_best_off = (flags & 1) ? 1 : 0; 119 | return UCL_E_OK; 120 | } 121 | 122 | 123 | /*********************************************************************** 124 | // 125 | ************************************************************************/ 126 | 127 | static int 128 | find_match ( UCL_COMPRESS_T *c, ucl_swd_t *s, 129 | ucl_uint this_len, ucl_uint skip ) 130 | { 131 | assert(c->init); 132 | 133 | if (skip > 0) 134 | { 135 | assert(this_len >= skip); 136 | swd_accept(s, this_len - skip); 137 | c->textsize += this_len - skip + 1; 138 | } 139 | else 140 | { 141 | assert(this_len <= 1); 142 | c->textsize += this_len - skip; 143 | } 144 | 145 | s->m_len = SWD_THRESHOLD; 146 | #ifdef SWD_BEST_OFF 147 | if (s->use_best_off) 148 | memset(s->best_pos,0,sizeof(s->best_pos)); 149 | #endif 150 | swd_findbest(s); 151 | c->m_len = s->m_len; 152 | #if defined(__UCL_CHECKER) 153 | /* s->m_off may be uninitialized if we didn't find a match, 154 | * but then its value will never be used. 155 | */ 156 | c->m_off = (s->m_len == SWD_THRESHOLD) ? 0 : s->m_off; 157 | #else 158 | c->m_off = s->m_off; 159 | #endif 160 | 161 | swd_getbyte(s); 162 | 163 | if (s->b_char < 0) 164 | { 165 | c->look = 0; 166 | c->m_len = 0; 167 | swd_exit(s); 168 | } 169 | else 170 | { 171 | c->look = s->look + 1; 172 | } 173 | c->bp = c->ip - c->look; 174 | 175 | #if 0 176 | /* brute force match search */ 177 | if (c->m_len > SWD_THRESHOLD && c->m_len + 1 <= c->look) 178 | { 179 | const ucl_bytep ip = c->bp; 180 | const ucl_bytep m = c->bp - c->m_off; 181 | const ucl_bytep in = c->in; 182 | 183 | if (ip - in > s->n) 184 | in = ip - s->n; 185 | for (;;) 186 | { 187 | while (*in != *ip) 188 | in++; 189 | if (in == ip) 190 | break; 191 | if (in != m) 192 | if (memcmp(in,ip,c->m_len+1) == 0) 193 | printf("%p %p %p %5d\n",in,ip,m,c->m_len); 194 | in++; 195 | } 196 | } 197 | #endif 198 | 199 | if (c->cb && c->textsize > c->printcount) 200 | { 201 | (*c->cb->callback)(c->textsize,c->codesize,3,c->cb->user); 202 | c->printcount += 1024; 203 | } 204 | 205 | return UCL_E_OK; 206 | } 207 | 208 | 209 | /*********************************************************************** 210 | // bit buffer 211 | ************************************************************************/ 212 | 213 | static int bbConfig(UCL_COMPRESS_T *c, int endian, int bitsize) 214 | { 215 | if (endian != -1) 216 | { 217 | if (endian != 0) 218 | return UCL_E_ERROR; 219 | c->bb_c_endian = endian; 220 | } 221 | if (bitsize != -1) 222 | { 223 | if (bitsize != 8 && bitsize != 16 && bitsize != 32) 224 | return UCL_E_ERROR; 225 | c->bb_c_s = bitsize; 226 | c->bb_c_s8 = bitsize / 8; 227 | } 228 | c->bb_b = 0; c->bb_k = 0; 229 | c->bb_p = NULL; 230 | c->bb_op = NULL; 231 | return UCL_E_OK; 232 | } 233 | 234 | 235 | static void bbWriteBits(UCL_COMPRESS_T *c) 236 | { 237 | ucl_bytep p = c->bb_p; 238 | ucl_uint32 b = c->bb_b; 239 | 240 | p[0] = UCL_BYTE(b >> 0); 241 | if (c->bb_c_s >= 16) 242 | { 243 | p[1] = UCL_BYTE(b >> 8); 244 | if (c->bb_c_s == 32) 245 | { 246 | p[2] = UCL_BYTE(b >> 16); 247 | p[3] = UCL_BYTE(b >> 24); 248 | } 249 | } 250 | } 251 | 252 | 253 | static void bbPutBit(UCL_COMPRESS_T *c, unsigned bit) 254 | { 255 | assert(bit == 0 || bit == 1); 256 | assert(c->bb_k <= c->bb_c_s); 257 | 258 | if (c->bb_k < c->bb_c_s) 259 | { 260 | if (c->bb_k == 0) 261 | { 262 | assert(c->bb_p == NULL); 263 | c->bb_p = c->bb_op; 264 | c->bb_op += c->bb_c_s8; 265 | } 266 | assert(c->bb_p != NULL); 267 | assert(c->bb_p + c->bb_c_s8 <= c->bb_op); 268 | 269 | c->bb_b = (c->bb_b << 1) + bit; 270 | c->bb_k++; 271 | } 272 | else 273 | { 274 | assert(c->bb_p != NULL); 275 | assert(c->bb_p + c->bb_c_s8 <= c->bb_op); 276 | 277 | bbWriteBits(c); 278 | c->bb_p = c->bb_op; 279 | c->bb_op += c->bb_c_s8; 280 | c->bb_b = bit; 281 | c->bb_k = 1; 282 | } 283 | } 284 | 285 | 286 | static void bbPutByte(UCL_COMPRESS_T *c, unsigned b) 287 | { 288 | /**printf("putbyte %p %p %x (%d)\n", op, bb_p, x, bb_k);*/ 289 | assert(c->bb_p == NULL || c->bb_p + c->bb_c_s8 <= c->bb_op); 290 | *c->bb_op++ = UCL_BYTE(b); 291 | } 292 | 293 | 294 | static void bbFlushBits(UCL_COMPRESS_T *c, unsigned filler_bit) 295 | { 296 | if (c->bb_k > 0) 297 | { 298 | assert(c->bb_k <= c->bb_c_s); 299 | while (c->bb_k != c->bb_c_s) 300 | bbPutBit(c, filler_bit); 301 | bbWriteBits(c); 302 | c->bb_k = 0; 303 | } 304 | c->bb_p = NULL; 305 | } 306 | 307 | 308 | 309 | /* 310 | vi:ts=4:et 311 | */ 312 | 313 | -------------------------------------------------------------------------------- /src/enc/ucl/getbit.h: -------------------------------------------------------------------------------- 1 | /* getbit.h -- bit-buffer access 2 | 3 | This file is part of the UCL data compression library. 4 | 5 | Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer 6 | All Rights Reserved. 7 | 8 | The UCL library is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of 11 | the License, or (at your option) any later version. 12 | 13 | The UCL library is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with the UCL library; see the file COPYING. 20 | If not, write to the Free Software Foundation, Inc., 21 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 22 | 23 | Markus F.X.J. Oberhumer 24 | 25 | http://www.oberhumer.com/opensource/ucl/ 26 | */ 27 | 28 | 29 | /*********************************************************************** 30 | // 31 | ************************************************************************/ 32 | 33 | #if 1 34 | #define getbit_8(bb, src, ilen) \ 35 | (((bb = bb & 0x7f ? bb*2 : ((unsigned)src[ilen++]*2+1)) >> 8) & 1) 36 | #elif 1 37 | #define getbit_8(bb, src, ilen) \ 38 | (bb*=2,bb&0xff ? (bb>>8)&1 : ((bb=src[ilen++]*2+1)>>8)&1) 39 | #else 40 | #define getbit_8(bb, src, ilen) \ 41 | (((bb*=2, (bb&0xff ? bb : (bb=src[ilen++]*2+1,bb))) >> 8) & 1) 42 | #endif 43 | 44 | 45 | #define getbit_le16(bb, src, ilen) \ 46 | (bb*=2,bb&0xffff ? (bb>>16)&1 : (ilen+=2,((bb=(src[ilen-2]+src[ilen-1]*256u)*2+1)>>16)&1)) 47 | 48 | 49 | #if 1 && (ACC_ENDIAN_LITTLE_ENDIAN) && defined(UA_GET4) 50 | #define getbit_le32(bb, bc, src, ilen) \ 51 | (bc > 0 ? ((bb>>--bc)&1) : (bc=31,\ 52 | bb=UA_GET4((src)+ilen),ilen+=4,(bb>>31)&1)) 53 | #else 54 | #define getbit_le32(bb, bc, src, ilen) \ 55 | (bc > 0 ? ((bb>>--bc)&1) : (bc=31,\ 56 | bb=src[ilen]+src[ilen+1]*0x100+src[ilen+2]*UCL_UINT32_C(0x10000)+src[ilen+3]*UCL_UINT32_C(0x1000000),\ 57 | ilen+=4,(bb>>31)&1)) 58 | #endif 59 | 60 | 61 | /* 62 | vi:ts=4:et 63 | */ 64 | 65 | -------------------------------------------------------------------------------- /src/enc/ucl/n2b_d.c: -------------------------------------------------------------------------------- 1 | /* n2b_d.c -- implementation of the NRV2B decompression algorithm 2 | 3 | This file is part of the UCL data compression library. 4 | 5 | Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer 6 | All Rights Reserved. 7 | 8 | The UCL library is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of 11 | the License, or (at your option) any later version. 12 | 13 | The UCL library is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with the UCL library; see the file COPYING. 20 | If not, write to the Free Software Foundation, Inc., 21 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 22 | 23 | Markus F.X.J. Oberhumer 24 | 25 | http://www.oberhumer.com/opensource/ucl/ 26 | */ 27 | 28 | 29 | /*********************************************************************** 30 | // actual implementation used by a recursive #include 31 | ************************************************************************/ 32 | 33 | #ifdef getbit 34 | 35 | #ifdef SAFE 36 | #define fail(x,r) if (x) { *dst_len = olen; return r; } 37 | #else 38 | #define fail(x,r) 39 | #endif 40 | 41 | { 42 | ucl_uint32 bb = 0; 43 | #ifdef TEST_OVERLAP 44 | ucl_uint ilen = src_off, olen = 0, last_m_off = 1; 45 | #else 46 | ucl_uint ilen = 0, olen = 0, last_m_off = 1; 47 | #endif 48 | #ifdef SAFE 49 | const ucl_uint oend = *dst_len; 50 | #endif 51 | //ACC_UNUSED(wrkmem); 52 | 53 | #ifdef TEST_OVERLAP 54 | src_len += src_off; 55 | fail(oend >= src_len, UCL_E_OVERLAP_OVERRUN); 56 | #endif 57 | 58 | for (;;) 59 | { 60 | ucl_uint m_off, m_len; 61 | 62 | while (getbit(bb)) 63 | { 64 | fail(ilen >= src_len, UCL_E_INPUT_OVERRUN); 65 | fail(olen >= oend, UCL_E_OUTPUT_OVERRUN); 66 | #ifdef TEST_OVERLAP 67 | fail(olen > ilen, UCL_E_OVERLAP_OVERRUN); 68 | olen++; ilen++; 69 | #else 70 | dst[olen++] = src[ilen++]; 71 | #endif 72 | } 73 | m_off = 1; 74 | do { 75 | m_off = m_off*2 + getbit(bb); 76 | fail(ilen >= src_len, UCL_E_INPUT_OVERRUN); 77 | fail(m_off > UCL_UINT32_C(0xffffff) + 3, UCL_E_LOOKBEHIND_OVERRUN); 78 | } while (!getbit(bb)); 79 | if (m_off == 2) 80 | { 81 | m_off = last_m_off; 82 | } 83 | else 84 | { 85 | fail(ilen >= src_len, UCL_E_INPUT_OVERRUN); 86 | m_off = (m_off-3)*256 + src[ilen++]; 87 | if (m_off == UCL_UINT32_C(0xffffffff)) 88 | break; 89 | last_m_off = ++m_off; 90 | } 91 | m_len = getbit(bb); 92 | m_len = m_len*2 + getbit(bb); 93 | if (m_len == 0) 94 | { 95 | m_len++; 96 | do { 97 | m_len = m_len*2 + getbit(bb); 98 | fail(ilen >= src_len, UCL_E_INPUT_OVERRUN); 99 | fail(m_len >= oend, UCL_E_OUTPUT_OVERRUN); 100 | } while (!getbit(bb)); 101 | m_len += 2; 102 | } 103 | m_len += (m_off > 0xd00); 104 | fail(olen + m_len > oend, UCL_E_OUTPUT_OVERRUN); 105 | fail(m_off > olen, UCL_E_LOOKBEHIND_OVERRUN); 106 | #ifdef TEST_OVERLAP 107 | olen += m_len + 1; 108 | fail(olen > ilen, UCL_E_OVERLAP_OVERRUN); 109 | #else 110 | { 111 | const ucl_bytep m_pos; 112 | m_pos = dst + olen - m_off; 113 | dst[olen++] = *m_pos++; 114 | do dst[olen++] = *m_pos++; while (--m_len > 0); 115 | } 116 | #endif 117 | } 118 | *dst_len = olen; 119 | return ilen == src_len ? UCL_E_OK : (ilen < src_len ? UCL_E_INPUT_NOT_CONSUMED : UCL_E_INPUT_OVERRUN); 120 | } 121 | 122 | #undef fail 123 | 124 | #endif /* getbit */ 125 | 126 | 127 | /*********************************************************************** 128 | // decompressor entries for the different bit-buffer sizes 129 | ************************************************************************/ 130 | 131 | #ifndef getbit 132 | 133 | #include "ucl_conf.h" 134 | #include "ucl.h" 135 | #include "getbit.h" 136 | 137 | 138 | UCL_PUBLIC(int) 139 | ucl_nrv2b_decompress_8 ( const ucl_bytep src, ucl_uint src_len, 140 | ucl_bytep dst, ucl_uintp dst_len, 141 | ucl_voidp wrkmem ) 142 | { 143 | #define getbit(bb) getbit_8(bb,src,ilen) 144 | #include "n2b_d.c" 145 | #undef getbit 146 | } 147 | 148 | #if 0 149 | UCL_PUBLIC(int) 150 | ucl_nrv2b_decompress_le16 ( const ucl_bytep src, ucl_uint src_len, 151 | ucl_bytep dst, ucl_uintp dst_len, 152 | ucl_voidp wrkmem ) 153 | { 154 | #define getbit(bb) getbit_le16(bb,src,ilen) 155 | #include "n2b_d.c" 156 | #undef getbit 157 | } 158 | 159 | 160 | UCL_PUBLIC(int) 161 | ucl_nrv2b_decompress_le32 ( const ucl_bytep src, ucl_uint src_len, 162 | ucl_bytep dst, ucl_uintp dst_len, 163 | ucl_voidp wrkmem ) 164 | { 165 | unsigned bc = 0; 166 | #define getbit(bb) getbit_le32(bb,bc,src,ilen) 167 | #include "n2b_d.c" 168 | #undef getbit 169 | } 170 | #endif /* 0 */ 171 | 172 | 173 | #endif /* !getbit */ 174 | 175 | 176 | /* 177 | vi:ts=4:et 178 | */ 179 | 180 | -------------------------------------------------------------------------------- /src/enc/ucl/ucl.h: -------------------------------------------------------------------------------- 1 | /* ucl.h -- prototypes for the UCL data compression library 2 | 3 | This file is part of the UCL data compression library. 4 | 5 | Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer 6 | Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer 7 | Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer 8 | Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer 9 | Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer 10 | Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer 11 | Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer 12 | Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer 13 | Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer 14 | All Rights Reserved. 15 | 16 | The UCL library is free software; you can redistribute it and/or 17 | modify it under the terms of the GNU General Public License as 18 | published by the Free Software Foundation; either version 2 of 19 | the License, or (at your option) any later version. 20 | 21 | The UCL library is distributed in the hope that it will be useful, 22 | but WITHOUT ANY WARRANTY; without even the implied warranty of 23 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 24 | GNU General Public License for more details. 25 | 26 | You should have received a copy of the GNU General Public License 27 | along with the UCL library; see the file COPYING. 28 | If not, write to the Free Software Foundation, Inc., 29 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 30 | 31 | Markus F.X.J. Oberhumer 32 | 33 | http://www.oberhumer.com/opensource/ucl/ 34 | */ 35 | 36 | 37 | #ifndef __UCL_H_INCLUDED 38 | #define __UCL_H_INCLUDED 39 | 40 | #ifndef __UCLCONF_H_INCLUDED 41 | #include "uclconf.h" 42 | #endif 43 | 44 | #ifdef __cplusplus 45 | extern "C" { 46 | #endif 47 | 48 | 49 | /*********************************************************************** 50 | // Compression fine-tuning configuration. 51 | // 52 | // Pass a NULL pointer to the compression functions for default values. 53 | // Otherwise set all values to -1 [i.e. initialize the struct by a 54 | // `memset(x,0xff,sizeof(x))'] and then set the required values. 55 | ************************************************************************/ 56 | 57 | struct ucl_compress_config_t 58 | { 59 | int bb_endian; 60 | int bb_size; 61 | ucl_uint max_offset; 62 | ucl_uint max_match; 63 | int s_level; 64 | int h_level; 65 | int p_level; 66 | int c_flags; 67 | ucl_uint m_size; 68 | }; 69 | 70 | #define ucl_compress_config_p ucl_compress_config_t __UCL_MMODEL * 71 | 72 | 73 | /*********************************************************************** 74 | // compressors 75 | // 76 | // Pass NULL for `cb' (no progress callback), `conf' (default compression 77 | // configuration) and `result' (no statistical result). 78 | ************************************************************************/ 79 | 80 | UCL_EXTERN(int) 81 | ucl_nrv2b_99_compress ( const ucl_bytep src, ucl_uint src_len, 82 | ucl_bytep dst, ucl_uintp dst_len, 83 | ucl_progress_callback_p cb, 84 | int level, 85 | const struct ucl_compress_config_p conf, 86 | ucl_uintp result ); 87 | 88 | UCL_EXTERN(int) 89 | ucl_nrv2d_99_compress ( const ucl_bytep src, ucl_uint src_len, 90 | ucl_bytep dst, ucl_uintp dst_len, 91 | ucl_progress_callback_p cb, 92 | int level, 93 | const struct ucl_compress_config_p conf, 94 | ucl_uintp result ); 95 | 96 | UCL_EXTERN(int) 97 | ucl_nrv2e_99_compress ( const ucl_bytep src, ucl_uint src_len, 98 | ucl_bytep dst, ucl_uintp dst_len, 99 | ucl_progress_callback_p cb, 100 | int level, 101 | const struct ucl_compress_config_p conf, 102 | ucl_uintp result ); 103 | 104 | 105 | /*********************************************************************** 106 | // decompressors 107 | // 108 | // Always pass NULL for `wrkmem'. This parameter is for symetry 109 | // with my other compression libaries and is not used in UCL - 110 | // UCL does not need any additional memory (or even local stack space) 111 | // for decompression. 112 | ************************************************************************/ 113 | 114 | UCL_EXTERN(int) 115 | ucl_nrv2b_decompress_8 ( const ucl_bytep src, ucl_uint src_len, 116 | ucl_bytep dst, ucl_uintp dst_len, 117 | ucl_voidp wrkmem ); 118 | UCL_EXTERN(int) 119 | ucl_nrv2b_decompress_le16 ( const ucl_bytep src, ucl_uint src_len, 120 | ucl_bytep dst, ucl_uintp dst_len, 121 | ucl_voidp wrkmem ); 122 | UCL_EXTERN(int) 123 | ucl_nrv2b_decompress_le32 ( const ucl_bytep src, ucl_uint src_len, 124 | ucl_bytep dst, ucl_uintp dst_len, 125 | ucl_voidp wrkmem ); 126 | UCL_EXTERN(int) 127 | ucl_nrv2b_decompress_safe_8 ( const ucl_bytep src, ucl_uint src_len, 128 | ucl_bytep dst, ucl_uintp dst_len, 129 | ucl_voidp wrkmem ); 130 | UCL_EXTERN(int) 131 | ucl_nrv2b_decompress_safe_le16 ( const ucl_bytep src, ucl_uint src_len, 132 | ucl_bytep dst, ucl_uintp dst_len, 133 | ucl_voidp wrkmem ); 134 | UCL_EXTERN(int) 135 | ucl_nrv2b_decompress_safe_le32 ( const ucl_bytep src, ucl_uint src_len, 136 | ucl_bytep dst, ucl_uintp dst_len, 137 | ucl_voidp wrkmem ); 138 | 139 | UCL_EXTERN(int) 140 | ucl_nrv2d_decompress_8 ( const ucl_bytep src, ucl_uint src_len, 141 | ucl_bytep dst, ucl_uintp dst_len, 142 | ucl_voidp wrkmem ); 143 | UCL_EXTERN(int) 144 | ucl_nrv2d_decompress_le16 ( const ucl_bytep src, ucl_uint src_len, 145 | ucl_bytep dst, ucl_uintp dst_len, 146 | ucl_voidp wrkmem ); 147 | UCL_EXTERN(int) 148 | ucl_nrv2d_decompress_le32 ( const ucl_bytep src, ucl_uint src_len, 149 | ucl_bytep dst, ucl_uintp dst_len, 150 | ucl_voidp wrkmem ); 151 | UCL_EXTERN(int) 152 | ucl_nrv2d_decompress_safe_8 ( const ucl_bytep src, ucl_uint src_len, 153 | ucl_bytep dst, ucl_uintp dst_len, 154 | ucl_voidp wrkmem ); 155 | UCL_EXTERN(int) 156 | ucl_nrv2d_decompress_safe_le16 ( const ucl_bytep src, ucl_uint src_len, 157 | ucl_bytep dst, ucl_uintp dst_len, 158 | ucl_voidp wrkmem ); 159 | UCL_EXTERN(int) 160 | ucl_nrv2d_decompress_safe_le32 ( const ucl_bytep src, ucl_uint src_len, 161 | ucl_bytep dst, ucl_uintp dst_len, 162 | ucl_voidp wrkmem ); 163 | 164 | UCL_EXTERN(int) 165 | ucl_nrv2e_decompress_8 ( const ucl_bytep src, ucl_uint src_len, 166 | ucl_bytep dst, ucl_uintp dst_len, 167 | ucl_voidp wrkmem ); 168 | UCL_EXTERN(int) 169 | ucl_nrv2e_decompress_le16 ( const ucl_bytep src, ucl_uint src_len, 170 | ucl_bytep dst, ucl_uintp dst_len, 171 | ucl_voidp wrkmem ); 172 | UCL_EXTERN(int) 173 | ucl_nrv2e_decompress_le32 ( const ucl_bytep src, ucl_uint src_len, 174 | ucl_bytep dst, ucl_uintp dst_len, 175 | ucl_voidp wrkmem ); 176 | UCL_EXTERN(int) 177 | ucl_nrv2e_decompress_safe_8 ( const ucl_bytep src, ucl_uint src_len, 178 | ucl_bytep dst, ucl_uintp dst_len, 179 | ucl_voidp wrkmem ); 180 | UCL_EXTERN(int) 181 | ucl_nrv2e_decompress_safe_le16 ( const ucl_bytep src, ucl_uint src_len, 182 | ucl_bytep dst, ucl_uintp dst_len, 183 | ucl_voidp wrkmem ); 184 | UCL_EXTERN(int) 185 | ucl_nrv2e_decompress_safe_le32 ( const ucl_bytep src, ucl_uint src_len, 186 | ucl_bytep dst, ucl_uintp dst_len, 187 | ucl_voidp wrkmem ); 188 | 189 | 190 | /*********************************************************************** 191 | // assembler decompressors [TO BE ADDED] 192 | ************************************************************************/ 193 | 194 | 195 | /*********************************************************************** 196 | // test an overlapping in-place decompression within a buffer: 197 | // - try a virtual decompression from &buf[src_off] -> &buf[0] 198 | // - no data is actually written 199 | // - only the bytes at buf[src_off..src_off+src_len-1] will get accessed 200 | // 201 | // NOTE: always pass NULL for `wrkmem' - see above. 202 | ************************************************************************/ 203 | 204 | UCL_EXTERN(int) 205 | ucl_nrv2b_test_overlap_8 ( const ucl_bytep buf, ucl_uint src_off, 206 | ucl_uint src_len, ucl_uintp dst_len, 207 | ucl_voidp wrkmem ); 208 | UCL_EXTERN(int) 209 | ucl_nrv2b_test_overlap_le16 ( const ucl_bytep buf, ucl_uint src_off, 210 | ucl_uint src_len, ucl_uintp dst_len, 211 | ucl_voidp wrkmem ); 212 | UCL_EXTERN(int) 213 | ucl_nrv2b_test_overlap_le32 ( const ucl_bytep buf, ucl_uint src_off, 214 | ucl_uint src_len, ucl_uintp dst_len, 215 | ucl_voidp wrkmem ); 216 | 217 | UCL_EXTERN(int) 218 | ucl_nrv2d_test_overlap_8 ( const ucl_bytep buf, ucl_uint src_off, 219 | ucl_uint src_len, ucl_uintp dst_len, 220 | ucl_voidp wrkmem ); 221 | UCL_EXTERN(int) 222 | ucl_nrv2d_test_overlap_le16 ( const ucl_bytep buf, ucl_uint src_off, 223 | ucl_uint src_len, ucl_uintp dst_len, 224 | ucl_voidp wrkmem ); 225 | UCL_EXTERN(int) 226 | ucl_nrv2d_test_overlap_le32 ( const ucl_bytep buf, ucl_uint src_off, 227 | ucl_uint src_len, ucl_uintp dst_len, 228 | ucl_voidp wrkmem ); 229 | 230 | UCL_EXTERN(int) 231 | ucl_nrv2e_test_overlap_8 ( const ucl_bytep buf, ucl_uint src_off, 232 | ucl_uint src_len, ucl_uintp dst_len, 233 | ucl_voidp wrkmem ); 234 | UCL_EXTERN(int) 235 | ucl_nrv2e_test_overlap_le16 ( const ucl_bytep buf, ucl_uint src_off, 236 | ucl_uint src_len, ucl_uintp dst_len, 237 | ucl_voidp wrkmem ); 238 | UCL_EXTERN(int) 239 | ucl_nrv2e_test_overlap_le32 ( const ucl_bytep buf, ucl_uint src_off, 240 | ucl_uint src_len, ucl_uintp dst_len, 241 | ucl_voidp wrkmem ); 242 | 243 | 244 | #ifdef __cplusplus 245 | } /* extern "C" */ 246 | #endif 247 | 248 | #endif /* already included */ 249 | 250 | -------------------------------------------------------------------------------- /src/enc/ucl/ucl_conf.h: -------------------------------------------------------------------------------- 1 | /* ucl_conf.h -- main internal configuration file for the the UCL library 2 | 3 | This file is part of the UCL data compression library. 4 | 5 | Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer 6 | All Rights Reserved. 7 | 8 | The UCL library is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of 11 | the License, or (at your option) any later version. 12 | 13 | The UCL library is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with the UCL library; see the file COPYING. 20 | If not, write to the Free Software Foundation, Inc., 21 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 22 | 23 | Markus F.X.J. Oberhumer 24 | 25 | http://www.oberhumer.com/opensource/ucl/ 26 | */ 27 | 28 | 29 | /* WARNING: this file should *not* be used by applications. It is 30 | part of the implementation of the library and is subject 31 | to change. 32 | */ 33 | 34 | 35 | #ifndef __UCL_CONF_H 36 | #define __UCL_CONF_H 37 | 38 | 39 | /*********************************************************************** 40 | // 41 | ************************************************************************/ 42 | 43 | #if defined(__UCLCONF_H_INCLUDED) 44 | # error "include this file first" 45 | #endif 46 | #include "uclconf.h" 47 | 48 | #if !defined(__UCL_MMODEL_HUGE) && defined(HAVE_MEMCMP) 49 | # define ucl_memcmp(a,b,c) memcmp(a,b,c) 50 | #endif 51 | #if !defined(__UCL_MMODEL_HUGE) && defined(HAVE_MEMCPY) 52 | # define ucl_memcpy(a,b,c) memcpy(a,b,c) 53 | #endif 54 | #if !defined(__UCL_MMODEL_HUGE) && defined(HAVE_MEMMOVE) 55 | # define ucl_memmove(a,b,c) memmove(a,b,c) 56 | #endif 57 | #if !defined(__UCL_MMODEL_HUGE) && defined(HAVE_MEMSET) 58 | # define ucl_memset(a,b,c) memset(a,b,c) 59 | #endif 60 | #if 0 /* WANT_ACC */ 61 | #if defined(UCL_HAVE_CONFIG_H) 62 | # define ACC_CONFIG_NO_HEADER 1 63 | #endif 64 | #define __ACCLIB_FUNCNAME(f) error_do_not_use_acclib 65 | #include "acc/acc.h" 66 | 67 | #if (ACC_CC_MSC && (_MSC_VER >= 1300)) 68 | /* avoid `-Wall' warnings in system header files */ 69 | # pragma warning(disable: 4820) 70 | /* avoid warnings about inlining */ 71 | # pragma warning(disable: 4710 4711) 72 | #endif 73 | 74 | #if defined(__UCL_MMODEL_HUGE) && (!ACC_HAVE_MM_HUGE_PTR) 75 | # error "this should not happen - check defines for __huge" 76 | #endif 77 | 78 | #if (ACC_OS_DOS16 + 0 != UCL_OS_DOS16 + 0) 79 | # error "DOS16" 80 | #endif 81 | #if (ACC_OS_OS216 + 0 != UCL_OS_OS216 + 0) 82 | # error "OS216" 83 | #endif 84 | #if (ACC_OS_WIN16 + 0 != UCL_OS_WIN16 + 0) 85 | # error "WIN16" 86 | #endif 87 | #if (ACC_OS_DOS32 + 0 != UCL_OS_DOS32 + 0) 88 | # error "DOS32" 89 | #endif 90 | #if (ACC_OS_OS2 + 0 != UCL_OS_OS2 + 0) 91 | # error "DOS32" 92 | #endif 93 | #if (ACC_OS_WIN32 + 0 != UCL_OS_WIN32 + 0) 94 | # error "WIN32" 95 | #endif 96 | #if (ACC_OS_WIN64 + 0 != UCL_OS_WIN64 + 0) 97 | # error "WIN64" 98 | #endif 99 | 100 | 101 | #include "acc/acc_incd.h" 102 | #if (ACC_OS_DOS16 || ACC_OS_OS216 || ACC_OS_WIN16) 103 | # include "acc/acc_ince.h" 104 | # include "acc/acc_inci.h" 105 | #endif 106 | 107 | #undef NDEBUG 108 | #if !defined(UCL_DEBUG) 109 | # define NDEBUG 1 110 | #endif 111 | #include 112 | 113 | 114 | #if (ACC_OS_DOS16 || ACC_OS_OS216 || ACC_OS_WIN16) && (ACC_CC_BORLANDC) 115 | # if (__BORLANDC__ >= 0x0450) /* v4.00 */ 116 | # pragma option -h /* enable fast huge pointers */ 117 | # else 118 | # pragma option -h- /* disable fast huge pointers - compiler bug */ 119 | # endif 120 | #endif 121 | #endif /* WANT_ACC */ 122 | 123 | 124 | /*********************************************************************** 125 | // 126 | ************************************************************************/ 127 | 128 | #if 1 129 | # define UCL_BYTE(x) ((unsigned char) (x)) 130 | #else 131 | # define UCL_BYTE(x) ((unsigned char) ((x) & 0xff)) 132 | #endif 133 | #if 0 134 | # define UCL_USHORT(x) ((unsigned short) (x)) 135 | #else 136 | # define UCL_USHORT(x) ((unsigned short) ((x) & 0xffff)) 137 | #endif 138 | 139 | #define UCL_MAX(a,b) ((a) >= (b) ? (a) : (b)) 140 | #define UCL_MIN(a,b) ((a) <= (b) ? (a) : (b)) 141 | #define UCL_MAX3(a,b,c) ((a) >= (b) ? UCL_MAX(a,c) : UCL_MAX(b,c)) 142 | #define UCL_MIN3(a,b,c) ((a) <= (b) ? UCL_MIN(a,c) : UCL_MIN(b,c)) 143 | 144 | #define ucl_sizeof(type) ((ucl_uint) (sizeof(type))) 145 | 146 | #define UCL_HIGH(array) ((ucl_uint) (sizeof(array)/sizeof(*(array)))) 147 | 148 | /* this always fits into 16 bits */ 149 | #define UCL_SIZE(bits) (1u << (bits)) 150 | #define UCL_MASK(bits) (UCL_SIZE(bits) - 1) 151 | 152 | #define UCL_LSIZE(bits) (1ul << (bits)) 153 | #define UCL_LMASK(bits) (UCL_LSIZE(bits) - 1) 154 | 155 | #define UCL_USIZE(bits) ((ucl_uint) 1 << (bits)) 156 | #define UCL_UMASK(bits) (UCL_USIZE(bits) - 1) 157 | 158 | /* Maximum value of a signed/unsigned type. 159 | Do not use casts, avoid overflows ! */ 160 | #define UCL_STYPE_MAX(b) (((1l << (8*(b)-2)) - 1l) + (1l << (8*(b)-2))) 161 | #define UCL_UTYPE_MAX(b) (((1ul << (8*(b)-1)) - 1ul) + (1ul << (8*(b)-1))) 162 | 163 | 164 | /*********************************************************************** 165 | // compiler and architecture specific stuff 166 | ************************************************************************/ 167 | 168 | /* Some defines that indicate if memory can be accessed at unaligned 169 | * memory addresses. You should also test that this is actually faster 170 | * even if it is allowed by your system. 171 | */ 172 | 173 | #undef UA_GET2 174 | #undef UA_SET2 175 | #undef UA_GET4 176 | #undef UA_SET4 177 | #if 1 && (ACC_ARCH_AMD64 || ACC_ARCH_IA32) 178 | # define UA_GET2(p) (* (const ucl_ushortp) (p)) 179 | # define UA_SET2(p) (* (ucl_ushortp) (p)) 180 | # define UA_GET4(p) (* (const acc_uint32e_t *) (p)) 181 | # define UA_SET4(p) (* (acc_uint32e_t *) (p)) 182 | #elif 0 && (ACC_ARCH_M68K) && (ACC_CC_GNUC >= 0x020900ul) 183 | typedef struct { unsigned short v; } __ucl_ua2_t __attribute__((__aligned__(1))); 184 | typedef struct { unsigned long v; } __ucl_ua4_t __attribute__((__aligned__(1))); 185 | # define UA_GET2(p) (((const __ucl_ua2_t *)(p))->v) 186 | # define UA_SET2(p) (((__ucl_ua2_t *)(p))->v) 187 | # define UA_GET4(p) (((const __ucl_ua4_t *)(p))->v) 188 | # define UA_SET4(p) (((__ucl_ua4_t *)(p))->v) 189 | #endif 190 | 191 | 192 | /*********************************************************************** 193 | // some globals 194 | ************************************************************************/ 195 | 196 | __UCL_EXTERN_C int __ucl_init_done; 197 | UCL_EXTERN(const ucl_bytep) ucl_copyright(void); 198 | 199 | 200 | /*********************************************************************** 201 | // ANSI C preprocessor macros 202 | ************************************************************************/ 203 | 204 | #define _UCL_STRINGIZE(x) #x 205 | #define _UCL_MEXPAND(x) _UCL_STRINGIZE(x) 206 | 207 | 208 | /*********************************************************************** 209 | // 210 | ************************************************************************/ 211 | 212 | //#include "ucl_ptr.h" 213 | 214 | 215 | #endif /* already included */ 216 | 217 | /* 218 | vi:ts=4:et 219 | */ 220 | 221 | -------------------------------------------------------------------------------- /src/enc/yar.c: -------------------------------------------------------------------------------- 1 | /* yar.c: decode and encode MM yaz archives */ 2 | 3 | /* 4 | * this file can also be compiled as a standalone program for 5 | * decompressing the contents of a MM yaz archive like so: 6 | * gcc -o unyar -Wall -Wextra -std=c99 -pedantic -DYAR_MAIN_TEST=1 yar.c 7 | * 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #define FERR(x) { \ 16 | fprintf(stderr, x); \ 17 | fprintf(stderr, "\n"); \ 18 | exit(EXIT_FAILURE); \ 19 | } 20 | 21 | /* surely an archive won't exceed 64 MB */ 22 | #define YAR_MAX (1024 * 1024 * 64) 23 | 24 | /* align out address before writing compressed file */ 25 | #define FILE_ALIGN \ 26 | while ((outSz % align)) \ 27 | { \ 28 | out[outSz] = 0; \ 29 | outSz += 1; \ 30 | } 31 | 32 | struct yarFile 33 | { 34 | int idx; /* original index in list */ 35 | int ofs; /* global offset of file */ 36 | }; 37 | 38 | static 39 | unsigned int 40 | u32b(void *src) 41 | { 42 | unsigned char *arr = src; 43 | 44 | return (arr[0] << 24) | (arr[1] << 16) | (arr[2] << 8) | arr[3]; 45 | } 46 | 47 | static 48 | void 49 | u32wr(void *dst, unsigned int src) 50 | { 51 | unsigned char *arr = dst; 52 | 53 | arr[0] = src >> 24; 54 | arr[1] = src >> 16; 55 | arr[2] = src >> 8; 56 | arr[3] = src; 57 | } 58 | 59 | static 60 | void 61 | progress(const char *name, int progress, int end) 62 | { 63 | fprintf( 64 | stderr 65 | , "\r""repacking '%s' %d/%d: " 66 | , name 67 | , progress 68 | , end 69 | ); 70 | } 71 | 72 | /* reencode yar archive */ 73 | /* returns 0 on success, pointer to error message otherwise */ 74 | char * 75 | yar_reencode( 76 | unsigned char *src /* source archive */ 77 | , unsigned int sz /* source archive size */ 78 | , unsigned char *dst /* destination archive */ 79 | , unsigned int *dst_sz /* destination archive size */ 80 | , int align /* compressed file alignment */ 81 | 82 | , const char *name /* name of archive (0 = hide progress) */ 83 | , const char *codec /* the expected encoding header "Yaz0" */ 84 | , void *imm /* intermediate buffer for conversion */ 85 | , void *ctx /* compression context (if applicable) */ 86 | 87 | /* decompresses file; return non-zero on fail; optional 88 | * if files are already decompressed (up to user to know) 89 | */ 90 | , int decode(void *src, void *dst, unsigned dstSz, unsigned *srcSz) 91 | 92 | /* compress file; returns non-zero on fail; optional if 93 | * files are desired to be left decompressed 94 | */ 95 | , int encode(void *src, unsigned srcSz, void *dst, unsigned *dstSz, void *ctx) 96 | 97 | /* test if file has been previously encoded; optional */ 98 | , int exist(void *src, unsigned srcSz, void *dst, unsigned *dstSz) 99 | ) 100 | { 101 | unsigned char *ss; 102 | unsigned char *out; 103 | unsigned int end; 104 | unsigned int end_out; 105 | unsigned int outSz = 0; 106 | int progress_end; 107 | struct yarFile *list = 0; 108 | struct yarFile *item; 109 | int list_num; 110 | 111 | assert(src); 112 | assert(sz); 113 | assert(dst_sz); 114 | assert(dst); 115 | assert(align >= 0); 116 | assert((align & 3) == 0); /* cannot have alignment smaller than 4 */ 117 | 118 | out = dst; 119 | 120 | end = 0; 121 | 122 | ss = src; 123 | item = list; 124 | do 125 | { 126 | unsigned ofs; 127 | unsigned uncompSz; 128 | unsigned OG_encSz; 129 | unsigned char *b; 130 | 131 | ofs = u32b(ss) + end; 132 | 133 | /* first entry points to end of list, and first file */ 134 | if (!end) 135 | { 136 | end = ofs; 137 | outSz = end; 138 | 139 | /* allocate file list */ 140 | list_num = (end / 4) + 1; 141 | list = calloc(list_num, sizeof(*list)); 142 | if (!list) 143 | return "memory error"; 144 | item = list; 145 | 146 | FILE_ALIGN 147 | 148 | /* output file may be aligned differently */ 149 | end_out = outSz; 150 | 151 | progress_end = end / 4; 152 | } 153 | 154 | /* b now points to compressed file */ 155 | b = src + ofs; 156 | 157 | /* update progress display */ 158 | if (name) 159 | progress(name, (ss - src) / 4, progress_end); 160 | 161 | /* there should be room for 4-byte codec and 4-byte size */ 162 | if (b + 4 >= src + sz) 163 | break; 164 | 165 | /* decompressed file size is second word */ 166 | uncompSz = u32b(b + 4); 167 | 168 | /* yaz-encoded file */ 169 | if (!memcmp(b, codec, 4)) 170 | { 171 | unsigned char *fout = out + outSz; 172 | unsigned encSz; 173 | 174 | /* user doesn't want encoded data */ 175 | if (!encode) 176 | { 177 | imm = fout; 178 | encSz = uncompSz; 179 | } 180 | 181 | /* decode 'b' only if user provided decoder */ 182 | if (decode) 183 | { 184 | if (decode(b, imm, uncompSz, &OG_encSz)) 185 | return "decoder error"; 186 | } 187 | /* if no decoder is provided, direct copy */ 188 | else 189 | memcpy(imm, b + 0x10, uncompSz); 190 | 191 | /* encode only if user wants that */ 192 | if (encode) 193 | { 194 | /* if no exist function has been provided, or 195 | * if it hasn't been encoded yet, encode it 196 | */ 197 | if (!exist || !exist(imm, uncompSz, fout, &encSz)) 198 | { 199 | if (encode(imm, uncompSz, fout, &encSz, ctx)) 200 | return "encoder error"; 201 | } 202 | } 203 | 204 | /* point current entry to new file location */ 205 | if (ss > src) 206 | u32wr(out + (ss - src), outSz - end_out); 207 | 208 | /* first entry follows different rules */ 209 | else 210 | u32wr(out + (ss - src), end_out); 211 | 212 | /* advance out_sz to immediately after current file */ 213 | outSz += encSz; 214 | 215 | /* align output */ 216 | FILE_ALIGN 217 | } 218 | 219 | /* end of list */ 220 | else if (u32b(b) == 0) 221 | break; 222 | 223 | /* unknown codec */ 224 | else 225 | { 226 | char *errmsg = (char*)out; 227 | char srep[16]; 228 | sprintf(srep, "%08x", u32b(b)); 229 | sprintf( 230 | errmsg 231 | , "unknown codec 0x%s encountered at %08X!\n" 232 | , srep 233 | , ofs 234 | ); 235 | return errmsg; 236 | } 237 | 238 | ss += 4; 239 | item += 1; 240 | 241 | } while ((unsigned)(ss - src) < end); 242 | 243 | /* update progress display */ 244 | if (name) 245 | progress(name, progress_end, progress_end); 246 | 247 | /* point final entry to end (four 00 bytes) */ 248 | u32wr(out + (ss - src), outSz - end_out); 249 | memset(out + outSz, 0, 16); 250 | outSz += 4; 251 | 252 | /* in case list end changed due to padding, make multiple * 253 | * end-of-list markers throughout the alignment space */ 254 | if (end_out > end) 255 | { 256 | unsigned i; 257 | unsigned last = u32b(out + (end - 4)); 258 | for (i = 0; i < (end_out - end) / 4; ++i) 259 | { 260 | u32wr(out + end + i * 4, last); 261 | } 262 | } 263 | 264 | /* align final output size to 16 */ 265 | if (outSz & 15) 266 | outSz += 16 - (outSz & 15); 267 | 268 | /* if new file was constructed, note its size */ 269 | *dst_sz = outSz; 270 | 271 | /* cleanup */ 272 | free(list); 273 | 274 | /* success */ 275 | return 0; 276 | } 277 | 278 | #ifdef YAR_MAIN_TEST 279 | /* 280 | * 281 | * usage example (writes decompressed archive) 282 | * 283 | */ 284 | 285 | /* yaz decoder, courtesy of spinout182 */ 286 | static 287 | int spinout_yaz_dec(void *_src, void *_dst, unsigned dstSz, unsigned *srcSz) 288 | { 289 | unsigned char *src = _src; 290 | unsigned char *dst = _dst; 291 | 292 | int srcPlace = 0, dstPlace = 0; /*current read/write positions*/ 293 | 294 | unsigned int validBitCount = 0; /*number of valid bits left in "code" byte*/ 295 | unsigned char currCodeByte = 0; 296 | 297 | int uncompressedSize = dstSz; 298 | 299 | src += 0x10; 300 | 301 | while(dstPlace < uncompressedSize) 302 | { 303 | /*read new "code" byte if the current one is used up*/ 304 | if(!validBitCount) 305 | { 306 | currCodeByte = src[srcPlace]; 307 | ++srcPlace; 308 | validBitCount = 8; 309 | } 310 | 311 | if(currCodeByte & 0x80) 312 | { 313 | /*direct copy*/ 314 | dst[dstPlace] = src[srcPlace]; 315 | dstPlace++; 316 | srcPlace++; 317 | } 318 | else 319 | { 320 | /*RLE part*/ 321 | unsigned char byte1 = src[srcPlace]; 322 | unsigned char byte2 = src[srcPlace + 1]; 323 | srcPlace += 2; 324 | 325 | unsigned int dist = ((byte1 & 0xF) << 8) | byte2; 326 | unsigned int copySource = dstPlace - (dist + 1); 327 | 328 | unsigned int numBytes = byte1 >> 4; 329 | if(numBytes) 330 | numBytes += 2; 331 | else 332 | { 333 | numBytes = src[srcPlace] + 0x12; 334 | srcPlace++; 335 | } 336 | 337 | /*copy run*/ 338 | unsigned int i; 339 | for(i = 0; i < numBytes; ++i) 340 | { 341 | dst[dstPlace] = dst[copySource]; 342 | copySource++; 343 | dstPlace++; 344 | } 345 | } 346 | 347 | /*use next bit from "code" byte*/ 348 | currCodeByte <<= 1; 349 | validBitCount-=1; 350 | } 351 | 352 | return 0; 353 | 354 | (void)srcSz; 355 | } 356 | 357 | 358 | /* encodes decompressed data, storing result in dst */ 359 | static 360 | int encode(void *src, unsigned srcSz, void *_dst, unsigned *dstSz, void *ctx) 361 | { 362 | unsigned char *dst = _dst; 363 | 364 | /* header */ 365 | /* codec */ 366 | memcpy(dst, "raw0", 4); 367 | 368 | /* decompressed size */ 369 | u32wr(dst + 4, srcSz); 370 | 371 | /* 8 more bytes of padding */ 372 | memset(dst + 8, 0, 8); 373 | 374 | /* contents */ 375 | /* direct copy (data left unencoded; you could encode here though) */ 376 | memcpy(dst + 0x10, src, srcSz); 377 | *dstSz = srcSz + 0x10; 378 | 379 | return 0; 380 | 381 | (void)ctx; 382 | } 383 | 384 | /* checks if data has already been encoded */ 385 | /* if it does, dst is filled with that data and 1 is returned */ 386 | /* 0 is returned otherwise */ 387 | static 388 | int exist(void *src, unsigned srcSz, void *dst, unsigned *dstSz) 389 | { 390 | return 0; 391 | 392 | (void)src; 393 | (void)srcSz; 394 | (void)dst; 395 | (void)dstSz; 396 | } 397 | 398 | /* unsafe but it's a test program so it's fine */ 399 | static 400 | unsigned char * 401 | file_read(char *fn, unsigned *sz) 402 | { 403 | FILE *fp; 404 | unsigned char *raw; 405 | 406 | assert(fn); 407 | assert(sz); 408 | 409 | fp = fopen(fn, "rb"); 410 | if (!fp) 411 | FERR("failed to open file for reading"); 412 | 413 | fseek(fp, 0, SEEK_END); 414 | *sz = ftell(fp); 415 | 416 | if (!sz) 417 | FERR("read file size == 0"); 418 | 419 | fseek(fp, 0, SEEK_SET); 420 | raw = malloc(*sz); 421 | if (!raw) 422 | FERR("memory error"); 423 | 424 | if (fread(raw, 1, *sz, fp) != *sz) 425 | FERR("file read error"); 426 | 427 | fclose(fp); 428 | return raw; 429 | } 430 | 431 | /* minimal file writer 432 | * returns 0 on failure 433 | * returns non-zero on success 434 | */ 435 | int savefile(const char *fn, const void *dat, const size_t sz) 436 | { 437 | FILE *fp; 438 | 439 | /* rudimentary error checking returns 0 on any error */ 440 | if ( 441 | !fn 442 | || !sz 443 | || !dat 444 | || !(fp = fopen(fn, "wb")) 445 | || fwrite(dat, 1, sz, fp) != sz 446 | || fclose(fp) 447 | ) 448 | return 0; 449 | 450 | return 1; 451 | } 452 | 453 | int main(int argc, char *argv[]) 454 | { 455 | void *raw; 456 | unsigned int raw_sz; 457 | 458 | void *out; 459 | void *imm; 460 | unsigned int out_sz = 0; 461 | 462 | if (argc != 3) 463 | FERR("args: unyar in.yar out.yar"); 464 | 465 | raw = file_read(argv[1], &raw_sz); 466 | fprintf(stderr, "input file %s:\n", argv[1]); 467 | 468 | /* surely an archive won't exceed 64 MB */ 469 | out = malloc(1024 * 1024 * 64); 470 | imm = malloc(1024 * 1024 * 64); 471 | 472 | yar_reencode( 473 | raw, raw_sz, out, &out_sz, 16, argv[1], "Yaz0", imm, 0 474 | , spinout_yaz_dec 475 | , encode 476 | , exist 477 | ); 478 | 479 | /* write output file */ 480 | if (!savefile(argv[2], out, out_sz)) 481 | FERR("failed to write output file"); 482 | 483 | free(raw); 484 | free(out); 485 | free(imm); 486 | 487 | return 0; 488 | } 489 | 490 | #endif /* YAR_MAIN_TEST */ 491 | 492 | -------------------------------------------------------------------------------- /src/enc/yar.h: -------------------------------------------------------------------------------- 1 | /* yar.c: decode and encode MM yaz archives */ 2 | 3 | #ifndef Z64YAR_H_INCLUDED 4 | #define Z64YAR_H_INCLUDED 5 | 6 | /* reencode yar archive */ 7 | /* returns 0 on success, pointer to error message otherwise */ 8 | char * 9 | yar_reencode( 10 | unsigned char *src /* source archive */ 11 | , unsigned int sz /* source archive size */ 12 | , unsigned char *dst /* destination archive */ 13 | , unsigned int *dst_sz /* destination archive size */ 14 | , int align /* compressed file alignment */ 15 | 16 | , const char *name /* name of archive (0 = hide progress) */ 17 | , const char *codec /* the expected encoding header "Yaz0" */ 18 | , void *imm /* intermediate buffer for conversion */ 19 | , void *ctx /* compression context (if applicable) */ 20 | 21 | /* decompresses file; return non-zero on fail; optional 22 | * if files are already decompressed (up to user to know) 23 | */ 24 | , int decode(void *src, void *dst, unsigned dstSz, unsigned *srcSz) 25 | 26 | /* compress file; returns non-zero on fail; optional if 27 | * files are desired to be left decompressed 28 | */ 29 | , int encode(void *src, unsigned srcSz, void *dst, unsigned *dstSz, void *ctx) 30 | 31 | /* test if file has been previously encoded; optional */ 32 | , int exist(void *src, unsigned srcSz, void *dst, unsigned *dstSz) 33 | ); 34 | 35 | #endif /* Z64YAR_H_INCLUDED */ 36 | 37 | -------------------------------------------------------------------------------- /src/enc/yaz.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "stretchy_buffer.h" 6 | 7 | struct yazCtx 8 | { 9 | uint16_t *c; 10 | uint32_t *cmds; 11 | uint16_t *ctrl; 12 | uint8_t *raws; 13 | uint8_t *ctl; 14 | uint8_t *back; 15 | int *return_data; 16 | }; 17 | 18 | void yazCtx_free(void *_ctx) 19 | { 20 | struct yazCtx *ctx = _ctx; 21 | 22 | if (!ctx) 23 | return; 24 | 25 | free(ctx->return_data); 26 | sb_free(ctx->c); 27 | sb_free(ctx->raws); 28 | sb_free(ctx->ctrl); 29 | sb_free(ctx->cmds); 30 | sb_free(ctx->ctl); 31 | sb_free(ctx->back); 32 | } 33 | 34 | void *yazCtx_new(void) 35 | { 36 | struct yazCtx *ctx = calloc(1, sizeof(*ctx)); 37 | 38 | if (!ctx) 39 | return 0; 40 | 41 | /* allocate everything */ 42 | ctx->c = sb_add(ctx->c, 32); 43 | ctx->return_data = malloc(2 * sizeof(*ctx->return_data)); 44 | ctx->raws = sb_add(ctx->raws, 32); 45 | ctx->ctrl = sb_add(ctx->ctrl, 32); 46 | ctx->cmds = sb_add(ctx->cmds, 32); 47 | ctx->ctl = sb_add(ctx->ctl , 32); 48 | ctx->back = sb_add(ctx->back, 32); 49 | 50 | return ctx; 51 | } 52 | 53 | // MIO0 encoding 54 | #define MIx 0 55 | 56 | #define min(MINA, MINB) ( ( (MINA)<(MINB) ) ? (MINA) : (MINB) ) 57 | #define max(MAXA, MAXB) ( ( (MAXA)>(MAXB) ) ? (MAXA) : (MAXB) ) 58 | 59 | #define U32b(u32X) ((u32X)[0]<<24|(u32X)[1]<<16|(u32X)[2]<<8|(u32X)[3]) 60 | #define U16b(u32X) ((u32X)[0]<<8|(u32X)[1]) 61 | #define U32wr(u32DST,u32SRC) (*(u32DST+0))=((u32SRC)>>24)&0xFF,\ 62 | (*(u32DST+1))=((u32SRC)>>16)&0xFF,\ 63 | (*(u32DST+2))=((u32SRC)>>8)&0xFF,\ 64 | (*(u32DST+3))=((u32SRC)>>0)&0xFF 65 | #define U16wr(u16DST,u16SRC) (*(u16DST+0))=((u16SRC)>>8)&0xFF,\ 66 | (*(u16DST+1))=((u16SRC)>>0)&0xFF 67 | 68 | static uint16_t *_enc_next_cpy(struct yazCtx *ctx, uint8_t *back) { 69 | stb__sbn(ctx->c)=0; // initialize count to 0 70 | int x; 71 | for (x=0; x < (sb_count(back) & (0xFFFFFFFE)); x += 2) { 72 | sb_push(ctx->c, (back[x]<<8) | back[x+1]); 73 | } 74 | return ctx->c; 75 | } 76 | 77 | static uint32_t _enc_z_from_tables(struct yazCtx *ctx, uint8_t *ctl, uint8_t *back, uint8_t *values, uint8_t *output, int dec_s, const char *mode) { 78 | //_enc_next_cpy(NULL); 79 | uint8_t *b=ctl, *v=values; 80 | uint16_t *c = _enc_next_cpy(ctx, back); 81 | uint32_t bit=0x10000, output_position=0; 82 | // if dec_s declared, will keep accurate track 83 | while (dec_s > 0) { 84 | // get next bit 85 | if (bit > 0xFFFF) { 86 | bit = b[0]; 87 | b++; 88 | output[output_position++] = bit & 0xFF; 89 | bit |= 0x100; 90 | } 91 | // catch end of control commands 92 | if (bit & 0x80) { 93 | output[output_position++] = v[0]; 94 | v++; 95 | dec_s--; 96 | } else { 97 | uint16_t val=c[0]; 98 | c++; 99 | output[output_position++] = ((val>>8)&0xFF); 100 | output[output_position++] = ((val)&0xFF); 101 | 102 | // decrement dec_s accurately with length 103 | val>>=12; 104 | val&=0xF; 105 | if(MIx) 106 | dec_s--; 107 | else if(val==0) { 108 | val = v[0]; 109 | v++; 110 | output[output_position++]=val; 111 | val+=16; 112 | } 113 | dec_s -= val+2; 114 | } 115 | bit <<= 1; 116 | } 117 | return output_position; 118 | } 119 | 120 | static int _enc_find(struct yazCtx *ctx, uint8_t *array, uint8_t *needle, int needle_len, int start_index, int source_length) { 121 | while(start_index < (source_length - needle_len + 1)) { 122 | int r, index = -1; 123 | for(r=start_index; r < (source_length - needle_len + 1); r++) { 124 | if(array[r]==needle[0]) { 125 | index=r; 126 | break; 127 | } 128 | } 129 | 130 | // if we did not find even the first element, the search has failed 131 | if (index == -1) 132 | return -1; 133 | 134 | int i, p; 135 | // check for needle 136 | for (i = 0, p = index; i < needle_len; i++, p++) { 137 | if (array[p] != needle[i]) 138 | break; 139 | } 140 | if(i==needle_len) { 141 | // needle was found 142 | return index; 143 | } 144 | // continue to search for needle 145 | start_index = index + 1; 146 | } 147 | return -1; 148 | } 149 | 150 | static int *_enc_search(struct yazCtx *ctx, uint8_t *data, uint32_t pos, uint32_t sz, uint32_t cap/*=0x111*/) { 151 | int *return_data = ctx->return_data; 152 | // this is necessary unless pos is signed, so let's play it safe 153 | int mp = (pos>0x1000)?(pos-0x1000):0; 154 | int ml = min(cap, sz - pos); 155 | if(ml<3) { 156 | return_data[0]=return_data[1]=0; 157 | return return_data; 158 | } 159 | int 160 | hitp = 0, 161 | hitl = 3, 162 | hl = -1 163 | ; 164 | 165 | if (mp < pos) { 166 | hl = _enc_find(ctx, data+mp, data+pos, hitl, 0, pos + hitl - mp); 167 | while (hl < (pos - mp)) { 168 | while ((hitl < ml) && (data[pos + hitl] == data[mp + hl + hitl]) ) { 169 | hitl += 1; 170 | } 171 | mp += hl; 172 | hitp = mp; 173 | if (hitl == ml) { 174 | return_data[0] = hitp; 175 | return_data[1] = hitl; 176 | return return_data; 177 | } 178 | mp += 1; 179 | hitl += 1; 180 | if (mp >= pos) 181 | break; 182 | hl = _enc_find(ctx, data+mp, data+pos, hitl, 0, pos + hitl - mp); 183 | } 184 | } 185 | 186 | // if length < 4, return miss 187 | if (hitl < 4) 188 | hitl = 1; 189 | 190 | return_data[0] = hitp; 191 | return_data[1] = hitl-1; 192 | return return_data; 193 | } 194 | 195 | static 196 | uint32_t encode(struct yazCtx *ctx, uint8_t *data, uint32_t data_size, uint8_t *output, const char *mode) { 197 | uint32_t 198 | cap=0x111, 199 | sz=data_size, 200 | pos=0, 201 | flag=0x80000000 202 | ; 203 | // initialize count of each to 0 204 | stb__sbn(ctx->raws)=0; 205 | stb__sbn(ctx->ctrl)=0; 206 | stb__sbn(ctx->cmds)=0; 207 | 208 | sb_push(ctx->cmds, 0); 209 | 210 | if(data_size==0) { 211 | memcpy(output, mode, 4); 212 | int i; 213 | for(i=4; i<16; i++) 214 | output[i]=0x00; 215 | return 16; 216 | } 217 | while(posraws, data[pos]); 226 | ctx->cmds[sb_count(ctx->cmds)-1] |= flag; 227 | pos += 1; 228 | } else { 229 | search_return = _enc_search(ctx, data, pos+1, sz, cap); 230 | int tstp = search_return[0]; 231 | int tstl = search_return[1]; 232 | 233 | if ((hitl + 1) < tstl) { 234 | sb_push(ctx->raws, data[pos]); 235 | ctx->cmds[sb_count(ctx->cmds)-1] |= flag; 236 | pos += 1; 237 | flag >>= 1; 238 | if (flag == 0) { 239 | flag = 0x80000000; 240 | sb_push(ctx->cmds, 0); 241 | } 242 | hitl = tstl; 243 | hitp = tstp; 244 | } 245 | int e = pos - hitp - 1; 246 | pos += hitl; 247 | // handle MIx first, then Yax conditions 248 | if (cap == 0x12) { 249 | hitl -= 3; 250 | sb_push(ctx->ctrl, (hitl<<12) | e); 251 | } else if (hitl < 0x12) { 252 | hitl -= 2; 253 | sb_push(ctx->ctrl, (hitl<<12)|e); 254 | } else { 255 | sb_push(ctx->ctrl, e); 256 | sb_push(ctx->raws, hitl - 0x12); 257 | } 258 | } 259 | // advance the flag and refill if required 260 | flag >>= 1; 261 | if (flag == 0) { 262 | flag = 0x80000000; 263 | sb_push(ctx->cmds, 0);//cmds.push_back(0); 264 | } 265 | } 266 | 267 | // if no cmds in final word, delete it 268 | if (flag == 0x80000000) { 269 | stb__sbn(ctx->cmds) -= 1;//cmds.erase(cmds.end()-1); 270 | } 271 | 272 | // block and stream differentiation 273 | // Yay is block, Yaz is stream 274 | int mode_block=1, mode_stream=1; // temporary, for testing 275 | #ifdef YAZ_MAIN_TEST 276 | int g_hlen = 8; 277 | #else 278 | extern int g_hlen; 279 | #endif 280 | mode_block=!strcmp(mode,"Yay0"); 281 | if (g_hlen) { 282 | memcpy(output, mode, 4); 283 | U32wr(output+4, sz); 284 | } else 285 | output -= 8; /* headerless */ 286 | if (mode_block) { 287 | uint32_t l = (sb_count(ctx->cmds) << 2) + 16; 288 | uint32_t o = (sb_count(ctx->ctrl) << 1) + l; 289 | U32wr(output+8, l); 290 | U32wr(output+12, o); 291 | 292 | uint32_t output_position = g_hlen + 8; 293 | uint32_t x; 294 | for (x=0; xcmds); x++) { 295 | U32wr(output+output_position, ctx->cmds[x]); 296 | output_position+=4; 297 | } 298 | for (x=0; xctrl); x++) { 299 | U16wr(output+output_position, ctx->ctrl[x]); 300 | output_position+=2; 301 | } 302 | for (x=0; xraws); x++) { 303 | output[output_position++] = ctx->raws[x]; 304 | } 305 | return output_position; 306 | } else if(mode_stream) { 307 | U32wr(output+8, 0); 308 | U32wr(output+12, 0); 309 | 310 | uint32_t output_position = 0; 311 | stb__sbn(ctx->ctl)=0; // initialize count to 0 312 | stb__sbn(ctx->back)=0; // initialize count to 0 313 | uint32_t x; 314 | for (x=0; x < sb_count(ctx->cmds); x++) { 315 | sb_push(ctx->ctl, (ctx->cmds[x]>>24)&0xFF); 316 | sb_push(ctx->ctl, (ctx->cmds[x]>>16)&0xFF); 317 | sb_push(ctx->ctl, (ctx->cmds[x]>>8)&0xFF); 318 | sb_push(ctx->ctl, (ctx->cmds[x])&0xFF); 319 | } 320 | for (x=0; x < sb_count(ctx->ctrl); x++) { 321 | sb_push(ctx->back, (ctx->ctrl[x]>>8)&0xFF); 322 | sb_push(ctx->back, (ctx->ctrl[x])&0xFF); 323 | } 324 | output_position = _enc_z_from_tables(ctx, ctx->ctl, ctx->back, ctx->raws, output+g_hlen+8, data_size, mode); 325 | return output_position + g_hlen + 8; 326 | } 327 | return 0; 328 | } 329 | 330 | 331 | int 332 | yazenc( 333 | void *_src 334 | , unsigned src_sz 335 | , void *_dst 336 | , unsigned *dst_sz 337 | , void *_ctx 338 | ) 339 | { 340 | unsigned char *src = _src; 341 | unsigned char *dst = _dst; 342 | if (!_ctx) 343 | return 1; 344 | *dst_sz = encode(_ctx, src, src_sz, dst, "Yaz0"); 345 | return 0; 346 | } 347 | 348 | /* yaz decoder, courtesy of spinout182 */ 349 | int 350 | yazdec(void *_src, void *_dst, unsigned dstSz, unsigned *srcSz) 351 | { 352 | unsigned char *src = _src; 353 | unsigned char *dst = _dst; 354 | 355 | int srcPlace = 0, dstPlace = 0; /*current read/write positions*/ 356 | 357 | unsigned int validBitCount = 0; /*number of valid bits left in "code" byte*/ 358 | unsigned char currCodeByte = 0; 359 | 360 | int uncompressedSize = dstSz; 361 | 362 | src += 0x10; 363 | 364 | while(dstPlace < uncompressedSize) 365 | { 366 | /*read new "code" byte if the current one is used up*/ 367 | if(!validBitCount) 368 | { 369 | currCodeByte = src[srcPlace]; 370 | ++srcPlace; 371 | validBitCount = 8; 372 | } 373 | 374 | if(currCodeByte & 0x80) 375 | { 376 | /*direct copy*/ 377 | dst[dstPlace] = src[srcPlace]; 378 | dstPlace++; 379 | srcPlace++; 380 | } 381 | else 382 | { 383 | /*RLE part*/ 384 | unsigned char byte1 = src[srcPlace]; 385 | unsigned char byte2 = src[srcPlace + 1]; 386 | srcPlace += 2; 387 | 388 | unsigned int dist = ((byte1 & 0xF) << 8) | byte2; 389 | unsigned int copySource = dstPlace - (dist + 1); 390 | 391 | unsigned int numBytes = byte1 >> 4; 392 | if(numBytes) 393 | numBytes += 2; 394 | else 395 | { 396 | numBytes = src[srcPlace] + 0x12; 397 | srcPlace++; 398 | } 399 | 400 | /*copy run*/ 401 | int i; 402 | for(i = 0; i < numBytes; ++i) 403 | { 404 | dst[dstPlace] = dst[copySource]; 405 | copySource++; 406 | dstPlace++; 407 | } 408 | } 409 | 410 | /*use next bit from "code" byte*/ 411 | currCodeByte <<= 1; 412 | validBitCount-=1; 413 | } 414 | 415 | if (srcSz) 416 | *srcSz = srcPlace; 417 | 418 | return 0; 419 | } 420 | 421 | #ifdef YAZ_MAIN_TEST 422 | 423 | #define FERR(x) { \ 424 | fprintf(stderr, x); \ 425 | fprintf(stderr, "\n"); \ 426 | exit(EXIT_FAILURE); \ 427 | } 428 | 429 | int main(int argc, char* argv[]) 430 | { 431 | FILE *fp; 432 | struct yazCtx *ctx; 433 | unsigned size; 434 | 435 | if(argc < 2) 436 | FERR("args: yazenc in.raw > out.yaz"); 437 | 438 | fp = fopen(argv[1], "rb"); 439 | if(fp == NULL) 440 | FERR("failed to open file"); 441 | 442 | fseek(fp, 0, SEEK_END); 443 | size = ftell(fp); 444 | fseek(fp, 0, SEEK_SET); 445 | 446 | fprintf(stderr, "input file size: %d\n", size); 447 | 448 | void *buf = malloc(size); 449 | void *outbuf = malloc( (size + 64) * 2); 450 | 451 | if (fread(buf, 1, size, fp) != size) 452 | FERR("failed to read file"); 453 | 454 | fclose(fp); 455 | 456 | ctx = yazCtx_new(); 457 | if (yazenc(buf, size, outbuf, &size, ctx)) 458 | FERR("encoding error"); 459 | 460 | if (fwrite(outbuf, 1, size, stdout) != size) 461 | FERR("failed to write stdout"); 462 | 463 | yazCtx_free(ctx); 464 | free(buf); 465 | free(outbuf); 466 | return EXIT_SUCCESS; 467 | } 468 | #endif /* YAZ_MAIN_TEST */ 469 | 470 | 471 | -------------------------------------------------------------------------------- /src/enc/zlib.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "libdeflate/libdeflate.h" 6 | 7 | #define CAPACITY (1024 * 1024 * 4) /* output buffer max (4 mb) */ 8 | 9 | int 10 | zlibenc( 11 | void *_src 12 | , unsigned src_sz 13 | , void *_dst 14 | , unsigned *dst_sz 15 | , void *_ctx 16 | ) 17 | { 18 | unsigned char *src = _src; 19 | unsigned char *dst = _dst; 20 | unsigned result_sz; 21 | 22 | extern int g_hlen; /* header length */ 23 | memset(dst, 0, g_hlen); 24 | memcpy(dst, "ZLIB", 4); 25 | dst[4] = (src_sz >> 24); 26 | dst[5] = (src_sz >> 16); 27 | dst[6] = (src_sz >> 8); 28 | dst[7] = (src_sz >> 0); 29 | 30 | /* zlib and gzip have different header lengths 31 | * https://stackoverflow.com/a/68538037 32 | */ 33 | #if 1 34 | 35 | #if 0 /* zlib */ 36 | z_stream stream = {0}; 37 | int r; 38 | stream.avail_in = src_sz; 39 | stream.next_in = src; 40 | stream.avail_out = CAPACITY; 41 | stream.next_out = dst + g_hlen; 42 | #define HEADER_LEN 2 43 | if ((r = deflateInit(&stream, Z_BEST_COMPRESSION)) != Z_OK) 44 | { 45 | fprintf(stderr, "[!] fatal compression error %d\n", r); 46 | exit(EXIT_FAILURE); 47 | } 48 | if ((r = deflate(&stream, Z_FINISH)) == Z_STREAM_ERROR) 49 | { 50 | fprintf(stderr, "[!] Z_STREAM_ERROR\n"); 51 | exit(EXIT_FAILURE); 52 | } 53 | deflateEnd(&stream); 54 | 55 | result_sz = CAPACITY - stream.avail_out; 56 | #else /* libdeflate */ 57 | #define HEADER_LEN 0 58 | int level = 12; 59 | struct libdeflate_compressor *compressor; 60 | compressor = libdeflate_alloc_compressor(level); 61 | result_sz = libdeflate_deflate_compress( 62 | compressor 63 | , src, src_sz 64 | , dst + g_hlen 65 | , CAPACITY 66 | ); 67 | libdeflate_free_compressor(compressor); 68 | #endif 69 | #else 70 | /* this gzip code was left in for testing purposes; it may 71 | * be useful if matching ique recompression is ever revisited; 72 | * ique matches (except for one byte...) when compressed using 73 | * gzip 1.2.4 or 1.2.4a (they produce identical results), 74 | * available here: https://ftp.gnu.org/gnu/gzip/ 75 | * this is not a compression error, because decompressing the 76 | * recompressed rom produces a rom identical to the original 77 | * decompressed ique rom; 78 | * TODO: find out why that byte doesn't match on recompression; 79 | * TODO: once that's working, add --codec ique for those wanting 80 | * matching ique recompression; otherwise, modern zlib works great! 81 | */ 82 | #define HEADER_LEN 10 83 | FILE *fp = fopen("tmp.bin", "wb"); 84 | fwrite(src, 1, src_sz, fp); 85 | fclose(fp); 86 | system("./gzip -c -9 -n tmp.bin > tmp.bin.gzip"); 87 | fp = fopen("tmp.bin.gzip", "rb"); 88 | fseek(fp, 0, SEEK_END); 89 | result_sz = ftell(fp); 90 | fseek(fp, 0, SEEK_SET); 91 | fread(dst, 1, result_sz, fp); 92 | fclose(fp); 93 | #endif 94 | *dst_sz = result_sz + g_hlen; 95 | 96 | /* trim zlib/gzip header */ 97 | memmove(dst + g_hlen, dst + g_hlen + HEADER_LEN, result_sz); 98 | *dst_sz -= HEADER_LEN; 99 | 100 | return 0; 101 | (void)_ctx; /* -Wunused-parameter */ 102 | } 103 | 104 | -------------------------------------------------------------------------------- /src/enc/zx7.c: -------------------------------------------------------------------------------- 1 | #if 0 2 | #include "zx7/zx7.h" 3 | #include "zx7/optimize.c" 4 | #include "zx7/compress.c" 5 | #include "zx7/zx7.c" 6 | 7 | int 8 | zx7enc( 9 | void *_src 10 | , unsigned src_sz 11 | , void *_dst 12 | , unsigned *dst_sz 13 | , void *_ctx 14 | ) 15 | { 16 | unsigned char *src = _src; 17 | unsigned char *dst = _dst; 18 | 19 | extern int g_hlen; /* header length */ 20 | memset(dst, 0, g_hlen); 21 | memcpy(dst, "ZX70", 4); 22 | dst[4] = (src_sz >> 24); 23 | dst[5] = (src_sz >> 16); 24 | dst[6] = (src_sz >> 8); 25 | dst[7] = (src_sz >> 0); 26 | 27 | *dst_sz = ZX7Compress(src, src_sz, dst + g_hlen); 28 | 29 | if (!*dst_sz) 30 | return 1; 31 | 32 | *dst_sz += g_hlen; 33 | 34 | return 0; 35 | } 36 | #endif 37 | 38 | -------------------------------------------------------------------------------- /src/enc/zx7/compress.c: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) Copyright 2012-2016 by Einar Saukas. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * * Redistributions of source code must retain the above copyright 7 | * notice, this list of conditions and the following disclaimer. 8 | * * Redistributions in binary form must reproduce the above copyright 9 | * notice, this list of conditions and the following disclaimer in the 10 | * documentation and/or other materials provided with the distribution. 11 | * * The name of its author may not be used to endorse or promote products 12 | * derived from this software without specific prior written permission. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 18 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | */ 25 | 26 | #include "zx7.h" 27 | 28 | #if !TARGET_PRIZM 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | #include 35 | 36 | static unsigned char* c_output_data; 37 | static unsigned int c_output_index; 38 | static unsigned int c_bit_index; 39 | static int c_bit_mask; 40 | 41 | static inline void c_write_byte(int value) { 42 | c_output_data[c_output_index++] = value; 43 | } 44 | 45 | static void c_write_bit(int value) { 46 | if (c_bit_mask == 0) { 47 | c_bit_mask = 128; 48 | c_bit_index = c_output_index; 49 | c_write_byte(0); 50 | } 51 | if (value > 0) { 52 | c_output_data[c_bit_index] |= c_bit_mask; 53 | } 54 | c_bit_mask >>= 1; 55 | } 56 | 57 | static void write_elias_gamma(int value) { 58 | int i; 59 | 60 | for (i = 2; i <= value; i <<= 1) { 61 | c_write_bit(0); 62 | } 63 | while ((i >>= 1) > 0) { 64 | c_write_bit(value & i); 65 | } 66 | } 67 | 68 | unsigned char *compress( 69 | Optimal *optimal 70 | , unsigned char *input_data 71 | , unsigned int input_size 72 | , long skip 73 | , unsigned int *output_size 74 | , unsigned char *dst 75 | ) 76 | { 77 | unsigned int input_index; 78 | unsigned int input_prev; 79 | int offset1; 80 | int mask; 81 | int i; 82 | 83 | /* calculate and allocate output buffer */ 84 | input_index = input_size-1; 85 | *output_size = (optimal[input_index].bits+18+7)/8 + 3; 86 | unsigned char *ret = dst; 87 | if (!ret) { 88 | return 0; 89 | } 90 | 91 | c_output_data = ret + 3; 92 | 93 | /* un-reverse optimal sequence */ 94 | optimal[input_index].bits = 0; 95 | while (input_index != skip) { 96 | input_prev = input_index - (optimal[input_index].len > 0 ? optimal[input_index].len : 1); 97 | optimal[input_prev].bits = input_index; 98 | input_index = input_prev; 99 | } 100 | 101 | c_output_index = 0; 102 | c_bit_mask = 0; 103 | 104 | /* first byte is always literal */ 105 | c_write_byte(input_data[input_index]); 106 | 107 | /* process remaining bytes */ 108 | while ((input_index = optimal[input_index].bits) > 0) { 109 | if (optimal[input_index].len == 0) { 110 | 111 | /* literal indicator */ 112 | c_write_bit(0); 113 | 114 | /* literal value */ 115 | c_write_byte(input_data[input_index]); 116 | 117 | } else { 118 | 119 | /* sequence indicator */ 120 | c_write_bit(1); 121 | 122 | /* sequence length */ 123 | write_elias_gamma(optimal[input_index].len-1); 124 | 125 | /* sequence offset */ 126 | offset1 = optimal[input_index].offset-1; 127 | if (offset1 < 128) { 128 | c_write_byte(offset1); 129 | } else { 130 | offset1 -= 128; 131 | c_write_byte((offset1 & 127) | 128); 132 | for (mask = 1024; mask > 127; mask >>= 1) { 133 | c_write_bit(offset1 & mask); 134 | } 135 | } 136 | } 137 | } 138 | 139 | /* sequence indicator */ 140 | c_write_bit(1); 141 | 142 | /* end marker > MAX_LEN */ 143 | for (i = 0; i < 16; i++) { 144 | c_write_bit(0); 145 | } 146 | c_write_bit(1); 147 | 148 | // decompressed size is first three bytes 149 | ret[0] = (input_size & 0xFF0000) >> 16; 150 | ret[1] = (input_size & 0x00FF00) >> 8; 151 | ret[2] = (input_size & 0x0000FF); 152 | 153 | return ret; 154 | } 155 | 156 | #ifdef __cplusplus 157 | } 158 | #endif 159 | 160 | #endif 161 | -------------------------------------------------------------------------------- /src/enc/zx7/dzx7.c: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) Copyright 2015 by Einar Saukas. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * * Redistributions of source code must retain the above copyright 7 | * notice, this list of conditions and the following disclaimer. 8 | * * Redistributions in binary form must reproduce the above copyright 9 | * notice, this list of conditions and the following disclaimer in the 10 | * documentation and/or other materials provided with the distribution. 11 | * * The name of its author may not be used to endorse or promote products 12 | * derived from this software without specific prior written permission. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 18 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | */ 25 | 26 | #include "zx7.h" 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | static unsigned char *d_input_data; 33 | static unsigned char *d_output_data; 34 | static unsigned int d_input_index; 35 | static unsigned int d_output_index; 36 | static unsigned int d_input_size; 37 | static int bit_mask; 38 | static int bit_value; 39 | 40 | static 41 | int d_read_byte(void) { 42 | return d_input_data[d_input_index++]; 43 | } 44 | 45 | static 46 | int d_read_bit(void) { 47 | bit_mask >>= 1; 48 | if (bit_mask == 0) { 49 | bit_mask = 128; 50 | bit_value = d_read_byte(); 51 | } 52 | return bit_value & bit_mask ? 1 : 0; 53 | } 54 | 55 | static 56 | int read_elias_gamma(void) { 57 | int i; 58 | int value; 59 | 60 | i = 0; 61 | while (!d_read_bit()) { 62 | i++; 63 | } 64 | if (i > 15) { 65 | return -1; 66 | } 67 | value = 1; 68 | while (i--) { 69 | value = value << 1 | d_read_bit(); 70 | } 71 | return value; 72 | } 73 | 74 | int read_offset(void) { 75 | int value; 76 | int i; 77 | 78 | value = d_read_byte(); 79 | if (value < 128) { 80 | return value; 81 | } else { 82 | i = d_read_bit(); 83 | i = i << 1 | d_read_bit(); 84 | i = i << 1 | d_read_bit(); 85 | i = i << 1 | d_read_bit(); 86 | return ((value & 127) | (i << 7)) + 128; 87 | } 88 | } 89 | 90 | static 91 | void d_write_byte(int value) { 92 | d_output_data[d_output_index++] = value; 93 | } 94 | 95 | void d_write_bytes(int offset, int length) { 96 | int i; 97 | while (length-- > 0) { 98 | i = d_output_index-offset; 99 | d_write_byte(d_output_data[i]); 100 | } 101 | } 102 | 103 | unsigned int ZX7GetDecompressedSize(unsigned char* compressedData) { 104 | return compressedData[0] * 65536 + compressedData[1] * 256 + compressedData[2]; 105 | } 106 | 107 | int ZX7Decompress(unsigned char* srcData, unsigned char* destData, unsigned int destLength) { 108 | if (destLength < ZX7GetDecompressedSize(srcData) || !srcData || !destData) { 109 | return -1; 110 | } 111 | 112 | int length; 113 | 114 | d_input_data = srcData + 3; 115 | d_output_data = destData; 116 | 117 | d_input_size = 0; 118 | d_input_index = 0; 119 | d_output_index = 0; 120 | bit_mask = 0; 121 | 122 | d_write_byte(d_read_byte()); 123 | while (1) { 124 | if (!d_read_bit()) { 125 | d_write_byte(d_read_byte()); 126 | } else { 127 | length = read_elias_gamma()+1; 128 | if (length == 0) { 129 | return 0; 130 | } 131 | d_write_bytes(read_offset()+1, length); 132 | } 133 | } 134 | } 135 | 136 | #ifdef __cplusplus 137 | } 138 | #endif 139 | -------------------------------------------------------------------------------- /src/enc/zx7/optimize.c: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) Copyright 2012-2016 by Einar Saukas. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * * Redistributions of source code must retain the above copyright 7 | * notice, this list of conditions and the following disclaimer. 8 | * * Redistributions in binary form must reproduce the above copyright 9 | * notice, this list of conditions and the following disclaimer in the 10 | * documentation and/or other materials provided with the distribution. 11 | * * The name of its author may not be used to endorse or promote products 12 | * derived from this software without specific prior written permission. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 18 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | */ 25 | 26 | #include "zx7.h" 27 | 28 | #if !TARGET_PRIZM 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | 35 | #include 36 | #include /* memset */ 37 | 38 | /* reusable memory (free using zx7_shutdown()) */ 39 | static unsigned int *min = 0; 40 | static unsigned int *max = 0; 41 | static unsigned int *matches = 0; 42 | static unsigned int *match_slots = 0; 43 | static Optimal *optimal = 0; 44 | 45 | void 46 | zx7_shutdown(void) 47 | { 48 | if (min) 49 | free(min); 50 | if (max) 51 | free(max); 52 | if (matches) 53 | free(matches); 54 | if (match_slots) 55 | free(match_slots); 56 | if (optimal) 57 | free(optimal); 58 | } 59 | 60 | static int elias_gamma_bits(int value) { 61 | int bits; 62 | 63 | bits = 1; 64 | while (value > 1) { 65 | bits += 2; 66 | value >>= 1; 67 | } 68 | return bits; 69 | } 70 | 71 | static int count_bits(int offset, int len) { 72 | return 1 + (offset > 128 ? 12 : 8) + elias_gamma_bits(len-1); 73 | } 74 | 75 | Optimal *optimize( 76 | unsigned char *input_data 77 | , unsigned int input_size 78 | , unsigned long skip 79 | ) { 80 | 81 | unsigned int *match; 82 | int match_index; 83 | int offset; 84 | unsigned int len; 85 | unsigned int best_len; 86 | unsigned int bits; 87 | unsigned int i; 88 | 89 | /* allocate all data structures at once */ 90 | if (!min) 91 | min = malloc((MAX_OFFSET+1) * sizeof(*min)); 92 | if (!max) 93 | max = malloc((MAX_OFFSET+1) * sizeof(*max)); 94 | if (!matches) 95 | matches = malloc(256 * 256 * sizeof(*matches)); 96 | if (!match_slots) 97 | match_slots = malloc(input_size * sizeof(*match_slots)); 98 | if (!optimal) 99 | optimal = malloc(input_size * sizeof(*optimal)); 100 | 101 | if (!min || !max || !matches || !match_slots || !optimal) 102 | return 0; 103 | 104 | memset(min, 0, (MAX_OFFSET+1) * sizeof(*min)); 105 | memset(max, 0, (MAX_OFFSET+1) * sizeof(*max)); 106 | memset(matches, 0, 256 * 256 * sizeof(*matches)); 107 | memset(match_slots, 0, input_size * sizeof(*match_slots)); 108 | memset(optimal, 0, input_size * sizeof(*optimal)); 109 | 110 | /* index skipped bytes */ 111 | for (i = 1; i <= skip; i++) { 112 | match_index = input_data[i-1] << 8 | input_data[i]; 113 | match_slots[i] = matches[match_index]; 114 | matches[match_index] = i; 115 | } 116 | 117 | /* first byte is always literal */ 118 | optimal[skip].bits = 8; 119 | 120 | /* process remaining bytes */ 121 | for (; i < input_size; i++) { 122 | 123 | optimal[i].bits = optimal[i-1].bits + 9; 124 | match_index = input_data[i-1] << 8 | input_data[i]; 125 | best_len = 1; 126 | for (match = &matches[match_index]; *match != 0 && best_len < MAX_LEN; match = &match_slots[*match]) { 127 | offset = i - *match; 128 | if (offset > MAX_OFFSET) { 129 | *match = 0; 130 | break; 131 | } 132 | 133 | for (len = 2; len <= MAX_LEN && i >= skip+len; len++) { 134 | if (len > best_len) { 135 | best_len = len; 136 | bits = optimal[i-len].bits + count_bits(offset, len); 137 | if (optimal[i].bits > bits) { 138 | optimal[i].bits = bits; 139 | optimal[i].offset = offset; 140 | optimal[i].len = len; 141 | } 142 | } else if (max[offset] != 0 && i+1 == max[offset]+len) { 143 | len = i-min[offset]; 144 | if (len > best_len) { 145 | len = best_len; 146 | } 147 | } 148 | if (i < offset+len || input_data[i-len] != input_data[i-len-offset]) { 149 | break; 150 | } 151 | } 152 | min[offset] = i+1-len; 153 | max[offset] = i; 154 | } 155 | match_slots[i] = matches[match_index]; 156 | matches[match_index] = i; 157 | } 158 | 159 | return optimal; 160 | } 161 | 162 | 163 | #ifdef __cplusplus 164 | } 165 | #endif 166 | 167 | #endif 168 | -------------------------------------------------------------------------------- /src/enc/zx7/zx7.c: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) Copyright 2012-2016 by Einar Saukas. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * * Redistributions of source code must retain the above copyright 7 | * notice, this list of conditions and the following disclaimer. 8 | * * Redistributions in binary form must reproduce the above copyright 9 | * notice, this list of conditions and the following disclaimer in the 10 | * documentation and/or other materials provided with the distribution. 11 | * * The name of its author may not be used to endorse or promote products 12 | * derived from this software without specific prior written permission. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 18 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | */ 25 | 26 | #include "zx7.h" 27 | 28 | #if !TARGET_PRIZM 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | // ZX7 Compress the given data, outData is malloc'd and the return value is the length (first 3 bytes of data will be 24-bit size result for convenience) 35 | unsigned int ZX7Compress(unsigned char *srcData, unsigned int inLength, unsigned char *outData) { 36 | unsigned int output_size; 37 | compress(optimize(srcData, inLength, 0), srcData, inLength, 0, &output_size, outData); 38 | 39 | return output_size; 40 | } 41 | 42 | #ifdef __cplusplus 43 | } 44 | #endif 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /src/enc/zx7/zx7.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) Copyright 2012-2016 by Einar Saukas. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * * Redistributions of source code must retain the above copyright 7 | * notice, this list of conditions and the following disclaimer. 8 | * * Redistributions in binary form must reproduce the above copyright 9 | * notice, this list of conditions and the following disclaimer in the 10 | * documentation and/or other materials provided with the distribution. 11 | * * The name of its author may not be used to endorse or promote products 12 | * derived from this software without specific prior written permission. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 18 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | */ 25 | 26 | #pragma once 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | #if !TARGET_PRIZM 33 | 34 | typedef struct optimal_t { 35 | unsigned int bits; 36 | int offset; 37 | int len; 38 | } Optimal; 39 | 40 | #define MAX_OFFSET 2176 /* range 1..2176 */ 41 | #define MAX_LEN 65536 /* range 2..65536 */ 42 | 43 | Optimal *optimize(unsigned char *input_data, unsigned int input_size, unsigned long skip); 44 | 45 | unsigned char *compress(Optimal *optimal, unsigned char *input_data, unsigned int input_size, long skip, unsigned int *output_size, unsigned char *dst); 46 | 47 | // THOMAS : added these for my use: 48 | 49 | // ZX7 Compress the given data, outData is malloc'd and the return value is the length (first 3 bytes of data will be 24-bit size result for convenience) 50 | unsigned int ZX7Compress(unsigned char *srcData, unsigned int inLength, unsigned char *outData); 51 | 52 | #endif 53 | 54 | // Get decompressed size of ZX7Compress'd data 55 | unsigned int ZX7GetDecompressedSize(unsigned char* compressedData); 56 | 57 | // Decompress the given data. Returns 0 with no errors 58 | int ZX7Decompress(unsigned char* srcData, unsigned char* destData, unsigned int destLength); 59 | 60 | /* free reusable buffers */ 61 | void 62 | zx7_shutdown(void); 63 | 64 | #ifdef __cplusplus 65 | } 66 | #endif 67 | -------------------------------------------------------------------------------- /src/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "wow.h" 8 | #include "rom.h" 9 | 10 | FILE* printer; 11 | int g_hlen = 8; 12 | 13 | static void compress(struct rom *rom, int start, int end) 14 | { 15 | rom_dma_compress(rom, start, end, 1); 16 | } 17 | 18 | static void skip(struct rom *rom, int start, int end) 19 | { 20 | rom_dma_compress(rom, start, end, 0); 21 | } 22 | 23 | static void repack(struct rom *rom, int start, int end) 24 | { 25 | rom_dma_repack( 26 | rom 27 | , start 28 | , end 29 | , "yaz" /* old codec */ 30 | , 0 /* new codec */ 31 | ); 32 | } 33 | 34 | static void do_pattern( 35 | struct rom *rom 36 | , const char *str 37 | , void func(struct rom *rom, int start, int end) 38 | ) 39 | { 40 | const char *Ostr = str; 41 | int last_int = -1; 42 | int last_op = 0; 43 | int cur; 44 | int len; 45 | 46 | while (*str) 47 | { 48 | if (*str == '\'' || *str == '"') 49 | { 50 | ++str; 51 | continue; 52 | } 53 | 54 | /* calculate length of current token */ 55 | len = strspn(str, "0123456789xXaAbBcCdDeEfF"); /* allow hex */ 56 | if (!len) /* no len, assume it's an operator */ 57 | len = 1; 58 | 59 | /* is a number or variable */ 60 | if (isdigit(*str) || !strncmp(str, "END", 3)) 61 | { 62 | /* 'END' is shorthand for last entry */ 63 | if (!strncmp(str, "END", 3)) 64 | { 65 | cur = rom_dma_num(rom); 66 | str += 2; 67 | } 68 | 69 | /* otherwise, it's a number */ 70 | else 71 | sscanf(str, "%i", &cur); 72 | 73 | if (cur < last_int) 74 | die( 75 | "invalid pattern '%s'; " 76 | "values are not in ascending order" 77 | , Ostr 78 | ); 79 | 80 | /* apply operations on item(s) */ 81 | if (last_op == '-') 82 | func(rom, last_int, cur); 83 | else 84 | func(rom, cur, cur); 85 | 86 | /* prevents processing this item 87 | * again when 'through' is used 88 | */ 89 | cur += 1; 90 | } 91 | 92 | /* 'through' or 'single item', respectively */ 93 | else if (*str == '-' || *str == ',') 94 | { 95 | if (last_int < 0) 96 | die( 97 | "invalid pattern '%s'; " 98 | "pattern does not begin with number" 99 | , Ostr 100 | ); 101 | last_op = *str; 102 | } 103 | 104 | /* unknown character encountered */ 105 | else 106 | { 107 | die( 108 | "invalid pattern '%s'; " 109 | "encountered unknown operator '%c'" 110 | , Ostr 111 | , *str 112 | ); 113 | } 114 | 115 | /* advance */ 116 | str += len; 117 | last_int = cur; 118 | } 119 | } 120 | 121 | static void usage(void) 122 | { 123 | /* compression examples for users to adapt to their needs */ 124 | fprintf(printer, "\n"); 125 | fprintf(printer, " compressing oot debug\n"); 126 | fprintf(printer, " --in \"path/to/in.z64\"\n"); 127 | fprintf(printer, " --out \"path/to/out.z64\"\n"); 128 | fprintf(printer, " --mb 32\n"); 129 | fprintf(printer, " --codec yaz\n"); 130 | fprintf(printer, " --cache \"path/to/cache\"\n"); 131 | fprintf(printer, " --dma \"0x12F70,1548\"\n"); 132 | fprintf(printer, " --compress \"9-14,28-END\"\n"); 133 | fprintf(printer, " --threads 4\n"); 134 | fprintf(printer, "\n"); 135 | fprintf(printer, " compressing oot ntsc 1.0\n"); 136 | fprintf(printer, " --in \"path/to/in.z64\"\n"); 137 | fprintf(printer, " --out \"path/to/out.z64\"\n"); 138 | fprintf(printer, " --mb 32\n"); 139 | fprintf(printer, " --codec yaz\n"); 140 | fprintf(printer, " --cache \"path/to/cache\"\n"); 141 | fprintf(printer, " --dma \"0x7430,1526\"\n"); 142 | fprintf(printer, " --compress \"10-14,27-END\"\n"); 143 | fprintf(printer, " --threads 4\n"); 144 | fprintf(printer, "\n"); 145 | fprintf(printer, " compressing mm usa\n"); 146 | fprintf(printer, " --in \"path/to/in.z64\"\n"); 147 | fprintf(printer, " --out \"path/to/out.z64\"\n"); 148 | fprintf(printer, " --mb 32\n"); 149 | fprintf(printer, " --codec yaz\n"); 150 | fprintf(printer, " --cache \"path/to/cache\"\n"); 151 | fprintf(printer, " --dma \"0x1A500,1568\"\n"); 152 | fprintf(printer, " --compress \"10-14,23,24,31-END\"\n"); 153 | fprintf(printer, " --skip \"1127\"\n"); 154 | fprintf(printer, " --repack \"15-20,22\"\n"); 155 | fprintf(printer, " --threads 4\n"); 156 | fprintf(printer, "\n"); 157 | fprintf(printer, " arguments\n"); 158 | fprintf(printer, " --in uncompressed input rom\n"); 159 | fprintf(printer, "\n"); 160 | fprintf(printer, " --out compressed output rom\n"); 161 | fprintf(printer, "\n"); 162 | fprintf(printer, " --matching attempt matching compression at the cost of\n"); 163 | fprintf(printer, " some optimizations and reduced performance\n"); 164 | fprintf(printer, "\n"); 165 | fprintf(printer, " --mb how many mb the compressed rom should be\n"); 166 | fprintf(printer, "\n"); 167 | fprintf(printer, " --codec currently supported codecs\n"); 168 | fprintf(printer, " yaz\n"); 169 | fprintf(printer, " ucl\n"); 170 | fprintf(printer, " lzo\n"); 171 | fprintf(printer, " zlib\n"); 172 | fprintf(printer, " aplib\n"); 173 | fprintf(printer, " * to use non-yaz codecs, find patches\n"); 174 | fprintf(printer, " and code on my z64enc repo\n"); 175 | fprintf(printer, "\n"); 176 | fprintf(printer, " --cache is optional and won't be created if\n"); 177 | fprintf(printer, " no path is specified (having a cache\n"); 178 | fprintf(printer, " makes subsequent compressions faster)\n"); 179 | fprintf(printer, " * pro-tip: linux users who don't want a\n"); 180 | fprintf(printer, " cache to persist across power cycles\n"); 181 | fprintf(printer, " can use the path \"/tmp/z64compress\"\n"); 182 | fprintf(printer, "\n"); 183 | fprintf(printer, " --dma specify dmadata address and count\n"); 184 | fprintf(printer, "\n"); 185 | fprintf(printer, " --compress enable compression on specified files\n"); 186 | fprintf(printer, "\n"); 187 | fprintf(printer, " --skip disable compression on specified files\n"); 188 | fprintf(printer, "\n"); 189 | fprintf(printer, " --headerless don't write file headers (for iQue)\n"); 190 | fprintf(printer, "\n"); 191 | fprintf(printer, " --repack handles Majora's Mask archives\n"); 192 | fprintf(printer, "\n"); 193 | fprintf(printer, " --threads optional multithreading;\n"); 194 | fprintf(printer, " exclude this argument to disable it\n"); 195 | fprintf(printer, "\n"); 196 | fprintf(printer, " --only-stdout reserve stderr for errors and print\n"); 197 | fprintf(printer, " everything else to stdout\n"); 198 | fprintf(printer, "\n"); 199 | fprintf(printer, " arguments are executed as they\n"); 200 | fprintf(printer, " are parsed, so order matters!\n"); 201 | fprintf(printer, "\n"); 202 | } 203 | 204 | wow_main 205 | { 206 | struct rom *rom = 0; 207 | const char *Ain = 0; 208 | const char *Aout = 0; 209 | const char *Adma = 0; 210 | const char *Acodec = 0; 211 | const char *Acache = 0; 212 | int Amb = 0; 213 | int Athreads = 0; 214 | bool Amatching = false; 215 | bool Aonly_stdout = false; 216 | bool Aheaderless = false; 217 | wow_main_argv; 218 | 219 | printer = stderr; 220 | for (int i = 1; i < argc; ++i) 221 | { 222 | if (!strcmp(argv[i], "--only-stdout")) 223 | { 224 | setvbuf(stdout, NULL, _IONBF, 0); 225 | printer = stdout; 226 | } 227 | } 228 | 229 | fprintf(printer, "welcome to z64compress 1.0.2 \n"); 230 | 231 | if (argc <= 1) 232 | { 233 | usage(); 234 | return EXIT_FAILURE; 235 | } 236 | 237 | /* hacky argument handling */ 238 | for (int i = 1; i < argc; i += 2) 239 | { 240 | const char *arg = argv[i]; 241 | 242 | /* arguments that do not require additional parameters */ 243 | 244 | if(!strcmp(arg, "--only-stdout")) 245 | { 246 | if (Aonly_stdout) 247 | die("--only-stdout arg provided more than once"); 248 | // handled above 249 | Aonly_stdout = true; 250 | i--; 251 | continue; 252 | } 253 | else if (!strcmp(arg, "--matching")) 254 | { 255 | if (Amatching) 256 | die("--matching arg provided more than once"); 257 | Amatching = true; 258 | i--; 259 | continue; 260 | } 261 | else if (!strcmp(arg, "--headerless")) 262 | { 263 | if (Aheaderless) 264 | die("--headerless arg provided more than once"); 265 | Aheaderless = true; 266 | g_hlen = 0; 267 | i--; 268 | continue; 269 | } 270 | 271 | /* arguments with additional parameters */ 272 | 273 | const char *next = argv[i + 1]; 274 | 275 | if (!next) 276 | die("%s missing parameter", arg); 277 | 278 | if (!strcmp(arg, "--in")) 279 | { 280 | if (Ain) 281 | die("--in arg provided more than once"); 282 | Ain = next; 283 | rom = rom_new(Ain); 284 | } 285 | else if (!strcmp(arg, "--out")) 286 | { 287 | if (Aout) 288 | die("--out arg provided more than once"); 289 | Aout = next; 290 | } 291 | else if (!strcmp(arg, "--cache")) 292 | { 293 | if (Acache) 294 | die("--cache arg provided more than once"); 295 | Acache = next; 296 | rom_set_cache(rom, Acache); 297 | } 298 | else if (!strcmp(arg, "--codec")) 299 | { 300 | if (Acodec) 301 | die("--codec arg provided more than once"); 302 | if (!Ain) 303 | die("--dma arg provided before --in arg"); 304 | Acodec = next; 305 | rom_set_codec(rom, Acodec); 306 | } 307 | else if (!strcmp(arg, "--dma")) 308 | { 309 | int num; 310 | int start = 0; 311 | 312 | if (!Acodec) 313 | die("--dma arg provided before --codec arg"); 314 | if (!Ain) 315 | die("--dma arg provided before --in arg"); 316 | if (Adma) 317 | die("--dma arg provided more than once"); 318 | Adma = next; 319 | if (sscanf(Adma, "%i,%i", &start, &num) != 2) 320 | die("--dma bad formatting '%s'", Adma); 321 | rom_dma(rom, start, num, Amatching); 322 | } 323 | else if (!strcmp(arg, "--mb")) 324 | { 325 | if (Amb) 326 | die("--mb arg provided more than once"); 327 | if (sscanf(next, "%i", &Amb) != 1) 328 | die("--mb could not get value from string '%s'", next); 329 | if (Amb <= 0) 330 | die("--mb invalid value %d", Amb); 331 | } 332 | else if (!strcmp(arg, "--compress")) 333 | { 334 | if (!Adma) 335 | die("--compress arg provided before --dma arg"); 336 | do_pattern(rom, next, compress); 337 | } 338 | else if (!strcmp(arg, "--skip")) 339 | { 340 | if (!Adma) 341 | die("--skip arg provided before --dma arg"); 342 | do_pattern(rom, next, skip); 343 | } 344 | else if (!strcmp(arg, "--repack")) 345 | { 346 | if (!Adma) 347 | die("--repack arg provided before --dma arg"); 348 | if (!Acodec) 349 | die("--repack arg provided before --codec arg"); 350 | do_pattern(rom, next, repack); 351 | } 352 | else if(!strcmp(arg, "--threads")) 353 | { 354 | if (Athreads) 355 | die("--threads arg provided more than once"); 356 | if (sscanf(next, "%i", &Athreads) != 1) 357 | die("--threads could not get value from string '%s'", next); 358 | if (Athreads < 0) 359 | die("--threads invalid value %d", Athreads); 360 | } 361 | else 362 | { 363 | die("unknown argument '%s'", arg); 364 | } 365 | } 366 | 367 | #define ARG_ZERO_TEST(TEST, NAME) \ 368 | if (!(TEST)) \ 369 | die("no " NAME " arg provided") 370 | 371 | ARG_ZERO_TEST(Ain , "--in" ); 372 | ARG_ZERO_TEST(Aout , "--out" ); 373 | ARG_ZERO_TEST(Acodec, "--codec"); 374 | 375 | #undef ARG_ZERO_TEST 376 | 377 | /* finished initializing dma settings */ 378 | rom_dma_ready(rom, Amatching); 379 | 380 | /* compress rom */ 381 | rom_compress(rom, Amb, Athreads, Amatching); 382 | fprintf(printer, "rom compressed successfully!\n"); 383 | 384 | /* write compressed rom */ 385 | rom_save(rom, Aout); 386 | fprintf(printer, "compressed rom written successfully!\n"); 387 | 388 | /* cleanup */ 389 | rom_free(rom); 390 | 391 | return EXIT_SUCCESS; 392 | } 393 | 394 | -------------------------------------------------------------------------------- /src/n64crc.c: -------------------------------------------------------------------------------- 1 | /* snesrc - SNES Recompiler 2 | * 3 | * Mar 23, 2010: addition by spinout to actually fix CRC if it is incorrect 4 | * 5 | * Copyright notice for this file: 6 | * Copyright (C) 2005 Parasyte 7 | * 8 | * Based on uCON64's N64 checksum algorithm by Andreas Sterbenz 9 | * 10 | * This program is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation; either version 2 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program; if not, write to the Free Software 22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 | */ 24 | 25 | #include 26 | 27 | #define ROL(i, b) (((i) << (b)) | ((i) >> (32 - (b)))) 28 | #define BYTES2LONG(b) ( (b)[0] << 24 | \ 29 | (b)[1] << 16 | \ 30 | (b)[2] << 8 | \ 31 | (b)[3] ) 32 | 33 | #define N64_HEADER_SIZE 0x40 34 | #define N64_BC_SIZE (0x1000 - N64_HEADER_SIZE) 35 | 36 | #define N64_CRC1 0x10 37 | #define N64_CRC2 0x14 38 | 39 | #define CHECKSUM_START 0x00001000 40 | #define CHECKSUM_LENGTH 0x00100000 41 | #define CHECKSUM_CIC6102 0xF8CA4DDC 42 | #define CHECKSUM_CIC6103 0xA3886759 43 | #define CHECKSUM_CIC6105 0xDF26F436 44 | #define CHECKSUM_CIC6106 0x1FEA617A 45 | 46 | 47 | static void gen_table(unsigned int crc_table[256]) 48 | { 49 | unsigned int crc, poly; 50 | int i, j; 51 | 52 | poly = 0xEDB88320; 53 | for (i = 0; i < 256; i++) { 54 | crc = i; 55 | for (j = 8; j > 0; j--) { 56 | if (crc & 1) crc = (crc >> 1) ^ poly; 57 | else crc >>= 1; 58 | } 59 | crc_table[i] = crc; 60 | } 61 | } 62 | 63 | 64 | static unsigned int crc32( 65 | unsigned int crc_table[256] 66 | , unsigned char *data 67 | , int len 68 | ) 69 | { 70 | unsigned int crc = ~0; 71 | int i; 72 | 73 | for (i = 0; i < len; i++) { 74 | crc = (crc >> 8) ^ crc_table[(crc ^ data[i]) & 0xFF]; 75 | } 76 | 77 | return ~crc; 78 | } 79 | 80 | 81 | static int N64GetCIC(unsigned int crc_table[256], unsigned char *data) 82 | { 83 | switch (crc32(crc_table, &data[N64_HEADER_SIZE], N64_BC_SIZE)) { 84 | case 0x6170A4A1: return 6101; 85 | case 0x90BB6CB5: return 6102; 86 | case 0x0B050EE0: return 6103; 87 | case 0x98BC2C86: return 6105; 88 | case 0xACC8580A: return 6106; 89 | } 90 | 91 | return 0; 92 | } 93 | 94 | 95 | static int N64CalcCRC( 96 | unsigned int crc_table[256] 97 | , unsigned int *crc 98 | , unsigned char *data 99 | ) 100 | { 101 | int bootcode, i; 102 | unsigned int seed; 103 | unsigned int t1, t2, t3; 104 | unsigned int t4, t5, t6; 105 | unsigned int r, d; 106 | 107 | switch ((bootcode = N64GetCIC(crc_table, data))) { 108 | case 6101: 109 | case 6102: 110 | seed = CHECKSUM_CIC6102; 111 | break; 112 | case 6103: 113 | seed = CHECKSUM_CIC6103; 114 | break; 115 | case 6105: 116 | seed = CHECKSUM_CIC6105; 117 | break; 118 | case 6106: 119 | seed = CHECKSUM_CIC6106; 120 | break; 121 | default: 122 | return 1; 123 | } 124 | 125 | t1 = t2 = t3 = t4 = t5 = t6 = seed; 126 | 127 | i = CHECKSUM_START; 128 | while (i < (CHECKSUM_START + CHECKSUM_LENGTH)) { 129 | d = BYTES2LONG(&data[i]); 130 | if ((t6 + d) < t6) 131 | t4++; 132 | t6 += d; 133 | t3 ^= d; 134 | r = ROL(d, (d & 0x1F)); 135 | t5 += r; 136 | if (t2 > d) 137 | t2 ^= r; 138 | else 139 | t2 ^= t6 ^ d; 140 | 141 | if (bootcode == 6105) 142 | t1 += BYTES2LONG(&data[N64_HEADER_SIZE + 0x0710 + (i & 0xFF)]) ^ d; 143 | else 144 | t1 += t5 ^ d; 145 | 146 | i += 4; 147 | } 148 | if (bootcode == 6103) { 149 | crc[0] = (t6 ^ t4) + t3; 150 | crc[1] = (t5 ^ t2) + t1; 151 | } 152 | else if (bootcode == 6106) { 153 | crc[0] = (t6 * t4) + t3; 154 | crc[1] = (t5 * t2) + t1; 155 | } 156 | else { 157 | crc[0] = t6 ^ t4 ^ t3; 158 | crc[1] = t5 ^ t2 ^ t1; 159 | } 160 | 161 | return 0; 162 | } 163 | 164 | 165 | /* recalculate rom crc */ 166 | void n64crc(void *rom) 167 | { 168 | unsigned int crc_table[256]; 169 | unsigned char CRC1[4]; 170 | unsigned char CRC2[4]; 171 | unsigned int crc[2]; 172 | unsigned char *rom8 = rom; 173 | 174 | assert(rom); 175 | 176 | gen_table(crc_table); 177 | 178 | if (!N64CalcCRC(crc_table, crc, rom)) 179 | { 180 | unsigned int kk1 = crc[0]; 181 | unsigned int kk2 = crc[1]; 182 | int i; 183 | 184 | for (i = 0; i < 4; ++i) 185 | { 186 | CRC1[i] = (kk1 >> (24-8*i))&0xFF; 187 | CRC2[i] = (kk2 >> (24-8*i))&0xFF; 188 | } 189 | 190 | for (i = 0; i < 4; ++i) 191 | *(rom8 + N64_CRC1 + i) = CRC1[i]; 192 | 193 | for (i = 0; i < 4; ++i) 194 | *(rom8 + N64_CRC2 + i) = CRC2[i]; 195 | } 196 | } 197 | 198 | -------------------------------------------------------------------------------- /src/n64crc.h: -------------------------------------------------------------------------------- 1 | /* snesrc - SNES Recompiler 2 | * 3 | * Mar 23, 2010: addition by spinout to actually fix CRC if it is incorrect 4 | * 5 | * Copyright notice for this file: 6 | * Copyright (C) 2005 Parasyte 7 | * 8 | * Based on uCON64's N64 checksum algorithm by Andreas Sterbenz 9 | * 10 | * This program is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation; either version 2 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program; if not, write to the Free Software 22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 | */ 24 | 25 | #ifndef N64CRC_H_INCLUDED 26 | #define N64CRC_H_INCLUDED 27 | 28 | /* recalculate rom crc */ 29 | void n64crc(void *rom); 30 | 31 | #endif /* N64CRC_H_INCLUDED */ 32 | 33 | -------------------------------------------------------------------------------- /src/rom.h: -------------------------------------------------------------------------------- 1 | /* 2 | * rom.h 3 | * 4 | * functions for compression magic reside herein 5 | * 6 | * z64me 7 | * 8 | */ 9 | 10 | #ifndef Z64COMPRESS_ROM_H_INCLUDED 11 | #define Z64COMPRESS_ROM_H_INCLUDED 12 | 13 | /* opaque definition */ 14 | struct rom; 15 | 16 | /* allocate a rom structure and load rom file */ 17 | struct rom *rom_new(const char *fn); 18 | 19 | /* free a rom structure */ 20 | void rom_free(struct rom *rom); 21 | 22 | /* save rom to disk using specified filename */ 23 | void rom_save(struct rom *rom, const char *fn); 24 | 25 | /* compress rom using specified algorithm */ 26 | void rom_compress(struct rom *rom, int mb, int numThreads, bool matching); 27 | 28 | /* specify start of dmadata and number of entries */ 29 | void rom_dma(struct rom *rom, unsigned int offset, int num_entries, bool matching); 30 | 31 | /* call this once dma settings are finalized */ 32 | void rom_dma_ready(struct rom *rom, bool matching); 33 | 34 | /* set compression flag on indices start <= idx <= end */ 35 | void 36 | rom_dma_compress(struct rom *rom, unsigned start, unsigned end, int comp); 37 | 38 | /* reencode existing archives within rom 39 | * NOTE: must be used before dma_ready() 40 | */ 41 | void rom_dma_repack( 42 | struct rom *rom 43 | , unsigned start 44 | , unsigned end 45 | , const char *from /* old codec */ 46 | , const char *to /* new codec */ 47 | ); 48 | 49 | /* get number of dma entries */ 50 | int rom_dma_num(struct rom *rom); 51 | 52 | /* set rom compression codec 53 | * valid options: "yaz", "lzo", "ucl", "aplib" 54 | * NOTE: to use codecs besides yaz, get patches from the z64enc repo 55 | */ 56 | void rom_set_codec(struct rom *rom, const char *codec); 57 | 58 | /* set rom compressed file cache directory */ 59 | void rom_set_cache(struct rom *rom, const char *cache); 60 | 61 | #endif /* Z64COMPRESS_ROM_H_INCLUDED */ 62 | 63 | -------------------------------------------------------------------------------- /src/sha1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define stb_big32(c) (((c)[0]<<24) + (c)[1]*65536 + (c)[2]*256 + (c)[3]) 6 | 7 | static void stb__sha1(unsigned char *chunk, unsigned h[5]) 8 | { 9 | int i; 10 | unsigned a,b,c,d,e; 11 | unsigned w[80]; 12 | 13 | for (i=0; i < 16; ++i) 14 | w[i] = stb_big32(&chunk[i*4]); 15 | for (i=16; i < 80; ++i) { 16 | unsigned t; 17 | t = w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16]; 18 | w[i] = (t + t) | (t >> 31); 19 | } 20 | 21 | a = h[0]; 22 | b = h[1]; 23 | c = h[2]; 24 | d = h[3]; 25 | e = h[4]; 26 | 27 | #define STB__SHA1(k,f) \ 28 | { \ 29 | unsigned temp = (a << 5) + (a >> 27) + (f) + e + (k) + w[i]; \ 30 | e = d; \ 31 | d = c; \ 32 | c = (b << 30) + (b >> 2); \ 33 | b = a; \ 34 | a = temp; \ 35 | } 36 | 37 | i=0; 38 | for (; i < 20; ++i) STB__SHA1(0x5a827999, d ^ (b & (c ^ d)) ); 39 | for (; i < 40; ++i) STB__SHA1(0x6ed9eba1, b ^ c ^ d ); 40 | for (; i < 60; ++i) STB__SHA1(0x8f1bbcdc, (b & c) + (d & (b ^ c)) ); 41 | for (; i < 80; ++i) STB__SHA1(0xca62c1d6, b ^ c ^ d ); 42 | 43 | #undef STB__SHA1 44 | 45 | h[0] += a; 46 | h[1] += b; 47 | h[2] += c; 48 | h[3] += d; 49 | h[4] += e; 50 | } 51 | 52 | void stb_sha1(unsigned char output[20], unsigned char *buffer, unsigned len) 53 | { 54 | unsigned char final_block[128]; 55 | unsigned end_start, final_len, j; 56 | int i; 57 | 58 | unsigned h[5]; 59 | 60 | h[0] = 0x67452301; 61 | h[1] = 0xefcdab89; 62 | h[2] = 0x98badcfe; 63 | h[3] = 0x10325476; 64 | h[4] = 0xc3d2e1f0; 65 | 66 | // we need to write padding to the last one or two 67 | // blocks, so build those first into 'final_block' 68 | 69 | // we have to write one special byte, plus the 8-byte length 70 | 71 | // compute the block where the data runs out 72 | end_start = len & ~63; 73 | 74 | // compute the earliest we can encode the length 75 | if (((len+9) & ~63) == end_start) { 76 | // it all fits in one block, so fill a second-to-last block 77 | end_start -= 64; 78 | } 79 | 80 | final_len = end_start + 128; 81 | 82 | // now we need to copy the data in 83 | assert(end_start + 128 >= len+9); 84 | assert(end_start < len || len < 64-9); 85 | 86 | j = 0; 87 | if (end_start > len) 88 | j = (unsigned) - (int) end_start; 89 | 90 | for (; end_start + j < len; ++j) 91 | final_block[j] = buffer[end_start + j]; 92 | final_block[j++] = 0x80; 93 | while (j < 128-5) // 5 byte length, so write 4 extra padding bytes 94 | final_block[j++] = 0; 95 | // big-endian size 96 | final_block[j++] = len >> 29; 97 | final_block[j++] = len >> 21; 98 | final_block[j++] = len >> 13; 99 | final_block[j++] = len >> 5; 100 | final_block[j++] = len << 3; 101 | assert(j == 128 && end_start + j == final_len); 102 | 103 | for (j=0; j < final_len; j += 64) { // 512-bit chunks 104 | if (j+64 >= end_start+64) 105 | stb__sha1(&final_block[j - end_start], h); 106 | else 107 | stb__sha1(&buffer[j], h); 108 | } 109 | 110 | for (i=0; i < 5; ++i) { 111 | output[i*4 + 0] = h[i] >> 24; 112 | output[i*4 + 1] = h[i] >> 16; 113 | output[i*4 + 2] = h[i] >> 8; 114 | output[i*4 + 3] = h[i] >> 0; 115 | } 116 | } 117 | 118 | // client can truncate this wherever they like 119 | void stb_sha1_readable(char display[30], unsigned char sha[20]) 120 | { 121 | char encoding[65] = "0123456789abcdefghijklmnopqrstuv" 122 | "wxyzABCDEFGHIJKLMNOPQRSTUVWXYZ#$"; 123 | int num_bits = 0, acc=0; 124 | int i=0,o=0; 125 | while (o < 26) { 126 | int v; 127 | // expand the accumulator 128 | if (num_bits < 6) { 129 | assert(i != 20); 130 | acc += sha[i++] << num_bits; 131 | num_bits += 8; 132 | } 133 | v = acc & ((1 << 6) - 1); 134 | display[o++] = encoding[v]; 135 | acc >>= 6; 136 | num_bits -= 6; 137 | } 138 | assert(num_bits == 20*8 - 26*6); 139 | display[o++] = '\0'; 140 | } 141 | 142 | -------------------------------------------------------------------------------- /src/sha1.h: -------------------------------------------------------------------------------- 1 | #ifndef STB_SHA1_H_INCLUDED 2 | #define STB_SHA1_H_INCLUDED 3 | 4 | void stb_sha1(unsigned char output[20], unsigned char *buffer, unsigned len); 5 | void stb_sha1_readable(char display[30], unsigned char sha[20]); 6 | 7 | #endif /* STB_SHA1_H_INCLUDED */ 8 | 9 | -------------------------------------------------------------------------------- /src/wow.c: -------------------------------------------------------------------------------- 1 | #define WOW_IMPLEMENTATION 2 | #include "wow.h" 3 | 4 | -------------------------------------------------------------------------------- /src/wow_dirent.h: -------------------------------------------------------------------------------- 1 | /* 2 | * wow_dirent.h 3 | * 4 | * dirent wrapper that abstracts unicode/utf8 platforms 5 | * 6 | * must be #include'd after dirent.h 7 | * 8 | * z64me 9 | * 10 | */ 11 | 12 | #ifndef WOW_DIRENT_INCLUDED 13 | #define WOW_DIRENT_INCLUDED 14 | #include "wow.h" 15 | 16 | #if defined(_WIN32) && defined(UNICODE) 17 | # define wow_DIR _WDIR 18 | # define wow_dirent _wdirent 19 | static 20 | wow_DIR * 21 | wow_opendir(const char *path) 22 | { 23 | void *wpath = wow_utf8_to_wchar(path); 24 | if (!wpath) 25 | return NULL; 26 | 27 | wow_DIR *rv = _wopendir(wpath); 28 | 29 | free(wpath); 30 | 31 | return rv; 32 | } 33 | static 34 | struct wow_dirent * 35 | wow_readdir(wow_DIR *dir) 36 | { 37 | struct wow_dirent *ep = _wreaddir(dir); 38 | if (!ep) 39 | return 0; 40 | 41 | /* convert d_name to utf8 for working on them directly */ 42 | char *str = wow_wchar_to_utf8(ep->d_name); 43 | memcpy(ep->d_name, str, strlen(str) + 1); 44 | free(str); 45 | 46 | return ep; 47 | } 48 | # define wow_closedir _wclosedir 49 | # define wow_dirent_char wchar_t 50 | 51 | #else /* not win32 unicode */ 52 | # define wow_DIR DIR 53 | # define wow_dirent dirent 54 | # define wow_opendir opendir 55 | # define wow_readdir readdir 56 | # define wow_closedir closedir 57 | # define wow_dirent_char char 58 | #endif 59 | 60 | #endif /* WOW_DIRENT_INCLUDED */ 61 | 62 | --------------------------------------------------------------------------------