Added test script; tidied and documented

The test script combines the sources then builds and runs an example. A futher example is built if the Emscripten compiler is available on the system. Documentation covers building.
This commit is contained in:
Carl Woffenden 2019-08-27 15:36:06 +02:00
parent 7c6fa81579
commit a57de4ac89
7 changed files with 94 additions and 23 deletions

View File

@ -1,8 +1,12 @@
# Single File Zstandard Decompression Library
Create the file using the shell script:
The script `combine.sh` creates an _amalgamted_ source file that can be used with out without `zstd.h`. This isn't a _header-only_ file but it does offer a similar level of simplicity when integrating into a project.
Create `zstddeclib.c` from the Zstd source using:
```
cd zstd/contrib/declib
./combine.sh -r ../../lib -r ../../lib/common -r ../../lib/decompress -o zstddeclib.c zstddeclib-in.c
```
Then add the resulting file to your project (see the [test sources](tests) for examples).
Then add the resulting file to your project (see the [example files](examples)).
`build.sh` will run the above script then compile and test the resulting library.

57
contrib/declib/build.sh Executable file
View File

@ -0,0 +1,57 @@
#!/bin/bash
# Where to find the sources
ZSTD_SRC_ROOT="../../lib"
# Temporary compiled binary
OUT_FILE="tempbin"
# Optional temporary compiled WebAssembly
OUT_WASM="temp.wasm"
# Amalgamate the sources
./combine.sh -r "$ZSTD_SRC_ROOT" -r "$ZSTD_SRC_ROOT/common" -r "$ZSTD_SRC_ROOT/decompress" -o zstddeclib.c zstddeclib-in.c
# Did combining work?
if [ $? -ne 0 ]; then
echo "Combine script: FAILED"
exit 1
fi
echo "Combine script: PASSED"
# Compile the generated output
cc -Os -g0 -o $OUT_FILE examples/simple.c
# Did compilation work?
if [ $? -ne 0 ]; then
echo "Compiling simple.c: FAILED"
exit 1
fi
echo "Compiling simple.c: PASSED"
# Run then delete the compiled output
./$OUT_FILE
retVal=$?
rm -f $OUT_FILE
# Did the test work?
if [ $retVal -ne 0 ]; then
echo "Running simple.c: FAILED"
exit 1
fi
echo "Running simple.c: PASSED"
# Is Emscripten available?
which emcc > /dev/null
if [ $? -ne 0 ]; then
echo "(Skipping Emscripten test)"
fi
# Compile the Emscripten example
CC_FLAGS="-Wall -Wextra -Os -g0 -flto --llvm-lto 3 -lGL -DNDEBUG=1"
emcc $CC_FLAGS -s WASM=1 -o $OUT_WASM examples/emscripten.c
# Did compilation work?
if [ $? -ne 0 ]; then
echo "Compiling emscripten.c: FAILED"
exit 1
fi
echo "Compiling emscripten.c: PASSED"
rm -f $OUT_WASM
exit 0

View File

