summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2013-07-25 10:37:23 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2013-08-07 08:44:48 +0200
commit50e8902c0ef0154c707377238473b4d917507e4b (patch)
tree369606d0bc7bc2b2634b350f4f8fae77cf705c3c /lib
parentbbaa8f1bb6056b29152ae8121d643125dbd4bcdf (diff)
downloadbarebox-50e8902c0ef0154c707377238473b4d917507e4b.tar.gz
barebox-50e8902c0ef0154c707377238473b4d917507e4b.tar.xz
Add deflate_decompress function
Needed to implement decompressors for gzip without headers. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'lib')
-rw-r--r--lib/decompress_inflate.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/lib/decompress_inflate.c b/lib/decompress_inflate.c
index 5c1ebb6850..d5ea01ad56 100644
--- a/lib/decompress_inflate.c
+++ b/lib/decompress_inflate.c
@@ -183,4 +183,43 @@ gunzip_nomem1:
return rc; /* returns Z_OK (0) if successful */
}
+int deflate_decompress(struct z_stream_s *stream, const u8 *src, unsigned int slen, u8 *dst,
+ unsigned int *dlen)
+{
+
+ int ret = 0;
+
+ ret = zlib_inflateReset(stream);
+ if (ret != Z_OK) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ stream->next_in = (u8 *)src;
+ stream->avail_in = slen;
+ stream->next_out = (u8 *)dst;
+ stream->avail_out = *dlen;
+
+ ret = zlib_inflate(stream, Z_SYNC_FLUSH);
+ /*
+ * Work around a bug in zlib, which sometimes wants to taste an extra
+ * byte when being used in the (undocumented) raw deflate mode.
+ * (From USAGI).
+ */
+ if (ret == Z_OK && !stream->avail_in && stream->avail_out) {
+ u8 zerostuff = 0;
+ stream->next_in = &zerostuff;
+ stream->avail_in = 1;
+ ret = zlib_inflate(stream, Z_FINISH);
+ }
+ if (ret != Z_STREAM_END) {
+ ret = -EINVAL;
+ goto out;
+ }
+ ret = 0;
+ *dlen = stream->total_out;
+out:
+ return ret;
+}
+
#define decompress gunzip