@@ -39,6 +39,7 @@ enum compression_type
};
int compress_data(void *in_buf, size_t in_len, void *out_buf, size_t *out_len, int type, int lzo_percent);
+int decompress_data(void *in_buf, size_t in_len, void *out_buf, size_t *out_len, int type);
int init_compression(void);
void destroy_compression(void);
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2008 Nokia Corporation.
* Copyright (C) 2008 University of Szeged, Hungary
+ * Copyright (C) 2015 sigma star gmbh
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
@@ -18,6 +19,8 @@
* Authors: Artem Bityutskiy
* Adrian Hunter
* Zoltan Sogor
+ * Richard Weinberger
+ * David Gstir
*/
#include "ubifs_common.h"
@@ -81,6 +84,47 @@ static int zlib_deflate(void *in_buf, size_t in_len, void *out_buf,
return 0;
}
+static int zlib_inflate(void *in_buf, size_t in_len, void *out_buf,
+ size_t *out_len)
+{
+ z_stream strm;
+
+ strm.zalloc = NULL;
+ strm.zfree = NULL;
+
+ /*
+ * Match exactly the zlib parameters used by the Linux kernel crypto
+ * API.
+ */
+ if (inflateInit2(&strm, -DEFLATE_DEF_WINBITS)) {
+ errcnt += 1;
+ return -1;
+ }
+
+ strm.next_in = in_buf;
+ strm.avail_in = in_len;
+ strm.total_in = 0;
+
+ strm.next_out = out_buf;
+ strm.avail_out = *out_len;
+ strm.total_out = 0;
+
+ if (inflate(&strm, Z_FINISH) != Z_STREAM_END) {
+ inflateEnd(&strm);
+ errcnt += 1;
+ return -1;
+ }
+
+ if (inflateEnd(&strm) != Z_OK) {
+ errcnt += 1;
+ return -1;
+ }
+
+ *out_len = strm.total_out;
+
+ return 0;
+}
+
#ifndef WITHOUT_LZO
static int lzo_compress(void *in_buf, size_t in_len, void *out_buf,
size_t *out_len)
@@ -200,6 +244,39 @@ int compress_data(void *in_buf, size_t in_len, void *out_buf,
return type;
}
+int decompress_data(void *in_buf, size_t in_len, void *out_buf,
+ size_t *out_len, int type)
+{
+ int err = 0;
+
+ switch (type) {
+ case UBIFS_COMPR_NONE:
+ if (*out_len < in_len) {
+ err = -1;
+ goto out;
+ }
+ memcpy(out_buf, in_buf, in_len);
+ *out_len = in_len;
+ break;
+#ifndef WITHOUT_LZO
+ case UBIFS_COMPR_LZO:
+ err = lzo1x_decompress_safe(in_buf, in_len, (unsigned char *)out_buf, out_len, NULL);
+ err = (err == LZO_E_OK) ? 0 : -1;
+ break;
+#endif
+ case UBIFS_COMPR_ZLIB:
+ err = zlib_inflate(in_buf, in_len, out_buf, out_len);
+ break;
+ default:
+ errcnt += 1;
+ err = 1;
+ break;
+ }
+
+out:
+ return err;
+}
+
int init_compression(void)
{
#ifdef WITHOUT_LZO