@ -0,0 +1,7 @@
# Single File ZStandard Examples
The examples `#include` the generated `zstddeclib.c` directly but work equally as well when including `zstd.h` and compiling the amalgamated source separately.
`simple.c` is the most basic example of decompressing content and verifying the result.
`emscripten.c` is a bare-bones [Emscripten](https://github.com/emscripten-core/emscripten) compiled WebGL demo using Zstd to further compress a DXT1 texture. The 256x256 texture would normally be 32kB, but even when bundled with the Zstd decompressor the resulting WebAssembly weighs in at 45kB.

View File

@ -6,7 +6,9 @@
* \n
* Compile using:
* \code
* emcc -Wall -Wextra -Os -g0 -lGL -s WASM=1 -o out.html emscripten.c
* export CC_FLAGS="-Wall -Wextra -Os -g0 -flto --llvm-lto 3 -lGL -DNDEBUG=1"
* export EM_FLAGS="-s WASM=1 -s ENVIRONMENT=web --shell-file shell.html --closure 1"
* emcc $CC_FLAGS $EM_FLAGS -o out.html emscripten.c
* \endcode
*/
@ -27,6 +29,8 @@
/**
* Zstd compressed DXT1 256x256 texture source.
*
* File credit: https://commons.wikimedia.org/wiki/File:FuBK-Testbild.png
*/
static uint8_t const srcZstd[] = {
0x28, 0xb5, 0x2f, 0xfd, 0x60, 0x00, 0x7f, 0xfd, 0xe2, 0x00, 0x8a, 0x05,
@ -682,11 +686,6 @@ static GLuint fragId = 0;
*/
static GLint uRotId = -1;
/**
* Draw colour ID.
*/
static GLint uColId = -1;
/**
* Draw colour ID.
*/
@ -774,15 +773,10 @@ static GLuint compileShader(GLenum const type, const GLchar* text) {
*/
#define GL_VERT_POSXY_ID 0
/**
* Vertex colour index.
*/
#define GL_VERT_COLOR_ID 1
/**
* Vertex UV0 index.
*/
#define GL_VERT_TXUV0_ID 2
#define GL_VERT_TXUV0_ID 1
/**
* \c GL vec2 storage type.
@ -871,7 +865,7 @@ static void tick() {
* and 'uploads' the resulting texture.
*
* As a (naive) comparison, removing Zstd and building with "-Os -g0 s WASM=1
* -lGL emscripten.c" results in a 23kB WebAssembly file; re-adding Zstd
* -lGL emscripten.c" results in a 19kB WebAssembly file; re-adding Zstd
* increases the Wasm by 25kB.
*/
int main() {
@ -882,7 +876,6 @@ int main() {
fragId = compileShader(GL_FRAGMENT_SHADER, fragShader2D);
glBindAttribLocation(progId, GL_VERT_POSXY_ID, "aPos");
glBindAttribLocation(progId, GL_VERT_COLOR_ID, "aCol");
glBindAttribLocation(progId, GL_VERT_TXUV0_ID, "aUV0");
glAttachShader(progId, vertId);
@ -890,7 +883,6 @@ int main() {
glLinkProgram (progId);
glUseProgram (progId);
uRotId = glGetUniformLocation(progId, "uRot");
uColId = glGetUniformLocation(progId, "uCol");
uTx0Id = glGetUniformLocation(progId, "uTx0");
if (uTx0Id >= 0) {
glUniform1i(uTx0Id, 0);

View File

@ -12,7 +12,7 @@ body {background:#333; font-family:"Verdana","Helvetica Neue","Helvetica","Ari
</style>
</head>
<body>
<canvas class="game" id="canvas" oncontextmenu="event.preventDefault()"></canvas>
<canvas id="canvas" oncontextmenu="event.preventDefault()"></canvas>
<script>
function trace(msg) {
console.log(msg);

View File

@ -1,6 +1,11 @@
/**
* \file simple.c
* Simple standalone example of using the single-file \c zstddeclib.
*
* \note In this simple example we include the amalgamated source and compile
* just this single file, but we could equally (and more conventionally)
* include \c zstd.h and compile both this file and \c zstddeclib.c (the
* resulting binaries differ slightly in size but perform the same).
*/
#include <stddef.h>
@ -14,6 +19,8 @@
/**
* Raw 256x256 DXT1 data (used to compare the result).
*
* File credit: https://commons.wikimedia.org/wiki/File:FuBK-Testbild.png
*/
static uint8_t const rawDxt1[] = {
0x3c, 0xe7, 0xc7, 0x39, 0x25, 0x25, 0x25, 0x00, 0x28, 0x42, 0xba, 0xd6,
@ -2751,6 +2758,8 @@ static uint8_t const rawDxt1[] = {
/**
* Zstd compressed version of \c #rawDxt1.
*
* File credit: https://commons.wikimedia.org/wiki/File:FuBK-Testbild.png
*/
static uint8_t const srcZstd[] = {
0x28, 0xb5, 0x2f, 0xfd, 0x60, 0x00, 0x7f, 0xfd, 0xe2, 0x00, 0x8a, 0x05,
@ -3373,7 +3382,7 @@ static uint8_t dstDxt1[sizeof rawDxt1] = {};
* dummy function to fake the process and stop the buffers being optimised out.
*/
size_t ZSTD_decompress(void* dst, size_t dstLen, const void* src, size_t srcLen) {
return (memcmp(dst, src, (srcLen < dstLen) ? srcLen : dstLen)) ? dstLen : 0;
return (memcmp(dst, src, (srcLen < dstLen) ? srcLen : dstLen)) ? 0 : dstLen;
}
#endif
@ -3385,13 +3394,13 @@ size_t ZSTD_decompress(void* dst, size_t dstLen, const void* src, size_t srcLen)
* \n
* As a (naive) comparison, removing Zstd and building with "-Os -g0 simple.c"
* results in a 48kB binary (macOS 10.14, Clang 10); re-adding Zstd increases
* the binary by 74kB.
* the binary by 67kB (after calling \c strip).
*/
int main() {
size_t size = ZSTD_decompress(dstDxt1, sizeof dstDxt1, srcZstd, sizeof srcZstd);
int compare = memcmp(rawDxt1, dstDxt1, sizeof dstDxt1);
printf("Decompressed size: %s\n", (size == sizeof dstDxt1) ? "OK" : "FAILED");
printf("Byte comparison: %s\n", (compare == 0) ? "OK" : "FAILED");
printf("Decompressed size: %s\n", (size == sizeof dstDxt1) ? "PASSED" : "FAILED");
printf("Byte comparison: %s\n", (compare == 0) ? "PASSED" : "FAILED");
if (size == sizeof dstDxt1 && compare == 0) {
return EXIT_SUCCESS;
}

View File

@ -42,6 +42,9 @@
*/
/*
* Settings to bake for the standalone decompressor.
*
* Note: It's important that none of these affects 'zstd.h' (only the
* implementation files we're amalgamating).
*/
#define DEBUGLEVEL 0
#define XXH_NAMESPACE ZSTD_
@ -51,7 +54,6 @@
#define ZSTD_LIB_COMPRESSION 0
#define ZSTD_LIB_DEPRECATED 0
#define ZSTD_NOBENCH
#define ZSTD_STATIC_LINKING_ONLY
#define ZSTD_STRIP_ERROR_STRINGS
#include "debug.c"