common: Move bootm_decomp_image() to image.c (as image_decomp())

Upcoming patches want to add decompression to use cases that are no
longer directly related to booting. It makes sense to retain a single
decompression routine, but it should no longer be in bootm.c (which is
not compiled for all configurations). This patch moves
bootm_decomp_image() to image.c and renames it to image_decomp() in
preparation of those upcoming patches.

Signed-off-by: Julius Werner <jwerner@chromium.org>
Reviewed-by: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
[trini: Fix warning around handle_decomp_error being unused]
Signed-off-by: Tom Rini <trini@konsulko.com>
diff --git a/common/image.c b/common/image.c
index 9f9538f..4958831 100644
--- a/common/image.c
+++ b/common/image.c
@@ -32,6 +32,12 @@
 #include <linux/errno.h>
 #include <asm/io.h>
 
+#include <bzlib.h>
+#include <linux/lzo.h>
+#include <lzma/LzmaTypes.h>
+#include <lzma/LzmaDec.h>
+#include <lzma/LzmaTools.h>
+
 #ifdef CONFIG_CMD_BDI
 extern int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
 #endif
@@ -375,6 +381,106 @@
 	}
 }
 
+/**
+ * print_decomp_msg() - Print a suitable decompression/loading message
+ *
+ * @type:	OS type (IH_OS_...)
+ * @comp_type:	Compression type being used (IH_COMP_...)
+ * @is_xip:	true if the load address matches the image start
+ */
+static void print_decomp_msg(int comp_type, int type, bool is_xip)
+{
+	const char *name = genimg_get_type_name(type);
+
+	if (comp_type == IH_COMP_NONE)
+		printf("   %s %s\n", is_xip ? "XIP" : "Loading", name);
+	else
+		printf("   Uncompressing %s\n", name);
+}
+
+int image_decomp(int comp, ulong load, ulong image_start, int type,
+		 void *load_buf, void *image_buf, ulong image_len,
+		 uint unc_len, ulong *load_end)
+{
+	int ret = 0;
+
+	*load_end = load;
+	print_decomp_msg(comp, type, load == image_start);
+
+	/*
+	 * Load the image to the right place, decompressing if needed. After
+	 * this, image_len will be set to the number of uncompressed bytes
+	 * loaded, ret will be non-zero on error.
+	 */
+	switch (comp) {
+	case IH_COMP_NONE:
+		if (load == image_start)
+			break;
+		if (image_len <= unc_len)
+			memmove_wd(load_buf, image_buf, image_len, CHUNKSZ);
+		else
+			ret = -ENOSPC;
+		break;
+#ifdef CONFIG_GZIP
+	case IH_COMP_GZIP: {
+		ret = gunzip(load_buf, unc_len, image_buf, &image_len);
+		break;
+	}
+#endif /* CONFIG_GZIP */
+#ifdef CONFIG_BZIP2
+	case IH_COMP_BZIP2: {
+		uint size = unc_len;
+
+		/*
+		 * If we've got less than 4 MB of malloc() space,
+		 * use slower decompression algorithm which requires
+		 * at most 2300 KB of memory.
+		 */
+		ret = BZ2_bzBuffToBuffDecompress(load_buf, &size,
+			image_buf, image_len,
+			CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0);
+		image_len = size;
+		break;
+	}
+#endif /* CONFIG_BZIP2 */
+#ifdef CONFIG_LZMA
+	case IH_COMP_LZMA: {
+		SizeT lzma_len = unc_len;
+
+		ret = lzmaBuffToBuffDecompress(load_buf, &lzma_len,
+					       image_buf, image_len);
+		image_len = lzma_len;
+		break;
+	}
+#endif /* CONFIG_LZMA */
+#ifdef CONFIG_LZO
+	case IH_COMP_LZO: {
+		size_t size = unc_len;
+
+		ret = lzop_decompress(image_buf, image_len, load_buf, &size);
+		image_len = size;
+		break;
+	}
+#endif /* CONFIG_LZO */
+#ifdef CONFIG_LZ4
+	case IH_COMP_LZ4: {
+		size_t size = unc_len;
+
+		ret = ulz4fn(image_buf, image_len, load_buf, &size);
+		image_len = size;
+		break;
+	}
+#endif /* CONFIG_LZ4 */
+	default:
+		printf("Unimplemented compression type %d\n", comp);
+		return -ENOSYS;
+	}
+
+	*load_end = load + image_len;
+
+	return ret;
+}
+
 
 #ifndef USE_HOSTCC
 #if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
@@ -551,6 +657,11 @@
 	memmove(to, from, len);
 #endif	/* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */
 }
+#else	/* USE_HOSTCC */
+void memmove_wd(void *to, void *from, size_t len, ulong chunksz)
+{
+	memmove(to, from, len);
+}
 #endif /* !USE_HOSTCC */
 
 void genimg_print_size(uint32_t size)