lib: Add decompression function
Add decompression function to decompress gzip package by using
zlib APIs. Modification for Zlib success compile in LK.
Change-Id: Ibc840fbc1094c0126ddc13d6422d06f5e196be7a
diff --git a/lib/zlib_inflate/decompress.c b/lib/zlib_inflate/decompress.c
new file mode 100644
index 0000000..692ccfa
--- /dev/null
+++ b/lib/zlib_inflate/decompress.c
@@ -0,0 +1,157 @@
+/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define NO_GZIP
+
+#include "zutil.h"
+
+#ifdef DYNAMIC_CRC_TABLE
+#include "crc32.h"
+#endif
+
+#include "zconf.h"
+#include "zlib.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+#include "decompress.h"
+#include <sys/types.h> /* for size_t */
+#include <string.h>
+#include <debug.h>
+#include <malloc.h>
+
+#define GZIP_HEADER_LEN 10
+#define GZIP_FILENAME_LIMIT 256
+
+static void zlib_free(voidpf qpaque, void *addr)
+{
+ return free(addr);
+}
+
+static void *zlib_alloc(voidpf qpaque, uInt items, size_t size)
+{
+ return malloc(items * size);
+}
+
+/* decompress gzip file "in_buf", return 0 if decompressed successful,
+ * return -1 if decompressed failed.
+ * in_buf - input gzip file
+ * in_len - input the length file
+ * out_buf - output the decompressed data
+ * out_buf_len - the available length of out_buf
+ * pos - position of the end of gzip file
+ * out_len - the length of decompressed data
+ */
+int decompress(unsigned char *in_buf, unsigned int in_len,
+ unsigned char *out_buf,
+ unsigned int out_buf_len,
+ unsigned int *pos,
+ unsigned int *out_len) {
+ struct z_stream_s *stream;
+ int rc = -1;
+ int i;
+
+ if (in_len < GZIP_HEADER_LEN) {
+ dprintf(INFO, "the input data is not a gzip package.\n");
+ return rc;
+ }
+ if (out_buf_len < in_len) {
+ dprintf(INFO, "the avaiable length of out_buf is not enough.\n");
+ return rc;
+ }
+
+ stream = malloc(sizeof(*stream));
+ if (stream == NULL) {
+ dprintf(INFO, "allocating z_stream failed.\n");
+ return rc;
+ }
+
+ stream->zalloc = zlib_alloc;
+ stream->zfree = zlib_free;
+ stream->next_out = out_buf;
+ stream->avail_out = out_buf_len;
+
+ /* skip over gzip header */
+ stream->next_in = in_buf + GZIP_HEADER_LEN;
+ stream->avail_in = out_buf_len - GZIP_HEADER_LEN;
+ /* skip over asciz filename */
+ if (in_buf[3] & 0x8) {
+ for (i = 0; i < GZIP_FILENAME_LIMIT && *stream->next_in++; i++) {
+ if (stream->avail_in == 0) {
+ dprintf(INFO, "header error");
+ goto gunzip_end;
+ }
+ --stream->avail_in;
+ }
+ }
+
+ rc = inflateInit2(stream, -MAX_WBITS);
+
+ if (rc == Z_OK) {
+ if (stream->avail_in == 0) {
+ stream->next_in = in_buf;
+ stream->avail_in = out_buf_len;
+ }
+ rc = inflate(stream, 0);
+
+ /* Z_STREAM_END is "we unpacked it all" */
+ if (rc == Z_STREAM_END) {
+ rc = 0;
+ } else if (rc != Z_OK) {
+ dprintf(INFO, "uncompression error");
+ rc = -1;
+ }
+ }
+
+ inflateEnd(stream);
+ if (pos)
+ /* alculation the length of the compressed package */
+ *pos = stream->next_in - in_buf + 8;
+
+ if (out_len)
+ *out_len = stream->total_out;
+
+gunzip_end:
+ free(stream);
+ return rc; /* returns 0 if decompressed successful */
+}
+
+/* check if the input "buf" file was a gzip package.
+ * Return true if the input "buf" is a gzip package.
+ */
+int is_gzip_package(unsigned char *buf, unsigned int len)
+{
+ if (len < 10 || !buf || buf[0] != 0x1f ||
+ buf[1] != 0x8b || buf[2] != 0x08)
+ {
+ dprintf(INFO, "Not a gzip file\n");
+ return false;
+ }
+
+ return true;
+}
diff --git a/lib/zlib_inflate/decompress.h b/lib/zlib_inflate/decompress.h
new file mode 100644
index 0000000..1cdd011
--- /dev/null
+++ b/lib/zlib_inflate/decompress.h
@@ -0,0 +1,35 @@
+/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __PLATFORM_MSM_SHARED_DECOMPRESS_H
+#define __PLATFORM_MSM_SHARED_DECOMPRESS_H
+
+int is_gzip_package(unsigned char *, unsigned int);
+
+int decompress(unsigned char *, unsigned int, unsigned char *, unsigned int, unsigned int *, unsigned int *);
+#endif /* __PLATFORM_MSM_SHARED_DECOMPRESS_H */
diff --git a/lib/zlib_inflate/inflate.c b/lib/zlib_inflate/inflate.c
index 870f89b..e341300 100644
--- a/lib/zlib_inflate/inflate.c
+++ b/lib/zlib_inflate/inflate.c
@@ -80,6 +80,8 @@
* The history for versions after 1.2.0 are in ChangeLog in zlib distribution.
*/
+#define NO_GZIP
+
#include "zutil.h"
#include "inftrees.h"
#include "inflate.h"
diff --git a/lib/zlib_inflate/rules.mk b/lib/zlib_inflate/rules.mk
new file mode 100755
index 0000000..96d2383
--- /dev/null
+++ b/lib/zlib_inflate/rules.mk
@@ -0,0 +1,9 @@
+LOCAL_DIR := $(GET_LOCAL_DIR)
+
+OBJS += \
+ $(LOCAL_DIR)/zutil.o \
+ $(LOCAL_DIR)/adler32.o \
+ $(LOCAL_DIR)/inftrees.o \
+ $(LOCAL_DIR)/inflate.o \
+ $(LOCAL_DIR)/inffast.o \
+ $(LOCAL_DIR)/decompress.o
diff --git a/lib/zlib_inflate/zlib.h b/lib/zlib_inflate/zlib.h
index 3e0c767..8da7aa5 100644
--- a/lib/zlib_inflate/zlib.h
+++ b/lib/zlib_inflate/zlib.h
@@ -1114,7 +1114,7 @@
7.6: size of z_off_t
Compiler, assembler, and debug options:
- 8: DEBUG
+ 8: DEBUG/ZLIB_DEBUG
9: ASMV or ASMINF -- use ASM code
10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention
11: 0 (reserved)
diff --git a/lib/zlib_inflate/zutil.c b/lib/zlib_inflate/zutil.c
index 23d2ebe..5f21a24 100644
--- a/lib/zlib_inflate/zutil.c
+++ b/lib/zlib_inflate/zutil.c
@@ -7,7 +7,8 @@
#include "zutil.h"
#ifndef Z_SOLO
-# include "gzguts.h"
+/* Comment because LK does not contain gzguts.h */
+// # include "gzguts.h"
#endif
#ifndef NO_DUMMY_DECL
@@ -61,7 +62,8 @@
case 8: flags += 2 << 6; break;
default: flags += 3 << 6;
}
-#ifdef DEBUG
+/* replace DEBUG with ZLIB_DEBUG since the former is already used in lk */
+#ifdef ZLIB_DEBUG
flags += 1 << 8;
#endif
#if defined(ASMV) || defined(ASMINF)
@@ -115,7 +117,7 @@
return flags;
}
-#ifdef DEBUG
+#ifdef ZLIB_DEBUG
# ifndef verbose
# define verbose 0
diff --git a/lib/zlib_inflate/zutil.h b/lib/zlib_inflate/zutil.h
index 24ab06b..4de61bb 100644
--- a/lib/zlib_inflate/zutil.h
+++ b/lib/zlib_inflate/zutil.h
@@ -216,7 +216,8 @@
#endif
/* Diagnostic functions */
-#ifdef DEBUG
+/* replace DEBUG with ZLIB_DEBUG since the former is already used in lk. */
+#ifdef ZLIB_DEBUG
# include <stdio.h>
extern int ZLIB_INTERNAL z_verbose;
extern void ZLIB_INTERNAL z_error OF((char *m));