-
Notifications
You must be signed in to change notification settings - Fork 30
Add zx7 compression utility #96
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
dr-carlos
wants to merge
6
commits into
Jonimoose:master
Choose a base branch
from
dr-carlos:zx7
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
85497d0
Add zx7 compression utility
dr-carlos 3dee84c
Use prizm_rules instead of old util_rules
dr-carlos 753ae6b
Clean up zx7
dr-carlos c509526
Fix zx7 Makefile
dr-carlos be3daa2
Add CLI tool to (de)compress files with zx7
dr-carlos 162011d
Fix typo in zx7
dr-carlos File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| #--------------------------------------------------------------------------------- | ||
| # Clear the implicit built in rules | ||
| #--------------------------------------------------------------------------------- | ||
| .SUFFIXES: | ||
|
|
||
| CXX=g++ | ||
| AR=ar | ||
|
|
||
| #--------------------------------------------------------------------------------- | ||
| # TARGET is the name of the output | ||
| # BUILD is the directory where object files & intermediate files will be placed | ||
| # SOURCES is a list of directories containing source code | ||
| # INCLUDES is a list of directories containing extra header files | ||
| #--------------------------------------------------------------------------------- | ||
| TARGET := $(notdir $(CURDIR)) | ||
| SOURCES := ../src src | ||
| INCLUDES := | ||
|
|
||
| #--------------------------------------------------------------------------------- | ||
| # options for code and library generation | ||
| #--------------------------------------------------------------------------------- | ||
|
|
||
| CFLAGS = -O2 \ | ||
| -Wall \ | ||
| -funroll-loops \ | ||
| -fno-trapping-math \ | ||
| -fno-trapv \ | ||
| -Wno-switch \ | ||
| -UTARGET_PRIZM \ | ||
| $(INCLUDE) | ||
|
|
||
| # ASFLAGS = $(CFLAGS) | ||
|
|
||
| # LDFLAGS = -O2 -Wl,-static -Wl,-gc-sections | ||
|
|
||
| #--------------------------------------------------------------------------------- | ||
| # list of directories containing libraries, this must be the top level containing | ||
| # include and lib | ||
| #--------------------------------------------------------------------------------- | ||
| LIBDIRS := | ||
|
|
||
| OUTPUT := $(CURDIR)/zx7 | ||
|
|
||
| #--------------------------------------------------------------------------------- | ||
| # automatically build a list of object files for our project | ||
| #--------------------------------------------------------------------------------- | ||
| CXXFILES := $(foreach dir,$(SOURCES),$(wildcard $(dir)/*.cpp)) | ||
| CFILES := $(foreach dir,$(SOURCES),$(wildcard $(dir)/*.c)) | ||
|
|
||
| #--------------------------------------------------------------------------------- | ||
| # use CXX for linking C++ projects, CC for standard C | ||
| #--------------------------------------------------------------------------------- | ||
| LD := $(CXX) | ||
|
|
||
| #--------------------------------------------------------------------------------- | ||
| # build a list of include paths | ||
| #--------------------------------------------------------------------------------- | ||
| INCLUDE := $(foreach dir,$(INCLUDES), -iquote $(CURDIR)/$(dir)) \ | ||
| $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ | ||
| -I$(CURDIR)/$(BUILD) -I$(CURDIR)/.. -I/usr/include/ | ||
|
|
||
| export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) | ||
|
|
||
| .PHONY: clean | ||
|
|
||
| #--------------------------------------------------------------------------------- | ||
| $(OUTPUT): | ||
| $(CXX) $(CFLAGS) $(CXXFILES) $(CFILES) $< -o $(OUTPUT) | ||
|
|
||
| #--------------------------------------------------------------------------------- | ||
| export CYGWIN := nodosfilewarning | ||
| clean: | ||
| $(RM) -f $(OUTPUT) | ||
|
|
||
| #--------------------------------------------------------------------------------- |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,165 @@ | ||
| #include <cstdio> | ||
| #include <cstring> | ||
|
|
||
| #include <algorithm> | ||
| #include <fstream> | ||
| #include <iostream> | ||
| #include <vector> | ||
|
|
||
| #include "zx7.h" | ||
|
|
||
| void printHelp() { | ||
| std::cout << "Usage: zx7 [OPTION]... INPUT [OUTPUT]" << std::endl | ||
| << "Compress INPUT with zx7 to OUTPUT." << std::endl | ||
| << std::endl | ||
| << " -d, --decompress\tdecompress INPUT instead of compressing " | ||
| "it, outputting to stdout if OUTPUT not specified" | ||
| << std::endl | ||
| << " -h, --help\t\tdisplay this help and exit" << std::endl; | ||
| } | ||
|
|
||
| class InputParser { | ||
| public: | ||
| InputParser(int &argc, char **argv) { | ||
| for (int i = 1; i < argc; ++i) | ||
| this->tokens.push_back(std::string(argv[i])); | ||
| } | ||
|
|
||
| const std::string &getCmdOption(const std::string &option, bool pop = true) { | ||
| std::vector<std::string>::const_iterator itr = | ||
| std::find(this->tokens.begin(), this->tokens.end(), option); | ||
|
|
||
| if (itr != this->tokens.end() && ++itr != this->tokens.end()) { | ||
| if (pop) | ||
| this->tokens.erase(itr); | ||
|
|
||
| return *itr; | ||
| } | ||
|
|
||
| static const std::string empty_string(""); | ||
| return empty_string; | ||
| } | ||
|
|
||
| bool cmdOptionExists(const std::string &option, bool pop = false) { | ||
| std::vector<std::string>::const_iterator itr = | ||
| std::find(this->tokens.begin(), this->tokens.end(), option); | ||
|
|
||
| if (itr == this->tokens.end()) | ||
| return false; | ||
|
|
||
| if (pop) | ||
| this->tokens.erase(itr); | ||
|
|
||
| return true; | ||
| } | ||
|
|
||
| std::vector<std::string> getRemainingOptions() const { return this->tokens; } | ||
|
|
||
| private: | ||
| std::vector<std::string> tokens; | ||
| }; | ||
|
|
||
| // int main(int argc, char **argv) { | ||
| // InputParser input(argc, argv); | ||
| // if (input.cmdOptionExists("-h")) { | ||
| // // Do stuff | ||
| // } | ||
| // const std::string &filename = input.getCmdOption("-f"); | ||
| // if (!filename.empty()) { | ||
| // // Do interesting things ... | ||
| // } | ||
| // return 0; | ||
| // } | ||
|
|
||
| enum mode { COMPRESS, DECOMPRESS }; | ||
|
|
||
| int main(int argc, char **argv) { | ||
| InputParser input(argc, argv); | ||
|
|
||
| try { | ||
| if (argc == 1) | ||
| throw "No arguments provided"; | ||
|
|
||
| if (input.cmdOptionExists("--help") || input.cmdOptionExists("-h")) | ||
| throw "--help"; | ||
|
|
||
| mode compression_mode = COMPRESS; | ||
|
|
||
| // + is the same as ||, but evaluates both (i.e. removes --decompress and -d | ||
| // if both are used) | ||
| if (input.cmdOptionExists("-d", true) + | ||
| input.cmdOptionExists("--decompress", true)) | ||
| compression_mode = DECOMPRESS; | ||
|
|
||
| const std::vector<std::string> files = input.getRemainingOptions(); | ||
|
|
||
| if (files.size() == 0) | ||
| throw "No input file"; | ||
|
|
||
| if (files.size() == 1 && compression_mode == COMPRESS) | ||
| throw "No output file"; | ||
|
|
||
| std::ifstream input_file(files[0], std::ios::binary); | ||
| const std::string input_data((std::istreambuf_iterator<char>(input_file)), | ||
| std::istreambuf_iterator<char>()); | ||
| const int input_size = input_data.size(); | ||
|
|
||
| unsigned char *out_data; | ||
| unsigned int out_size; | ||
|
|
||
| if (compression_mode == COMPRESS) { | ||
| out_size = ZX7Compress((unsigned char *)input_data.data(), input_size, | ||
| &out_data); | ||
| } else { | ||
| out_size = ZX7GetDecompressedSize((unsigned char *)input_data.data()); | ||
| out_data = (unsigned char *)malloc(out_size); | ||
| if (out_data == NULL) | ||
| throw std::runtime_error("Could not allocate output memory."); | ||
|
|
||
| ZX7Decompress((unsigned char *)input_data.data(), out_data, out_size); | ||
| } | ||
|
|
||
| if (files.size() == 1) { | ||
| std::cout << out_data; | ||
| } else { | ||
| std::ofstream output_file(files[1], std::ios::binary); | ||
|
|
||
| output_file.write((char *)out_data, out_size); | ||
| } | ||
| } catch (const char *err) { | ||
| if (strcmp(err, "--help") != 0) | ||
| std::cout << "Error: " << err << "." << std::endl; | ||
|
|
||
| printHelp(); | ||
| } | ||
|
|
||
| // std::ifstream compress_file; | ||
|
|
||
| // if (argc == 0) | ||
|
|
||
| // compress_file.open() | ||
|
|
||
| // char buff[] | ||
|
|
||
| // compress_file = fopen("") | ||
|
|
||
| // const char *srcData = "Bonjour, j'mappel docteur cahlos!"; | ||
| // unsigned char *outData; | ||
| // int compressedSize = ZX7Compress((const unsigned char *)srcData, | ||
| // strlen(srcData) + 1, &outData); | ||
|
|
||
| // for (int i = 0; i < compressedSize; i++) { | ||
| // printf("%d,", outData[i]); | ||
|
|
||
| // if (i % 64 == 63) | ||
| // printf("\n\t"); | ||
| // } | ||
|
|
||
| // unsigned char destData[compressedSize]; | ||
| // ZX7Decompress(outData, destData, compressedSize); | ||
|
|
||
| // printf("\n%s\n", destData); | ||
|
|
||
| // return 0; | ||
| return 0; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| /* | ||
| * (c) Copyright 2012 by 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 <COPYRIGHT HOLDER> 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. | ||
| */ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,114 @@ | ||
| #--------------------------------------------------------------------------------- | ||
| # Clear the implicit built in rules | ||
| #--------------------------------------------------------------------------------- | ||
| .SUFFIXES: | ||
|
|
||
| ifeq ($(strip $(FXCGSDK)),) | ||
| export FXCGSDK := $(realpath ../../) | ||
| endif | ||
|
|
||
| include $(FXCGSDK)/toolchain/prizm_rules | ||
|
|
||
|
|
||
| #--------------------------------------------------------------------------------- | ||
| # TARGET is the name of the output | ||
| # BUILD is the directory where object files & intermediate files will be placed | ||
| # SOURCES is a list of directories containing source code | ||
| # INCLUDES is a list of directories containing extra header files | ||
| #--------------------------------------------------------------------------------- | ||
| TARGET := $(notdir $(CURDIR)) | ||
| BUILD := build | ||
| SOURCES := src | ||
| INCLUDES := | ||
|
|
||
| #--------------------------------------------------------------------------------- | ||
| # options for code and library generation | ||
| #--------------------------------------------------------------------------------- | ||
|
|
||
| CFLAGS = -Os \ | ||
| -Wall \ | ||
| -funroll-loops \ | ||
| -fno-trapping-math \ | ||
| -fno-trapv \ | ||
| -Wno-switch \ | ||
| $(MACHDEP) $(INCLUDE) $(DEFINES) | ||
|
|
||
| CXXFLAGS = $(CFLAGS) \ | ||
| -fpermissive \ | ||
| -fno-rtti \ | ||
| -fno-exceptions \ | ||
| -fno-threadsafe-statics \ | ||
| -fno-use-cxa-get-exception-ptr | ||
|
|
||
| ASFLAGS = $(CFLAGS) | ||
|
|
||
| LDFLAGS = $(MACHDEP) -O2 -T$(FXCGSDK)/toolchain/prizm.x -Wl,-static -Wl,-gc-sections | ||
|
|
||
| #--------------------------------------------------------------------------------- | ||
| # list of directories containing libraries, this must be the top level containing | ||
| # include and lib | ||
| #--------------------------------------------------------------------------------- | ||
| LIBDIRS := | ||
|
|
||
| ifneq ($(BUILD),$(notdir $(CURDIR))) | ||
|
|
||
| export OUTPUT := $(CURDIR)/../../lib/lib$(TARGET) | ||
| export DEPSDIR := $(CURDIR)/$(BUILD) | ||
|
|
||
| #--------------------------------------------------------------------------------- | ||
| # automatically build a list of object files for our project | ||
| #--------------------------------------------------------------------------------- | ||
| CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) | ||
| CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) | ||
| SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S))) | ||
|
|
||
| #--------------------------------------------------------------------------------- | ||
| # use CXX for linking C++ projects, CC for standard C | ||
| #--------------------------------------------------------------------------------- | ||
| ifeq ($(strip $(CPPFILES)),) | ||
| export LD := $(CC) | ||
| else | ||
| export LD := $(CXX) | ||
| endif | ||
|
|
||
| #--------------------------------------------------------------------------------- | ||
| # build a list of include paths | ||
| #--------------------------------------------------------------------------------- | ||
| export INCLUDE := $(foreach dir,$(INCLUDES), -iquote $(CURDIR)/$(dir)) \ | ||
| $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ | ||
| -I$(CURDIR)/$(BUILD) -I$(LIBFXCG_INC) -I$(CURDIR) | ||
|
|
||
| export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) | ||
|
|
||
| export OFILES := $(addsuffix .o,$(BINFILES)) \ | ||
| $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \ | ||
| $(SFILES:.S=.o) | ||
| .PHONY: $(BUILD) clean | ||
|
|
||
| #--------------------------------------------------------------------------------- | ||
| all: $(BUILD) | ||
| @make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile | ||
|
|
||
| $(BUILD): | ||
| @[ -d $@ ] || mkdir $@ | ||
|
|
||
| #--------------------------------------------------------------------------------- | ||
| export CYGWIN := nodosfilewarning | ||
| clean: | ||
| $(RM) -fr $(BUILD) $(OUTPUT).a $(OFILES) | ||
|
|
||
| #--------------------------------------------------------------------------------- | ||
| else | ||
|
|
||
| DEPENDS := $(OFILES:.o=.d) | ||
|
|
||
| #--------------------------------------------------------------------------------- | ||
| # main targets | ||
| #--------------------------------------------------------------------------------- | ||
| $(OUTPUT).a: $(OFILES) | ||
|
|
||
| -include $(DEPENDS) | ||
|
|
||
| #--------------------------------------------------------------------------------- | ||
| endif | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| # zx7 utility | ||
|
|
||
| zx7 implementation by Einar Saukas allows for low impact decompression routines with very thorough offline compression. See the unmodified zx7.txt for more information. | ||
|
|
||
| Use the compress routine in an offline tool to generate your data, and then decompress it on Prizm devices by using the ZX7Decompress function. | ||
|
|
||
| Link to libzx7 by using -lzx7 in your project makefile, and include zx7/zx7.h to use. | ||
|
|
||
| The CLI folder contains the source and Makefile for a CLI app to compress and decompress files with zx7. |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this the only product of this utility? I'd really like it to be more integrated, since right now it's just a library that the user can link which can just as easily be vendored into their own program- there's no reason for it to live here.
I'd consider the ability for a user to select resources to compress (automatically building and running the compressor as needed) and then linking the decompressor into a program to be much more useful than simply spitting out a library archive.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure!
I've built a tool (in utils/zx7/CLI) which can compress and decompress files with zx7.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a start, but doesn't address the concept of having actual integration with the tools. Right now there's really no reason to offer this library with the toolchain versus encouraging users to include the decompressor in their project, because this doesn't solve any of the hard problems involved in packaging compressed resources into a binary.
What I really want this to be able to do is for the user to load some rules we provide, and then the library handles compressing specified resource files, embedding the data in the output binary, and possibly generating a header file describing the compressed resources.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, okay. I'll work on it, but it'll be a while.