mirror of
https://github.com/pfusik/zlib6502.git
synced 2024-12-01 06:49:25 +00:00
zopfli beats the other compression methods.
This commit is contained in:
parent
5d41b9a647
commit
3faede80c3
12
Makefile
12
Makefile
@ -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:
|
||||
|
29
README.md
29
README.md
@ -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
|
||||
-------
|
||||
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user