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 inflate.obx: inflate.asx
xasm -d inflate=\$$b700 -d inflate_data=\$$b900 -d inflate_zp=\$$f0 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: 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: .DELETE_ON_ERROR:

View File

@ -63,27 +63,21 @@ Compression
----------- -----------
There are several ways to get DEFLATE compressed data. 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) Historically, I have used:
is also worth a try. It creates ZIP files, so I wrote `zip2deflate` to extract
DEFLATE data from a ZIP.
Windows binaries of `gzip2deflate` and `zip2deflate` are * my programs using the [Deflater](http://docs.oracle.com/javase/8/docs/api/java/util/zip/Deflater.html) Java class
[available for download](http://pfusik.github.io/zlib6502/2deflate.zip). * my `deflater` program written with the [zlib library](http://www.zlib.net/).
For other platforms, you will need to compile these programs yourself. * 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? 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. Someday I'm going to include more functions, including compression.
Meanwhile, you may look at [cc65](https://github.com/cc65/cc65) `zlib.h`. 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` In addition to `inflate`, it supports zlib-compatible `uncompress`, `adler32` and `crc32`.
plus zlib-compatible `uncompress`, `adler32` and `crc32`.
License 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;
}