zopfli beats the other compression methods.

This commit is contained in:
Piotr Fusik 2017-02-12 19:40:36 +01:00
parent 5d41b9a647
commit 3faede80c3
4 changed files with 13 additions and 188 deletions

View File

@ -1,17 +1,9 @@
all: inflate.obx gzip2deflate zip2deflate
inflate.obx: inflate.asx
xasm -d inflate=\$$b700 -d inflate_data=\$$b900 -d inflate_zp=\$$f0 inflate.asx
%: %.c
gcc -s -O2 -Wall -o $@ $<
2deflate.zip: gzip2deflate zip2deflate
rm -f $@ && 7z a -mx=9 -tzip $@ gzip2deflate.exe zip2deflate.exe
clean:
rm -f inflate.obx gzip2deflate zip2deflate 2deflate.zip gzip2deflate.exe zip2deflate.exe
rm -f inflate.obx
.PHONY: all clean
.PHONY: clean
.DELETE_ON_ERROR:

View File

@ -63,27 +63,21 @@ Compression
-----------
There are several ways to get DEFLATE compressed data.
Originally I wrote a command-line utility called `deflater`
which used the standard [zlib library](http://www.zlib.net/).
However, better compression can be obtained with [7-Zip](http://7-zip.org/).
It supports the gzip format which is a thin layer on top of DEFLATE.
My program `gzip2deflate` extracts the DEFLATE stream from a gzip file.
It reads gzip on its standard input and writes DEFLATE to its standard output.
I recommend using it this way:
7z a -tgzip -mx=9 -so dummy INPUT_FILE | gzip2deflate >OUTPUT_FILE.dfl
If you are looking for maximum compression, use [Zopfli](https://github.com/google/zopfli).
For example:
If you don't have 7-Zip, use:
zopfli --deflate INPUT_FILE
gzip -c -9 INPUT_FILE | gzip2deflate >OUTPUT_FILE.dfl
will compress to `INPUT_FILE.deflate`.
I have compiled a [Windows exe](http://pfusik.github.io/zlib6502/zopfli.exe.gz) for you.
If you are looking for maximum compression, [KZIP](http://advsys.net/ken/utils.htm)
is also worth a try. It creates ZIP files, so I wrote `zip2deflate` to extract
DEFLATE data from a ZIP.
Historically, I have used:
Windows binaries of `gzip2deflate` and `zip2deflate` are
[available for download](http://pfusik.github.io/zlib6502/2deflate.zip).
For other platforms, you will need to compile these programs yourself.
* my programs using the [Deflater](http://docs.oracle.com/javase/8/docs/api/java/util/zip/Deflater.html) Java class
* my `deflater` program written with the [zlib library](http://www.zlib.net/).
* my `gzip2deflate` program that extracted the DEFLATE stream from a GZ file created with gzip or [7-Zip](http://7-zip.org/)
* my `zip2deflate` program that extracted the DEFLATE stream from a ZIP created with [KZIP](http://advsys.net/ken/utils.htm)
zlib?
-----
@ -92,8 +86,7 @@ This project is named zlib6502, but only supports DEFLATE decompression.
Someday I'm going to include more functions, including compression.
Meanwhile, you may look at [cc65](https://github.com/cc65/cc65) `zlib.h`.
This is my old code, which includes an old version of `inflate`
plus zlib-compatible `uncompress`, `adler32` and `crc32`.
In addition to `inflate`, it supports zlib-compatible `uncompress`, `adler32` and `crc32`.
License
-------

View File

@ -1,78 +0,0 @@
// gzip2deflate by Piotr Fusik <fox@scene.pl>
// http://xasm.atari.org
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef __WIN32
#include <fcntl.h>
#endif
static int get_byte(void)
{
int b = getchar();
if (b == EOF) {
fputs("gzip2deflate: unexpected end of stream\n", stderr);
exit(1);
}
return b;
}
static void skip_bytes(int n)
{
while (--n >= 0)
get_byte();
}
static void skip_string(void)
{
while (get_byte() != 0);
}
int main (int argc, char *argv[])
{
int flg;
char buf[8 + 4096];
size_t len;
#ifdef __WIN32
_setmode(_fileno(stdin), _O_BINARY);
_setmode(_fileno(stdout), _O_BINARY);
#endif
if (get_byte() != 0x1f || get_byte() != 0x8b || get_byte() != 8) {
fputs("gzip2deflate: not a gzip file on stdin\n", stderr);
return 1;
}
flg = get_byte();
skip_bytes(6);
if ((flg & 4) != 0) {
int xlen = get_byte();
xlen += get_byte() << 8;
skip_bytes(xlen);
}
if ((flg & 8) != 0)
skip_string();
if ((flg & 16) != 0)
skip_string();
if ((flg & 2) != 0)
skip_bytes(2);
/* copy everything except the last 8 bytes */
len = 0;
for (;;) {
len += fread(buf + len, 1, sizeof(buf) - len, stdin);
if (len != sizeof(buf))
break;
fwrite(buf, 1, sizeof(buf) - 8, stdout);
memcpy(buf, buf + sizeof(buf) - 8, 8);
len = 8;
}
if (ferror(stdin)) {
fputs("gzip2deflate: read error\n", stderr);
return 1;
}
if (len < 8) {
fputs("gzip2deflate: unexpected end of stream\n", stderr);
return 1;
}
fwrite(buf, 1, len - 8, stdout);
return 0;
}

View File

@ -1,82 +0,0 @@
// zip2deflate by Piotr Fusik <fox@scene.pl>
// http://xasm.atari.org
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _WIN32
#include <fcntl.h>
#endif
static int get_byte(void)
{
int b = getchar();
if (b == EOF) {
fputs("zip2deflate: unexpected end of stream\n", stderr);
exit(1);
}
return b;
}
static void skip_bytes(size_t n)
{
for (; n > 0; n--)
get_byte();
}
static size_t get_word(void)
{
size_t lo = get_byte();
return lo + (get_byte() << 8);
}
static size_t get_long(void)
{
size_t lo = get_word();
return lo + (get_word() << 16);
}
int main (int argc, char *argv[])
{
size_t compressed_size;
size_t filename_length;
size_t extra_field_length;
#ifdef _WIN32
_setmode(_fileno(stdin), _O_BINARY);
_setmode(_fileno(stdout), _O_BINARY);
#endif
if (get_long() != 0x04034b50) {
fputs("zip2deflate: not a ZIP file on stdin\n", stderr);
return 1;
}
if (get_word() != 20 /* version needed to extract */
|| (get_word() & 0x41) != 0 /* general purpose bit flag */
|| get_word() != 8 /* compression method */
) {
fputs("zip2deflate: unexpected header (not compressed? encrypted?)\n", stderr);
return 1;
}
skip_bytes(8); /* last mod file time, date, crc-32 */
compressed_size = get_long();
skip_bytes(4); /* uncompressed size */
filename_length = get_word();
extra_field_length = get_word();
skip_bytes(filename_length + extra_field_length);
while (compressed_size > 0) {
char buf[4096];
size_t len = compressed_size < 4096 ? compressed_size : 4096;
len = fread(buf, 1, len, stdin);
if (len == 0) {
fputs("zip2deflate: unexpected end of stream\n", stderr);
return 1;
}
fwrite(buf, 1, len, stdout);
compressed_size -= len;
}
if (get_long() != 0x02014b50) {
fputs("zip2deflate: unexpected header (more than one file?)\n", stderr);
return 1;
}
return 0;
}