diff --git a/libzpaq/libzpaq.h b/libzpaq/libzpaq.h index e7879b4..e09a616 100644 --- a/libzpaq/libzpaq.h +++ b/libzpaq/libzpaq.h @@ -438,4 +438,35 @@ void compress(Reader* in, Writer* out, int level); } // namespace libzpaq +typedef unsigned char uchar; + +struct bufRead: public libzpaq::Reader { + uchar *s_buf; + long long *s_len; + bufRead(uchar *buf_, long long *n_): s_buf(buf_), s_len(n_) {} + int get() { + if (*s_len > 0) { + (*s_len)--; + return ((int)(uchar)*s_buf++); + } + return -1; + } // read and return byte 0..255, or -1 at EOF +}; + +struct bufWrite: public libzpaq::Writer { + uchar *c_buf; + long long *c_len; + bufWrite(uchar *buf_, long long *n_): c_buf(buf_), c_len(n_) {} + void put(int c) { + c_buf[(*c_len)++] = (uchar)c; + } +}; + +extern "C" void zpaq_compress(uchar *c_buf, long long *c_len, uchar *s_buf, long long s_len, int level) { + bufRead bufR(s_buf, &s_len); + bufWrite bufW(c_buf, c_len); + + compress (&bufR, &bufW, level); +} + #endif // LIBZPAQ_H diff --git a/lrzip.h b/lrzip.h index b1631da..d4bf99f 100644 --- a/lrzip.h +++ b/lrzip.h @@ -42,4 +42,5 @@ void clear_tmpinbuf(rzip_control *control); bool clear_tmpinfile(rzip_control *control); void close_tmpinbuf(rzip_control *control); bool initialize_control(rzip_control *control); +extern void zpaq_compress(uchar *c_buf, long long *c_len, uchar *s_buf, long long s_len, int level); #endif diff --git a/stream.c b/stream.c index c896418..61962c5 100644 --- a/stream.c +++ b/stream.c @@ -239,6 +239,35 @@ static inline int fake_open_memstream_update_buffer(FILE *fp, uchar **buf, size_ length in c_len */ +static int zpaq_compress_buf(rzip_control *control, struct compress_thread *cthread, long thread) +{ + i64 c_len = 0; + uchar *c_buf; + + c_buf = malloc(cthread->s_len + control->page_size); + if (!c_buf) { + print_err("Unable to allocate c_buf in zpaq_compress_buf\n"); + return -1; + } + + zpaq_compress(c_buf, &c_len, cthread->s_buf, cthread->s_len, control->compression_level / 4 + 1); + + if (unlikely(c_len >= cthread->c_len)) { + print_maxverbose("Incompressible block\n"); + /* Incompressible, leave as CTYPE_NONE */ + free(c_buf); + return 0; + } + + cthread->c_len = c_len; + free(cthread->s_buf); + cthread->s_buf = c_buf; + cthread->c_type = CTYPE_ZPAQ; + return 0; +} + + +#if 0 static int zpaq_compress_buf(rzip_control *control, struct compress_thread *cthread, long thread) { uchar *c_buf = NULL; @@ -285,6 +314,7 @@ static int zpaq_compress_buf(rzip_control *control, struct compress_thread *cthr cthread->c_type = CTYPE_ZPAQ; return 0; } +#endif static int bzip2_compress_buf(rzip_control *control, struct compress_thread *cthread) {