// SPDX-License-Identifier: GPL 2.0+ OR BSD-3-Clause
/*
 * Copyright 2015 Google Inc.
 */

#include <common.h>
#include <compiler.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <errno.h>

#include "lz4_wrapper.h"

#define LZ4F_MAGIC 0x184D2204

#define LZ4_MAX_BLOCK_SIZE_64K 4
#define LZ4_MAX_BLOCK_SIZE_256K 5
#define LZ4_MAX_BLOCK_SIZE_1M 6
#define LZ4_MAX_BLOCK_SIZE_4M 7

struct lz4_block_header {
	union {
		u32 raw;
		struct {
			u32 size : 31;
			u32 not_compressed : 1;
		};
	};
	/* + size bytes of data */
	/* + u32 block_checksum iff has_block_checksum is set */
} __packed;

static u16 LZ4_readLE16(const void *src)
{
	return le16_to_cpu(*(u16 *)src);
}
static void LZ4_copy4(void *dst, const void *src)
{
	*(u32 *)dst = *(u32 *)src;
}
static void LZ4_copy8(void *dst, const void *src)
{
	*(u64 *)dst = *(u64 *)src;
}

/* Unaltered (except removing unrelated code) from github.com/Cyan4973/lz4. */
#include "lz4.c" /* #include for inlining, do not link! */

bool is_data_lz4_compressed(const void *src, size_t srcn)
{
	if (srcn < sizeof(struct lz4_frame_header)) {
		return false;
	}

	struct lz4_frame_header h;
	memcpy(&h, src, sizeof(h));
	return le32_to_cpu(h.magic) == LZ4F_MAGIC;
}

int check_and_extract_lz4_frame_header(const void *src, size_t srcn,
				       struct lz4_frame_header *out,
				       size_t *data_offset)
{
	const void *in = src;
	const struct lz4_frame_header *h = in;

	if (srcn < sizeof(*h) + sizeof(u64) + sizeof(u8))
		return -EINVAL; /* input overrun */

	/* We assume there's always only a single, standard frame. */
	if (le32_to_cpu(h->magic) != LZ4F_MAGIC || h->version != 1) {
		fprintf(stderr, "invalid magic %x, %d\n",
			le32_to_cpu(h->magic) != LZ4F_MAGIC, h->version);
		return -EPROTONOSUPPORT; /* unknown format */
	}
	if (h->reserved0 || h->reserved1 || h->reserved2)
		return -EINVAL; /* reserved must be zero */
	if (!h->independent_blocks) {
		fprintf(stderr, "no support for independent block\n");
		return -EPROTONOSUPPORT; /* we can't support this yet */
	}

	in += sizeof(*h);
	if (h->has_content_size)
		in += sizeof(u64);
	in += sizeof(u8);
	*data_offset = in - src;
	*out = *h;
	return 0;
}

/**
 * Decompress one block of data from lz4 data.
 *
 * @param src	The lz4 compressed data.
 * @param srcn	Size of |src|.
 * @param dst	Output pointer for storing the decompress block.
 * @param dstn	Size of |dst|.
 * @param block_size	Output pointer for size of current compressed block.
 * @param decompressed_size Output pointer for the amount of data decompressed.
 */
int decompress_block(const void *src, size_t srcn, void *dst, int dstn,
		     size_t *block_size, size_t *decompressed_size)
{
	const void *in = src;
	void *out = dst;
	const void *end = out + dstn;
	*decompressed_size = 0;
	struct lz4_block_header b;
	b.raw = le32_to_cpu(*(u32 *)in);
	*block_size = sizeof(struct lz4_block_header) + b.size;
	in += sizeof(struct lz4_block_header);
	if (in - src + b.size > srcn) {
		fprintf(stderr, "input overrun\n");
		return -EINVAL; /* input overrun */
	}

	if (!b.size) {
		return 0; /* decompression successful */
	}

	if (b.not_compressed) {
		size_t size = min((ptrdiff_t)b.size, end - out);
		memcpy(out, in, size);
		out += size;
		if (size < b.size) {
			fprintf(stderr, "output overrun\n");
			return -ENOBUFS; /* output overrun */
		}
	} else {
		/* constant folding essential, do not touch params! */
		int ret = LZ4_decompress_generic((const char* const)in, out, b.size, end - out,
						 endOnInputSize, full, 0,
						 noDict, out, NULL, 0);
		if (ret < 0) {
			fprintf(stderr, "LZ4_decompress_generic error %d\n",
				ret);
			return -EPROTO; /* decompression error */
		}
		out += ret;
	}

	*decompressed_size = out - dst;
	return 0;
}

int ulz4fn(const void *src, size_t srcn, void *dst, size_t *dstn)
{
	const void *src_end = src + srcn;
	const void *dst_end = dst + *dstn;
	struct lz4_frame_header h;
	size_t data_offset = 0;
	int ret =
		check_and_extract_lz4_frame_header(src, srcn, &h, &data_offset);
	if (ret) {
		return ret;
	}
	const void *data = (uint8_t *)src + data_offset;
	void *out = dst;
	size_t decompressed_size = 0, block_size;
	do {
		if ((ret = decompress_block(data, src_end - data, out,
					   dst_end - out, &block_size,
					   &decompressed_size))) {
			return ret;
		}
		out += decompressed_size;
		data += block_size + (h.has_block_checksum ? sizeof(u32) : 0);
	} while (decompressed_size);

	*dstn = out - dst;
	return 0;
}

int get_lz4_max_block_size(const struct lz4_frame_header *h, size_t *out)
{
	switch (h->max_block_size) {
	case LZ4_MAX_BLOCK_SIZE_64K:
		*out = 64 * 1024;
		break;
	case LZ4_MAX_BLOCK_SIZE_256K:
		*out = 256 * 1024;
		break;
	case LZ4_MAX_BLOCK_SIZE_1M:
		*out = 1024 * 1024;
		break;
	case LZ4_MAX_BLOCK_SIZE_4M:
		*out = 4 * 1024 * 1024;
		break;
	default:
		printf("Invalid block max size code");
		return -1;
	}
	return 0;
}

int lz4_decompress(const struct lz4_frame_header *h, const uint8_t *src,
		   size_t *srcn, uint8_t *dst, size_t *dstn,
		   bool *has_more_data)
{
	int ret = 0;
	size_t max_block_size = 0;
	if ((ret = get_lz4_max_block_size(h, &max_block_size))) {
		return ret;
	}

	const uint8_t *in_curr = src;
	const uint8_t *in_end = src + *srcn;
	uint8_t *out_curr = dst;
	uint8_t *out_end = dst + *dstn;
	*dstn = 0;
	*srcn = 0;
	*has_more_data = true;
	while (out_curr + max_block_size <= out_end) {
		size_t compressed_size = 0, decompressed_size = 0;
		if ((ret = decompress_block(in_curr, in_end - in_curr, out_curr,
					    out_end - out_curr,
					    &compressed_size,
					    &decompressed_size))) {
			return ret;
		}
		in_curr += compressed_size +
			   (h->has_block_checksum ? sizeof(u32) : 0);
		out_curr += decompressed_size;
		// If no more data can be decompressed, exit the loop
		if (!decompressed_size) {
			*has_more_data = false;
			break;
		}
	}

	*dstn = out_curr - dst;
	*srcn = in_curr - src;
	return 0;
}
