From edebe94cbbb43cd74c233742363840f8317480cb Mon Sep 17 00:00:00 2001 From: Ivan Tatarinov Date: Tue, 25 May 2021 14:02:19 +0300 Subject: [PATCH] sdk: added `dzx7b` utility --- sdk/bin/dzx7b.exe | Bin 0 -> 14848 bytes sdk/bin/dzx7b.exe.license | 11 ++ sdk/src/zx7b/Makefile | 10 +- sdk/src/zx7b/dzx7b.c | 291 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 311 insertions(+), 1 deletion(-) create mode 100755 sdk/bin/dzx7b.exe create mode 100644 sdk/bin/dzx7b.exe.license create mode 100644 sdk/src/zx7b/dzx7b.c diff --git a/sdk/bin/dzx7b.exe b/sdk/bin/dzx7b.exe new file mode 100755 index 0000000000000000000000000000000000000000..69b40c85391159cd5042c6c7ec936bc80b9c4f72 GIT binary patch literal 14848 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 ST90z>Ij4bh8u-i8!2bYi54Z3D literal 0 HcmV?d00001 diff --git a/sdk/bin/dzx7b.exe.license b/sdk/bin/dzx7b.exe.license new file mode 100644 index 0000000..331be09 --- /dev/null +++ b/sdk/bin/dzx7b.exe.license @@ -0,0 +1,11 @@ +SPDX-FileName: dzx7b.exe + +SPDX-FileType: BINARY + +SPDX-FileChecksum: SHA1: 1c1d766371864e10bfb5c95fa57d7598e8a6bf89 + +SPDX-FileCopyrightText: Copyright (c) 2015 Einar Saukas. All rights reserved. + +SPDX-License-Identifier: BSD-3-clause + +SPDX-FileComment: dzx7b version 1.0 (2015) - LZ77/LZSS backwards decompressor. diff --git a/sdk/src/zx7b/Makefile b/sdk/src/zx7b/Makefile index 8799501..823104c 100644 --- a/sdk/src/zx7b/Makefile +++ b/sdk/src/zx7b/Makefile @@ -30,7 +30,9 @@ bindir ?= $(exec_prefix)/bin INSTALL ?= install INSTALL_PROGRAM ?= $(INSTALL) -BINS = zx7b$(EXESUFFIX) +BINS=\ + zx7b$(EXESUFFIX)\ + dzx7b$(EXESUFFIX) .PHONY: all all: $(foreach t,$(BINS),build/$(t)) @@ -42,12 +44,18 @@ $(DESTDIR)$(bindir): build/zx7b$(EXESUFFIX): $(srcdir)/zx7b.c Makefile | build $(CC) $(CFLAGS) -o $@ $< +build/dzx7b$(EXESUFFIX): $(srcdir)/dzx7b.c Makefile | build + $(CC) $(CFLAGS) -o $@ $< + .PHONY: install install: $(foreach t,$(BINS),$(DESTDIR)$(bindir)/$(t)) $(DESTDIR)$(bindir)/zx7b$(EXESUFFIX): build/zx7b$(EXESUFFIX) | $(DESTDIR)$(bindir) $(INSTALL_PROGRAM) $< $@ +$(DESTDIR)$(bindir)/dzx7b$(EXESUFFIX): build/dzx7b$(EXESUFFIX) | $(DESTDIR)$(bindir) + $(INSTALL_PROGRAM) $< $@ + .PHONY: uninstall uninstall: rm -f $(foreach t,$(BINS),$(DESTDIR)$(bindir)/$(t)) diff --git a/sdk/src/zx7b/dzx7b.c b/sdk/src/zx7b/dzx7b.c new file mode 100644 index 0000000..11fd4e6 --- /dev/null +++ b/sdk/src/zx7b/dzx7b.c @@ -0,0 +1,291 @@ +/* + * dzx7b - LZ77/LZSS backwards decompressor. + * + * Copyright (c) 2015 Einar Saukas. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * The name of its author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * SPDX-FileCopyrightText: Copyright (c) 2015 Einar Saukas. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * SPDX-LicenseComments: License's text equals to one from https://directory.fsf.org/wiki/License:BSD-3-Clause + */ + +#include +#include +#include + +#define PROGRAM "dzx7b" +#define DESCRIPTION "LZ77/LZSS backwards decompressor." +#define VERSION "1.0 (2015)" +#define COPYRIGHT "Copyright (c) 2015 Einar Saukas. All rights reserved." +#define LICENSE "Distributed under BSD 3-clause license." +#define HOMEPAGE "https://github.com/antoniovillena/zx7b/" + +FILE *ifp; +FILE *ofp; +char *input_name; +char *output_name; +unsigned char *input_data; +unsigned char *output_data; +size_t input_index; +size_t output_index; +size_t input_size; +size_t output_size; +size_t partial_counter; +size_t total_counter; +int bit_mask; +int bit_value; + +int read_byte() { + return input_data[input_index++]; +} + +int read_bit() { + bit_mask >>= 1; + if (bit_mask == 0) { + bit_mask = 128; + bit_value = read_byte(); + } + return bit_value & bit_mask ? 1 : 0; +} + +int read_elias_gamma() { + int i; + int value; + + value = 1; + while (!read_bit()) { + value = value << 1 | read_bit(); + } + if( (value&255)==255 ) + value= -1; + return value; +} + +int read_offset() { + int value; + int i; + + value = read_byte(); + if (value < 128) { + return value; + } else { + i = read_bit(); + i = i << 1 | read_bit(); + i = i << 1 | read_bit(); + i = i << 1 | read_bit(); + return (value & 127 | i << 7) + 128; + } +} + +void write_byte(int value) { + output_data[output_index++] = value; +} + +void write_bytes(int offset, int length) { + if (offset > output_size+output_index) { + fprintf(stderr, "Error: Invalid data in input file %s\n", input_name); + exit(1); + } + while (length-- > 0) { + write_byte(output_data[output_index-offset]); + } +} + +void decompress() { + int length,i; + + input_index = 0; + partial_counter = 0; + output_index = 0; + bit_mask = 0; + + write_byte(read_byte()); + while (1) { + if (!read_bit()) { + write_byte(read_byte()); + } else { + length = read_elias_gamma()+1; + if (length == 0) { + return; + } + write_bytes(read_offset()+1, length); + } + } +} + +void show_help() { + printf( + PROGRAM " version " VERSION " - " DESCRIPTION "\n" + COPYRIGHT "\n" + LICENSE "\n" + "Home page: " HOMEPAGE "\n" + "\n" + "Usage:\n" + " " PROGRAM " [-f] input.zx7 [output]\n" + "\n" + " -f Force overwrite of output file\n" + " output Decompressed output file\n" + ); +} + +int main(int argc, char *argv[]) { + int forced_mode = 0; + int i; + + /* process hidden optional parameters */ + for (i = 1; i < argc && *argv[i] == '-'; i++) { + if (!strcmp(argv[i], "-f")) { + forced_mode = 1; + } else { + fprintf(stderr, "Error: Invalid parameter `%s\'\n", argv[i]); + exit(1); + } + } + + /* determine output filename */ + if (argc == i+1) { + input_name = argv[i]; + input_size = strlen(input_name); + if (input_size > 4 && !strcmp(input_name+input_size-4, ".zx7")) { + output_name = (char *)malloc(input_size); + strcpy(output_name, input_name); + output_name[input_size-4] = '\0'; + } else { + fprintf(stderr, "Error: Cannot infer output filename\n"); + exit(1); + } + } else if (argc == i+2) { + input_name = argv[i]; + output_name = argv[i+1]; + } else { + show_help(); + exit(1); + } + + /* open input file */ + ifp = fopen(input_name, "rb"); + if (!ifp) { + fprintf(stderr, "Error: Cannot access input file %s\n", input_name); + exit(1); + } + + /* determine input size */ + fseek(ifp, 0L, SEEK_END); + input_size = ftell(ifp); + fseek(ifp, 0L, SEEK_SET); + if (!input_size) { + fprintf(stderr, "Error: Empty input file %s\n", argv[1]); + exit(1); + } + + /* allocate input buffer */ + input_data = (unsigned char *)malloc(input_size); + if (!input_data) { + fprintf(stderr, "Error: Insufficient memory\n"); + exit(1); + } + + /* read input file */ + total_counter = 0; + do { + partial_counter = fread(input_data+total_counter, sizeof(char), input_size-total_counter, ifp); + total_counter += partial_counter; + } while ( partial_counter > 0 ); + + if (total_counter != input_size) { + fprintf(stderr, "Error: Cannot read input file %s\n", argv[1]); + exit(1); + } + + /* check output file */ + if (!forced_mode && fopen(output_name, "rb") != NULL) { + fprintf(stderr, "Error: Already existing output file %s\n", output_name); + exit(1); + } + + /* create output file */ + ofp = fopen(output_name, "wb"); + if (!ofp) { + fprintf(stderr, "Error: Cannot create output file %s\n", output_name); + exit(1); + } + + /* reverse input data */ + for ( i= 0; i>1; i++ ){ + partial_counter = input_data[i]; + input_data[i] = input_data[input_size-1-i]; + input_data[input_size-1-i] = partial_counter; + } + + /* calculate output file size and allocate memory */ + output_size = 1; + read_byte(); + while (1) { + if (!read_bit()) { + output_size++; + read_byte(); + } else { + i = read_elias_gamma()+1; + if (i == 0) { + break; + } + read_offset(); + output_size+= i; + } + } + output_data = (unsigned char *)malloc(output_size); + if (!output_data) { + fprintf(stderr, "Error: Insufficient memory\n"); + exit(1); + } + + /* decompress */ + decompress(); + + /* reverse output data */ + for ( i= 0; i>1; i++ ) { + partial_counter= output_data[i]; + output_data[i]= output_data[output_size-1-i]; + output_data[output_size-1-i]= partial_counter; + } + + /* write output file */ + if (fwrite(output_data, sizeof(char), output_size, ofp) != output_size) { + fprintf(stderr, "Error: Cannot write output file %s\n", output_name); + exit(1); + } + + /* close input file */ + fclose(ifp); + + /* close output file */ + fclose(ofp); + + /* done! */ + printf("File `%s' converted from %lu to %lu bytes!\n", + output_name, (unsigned long)input_size, (unsigned long)output_size); + + return 0; +}