From 0c7707610f46a28b65eff935500c78c9781f8f4f Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Wed, 26 Aug 2015 11:31:40 +0200 Subject: [PATCH] lavc: Add a lzf decompressor Signed-off-by: Vittorio Giovara --- configure | 1 + libavcodec/Makefile | 1 + libavcodec/lzf.c | 90 +++++++++++++++++++++++++++++++++++++++++++++ libavcodec/lzf.h | 29 +++++++++++++++ 4 files changed, 121 insertions(+) create mode 100644 libavcodec/lzf.c create mode 100644 libavcodec/lzf.h diff --git a/configure b/configure index c3c4f82191..9e83285f2c 100755 --- a/configure +++ b/configure @@ -1613,6 +1613,7 @@ CONFIG_EXTRA=" libx262 lgplv3 lpc + lzf me_cmp mpeg_er mpegaudio diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 2fbcc0922a..534fe4dfb0 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -68,6 +68,7 @@ OBJS-$(CONFIG_JPEGTABLES) += jpegtables.o OBJS-$(CONFIG_LIBXVID) += libxvid_rc.o OBJS-$(CONFIG_LPC) += lpc.o OBJS-$(CONFIG_LSP) += lsp.o +OBJS-$(CONFIG_LZF) += lzf.o OBJS-$(CONFIG_MDCT) += mdct_fixed.o mdct_float.o OBJS-$(CONFIG_ME_CMP) += me_cmp.o OBJS-$(CONFIG_MPEG_ER) += mpeg_er.o diff --git a/libavcodec/lzf.c b/libavcodec/lzf.c new file mode 100644 index 0000000000..35b932bd08 --- /dev/null +++ b/libavcodec/lzf.c @@ -0,0 +1,90 @@ +/* + * lzf decompression algorithm + * Copyright (c) 2015 Luca Barbato + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * lzf decompression + * + * LZF is a fast compression/decompression algorithm that takes very little + * code space and working memory, ideal for real-time and block compression. + * + * https://en.wikibooks.org/wiki/Data_Compression/Dictionary_compression#LZF + */ + +#include "libavutil/mem.h" + +#include "bytestream.h" +#include "lzf.h" + +#define LZF_LITERAL_MAX (1 << 5) +#define LZF_LONG_BACKREF 7 + 2 + +int ff_lzf_uncompress(GetByteContext *gb, uint8_t **buf, int64_t *size) +{ + int ret = 0; + uint8_t *p = *buf; + int64_t len = 0; + + while (bytestream2_get_bytes_left(gb) > 2) { + uint8_t s = bytestream2_get_byte(gb); + + if (s < LZF_LITERAL_MAX) { + s++; + if (s > *size - len) { + *size += *size /2; + ret = av_reallocp(buf, *size); + if (ret < 0) + return ret; + } + + bytestream2_get_buffer(gb, p, s); + p += s; + len += s; + } else { + int l = 2 + (s >> 5); + int off = ((s & 0x1f) << 8) + 1; + + if (l == LZF_LONG_BACKREF) + l += bytestream2_get_byte(gb); + + off += bytestream2_get_byte(gb); + + if (off > len) + return AVERROR_INVALIDDATA; + + if (l > *size - len) { + *size += *size / 2; + ret = av_reallocp(buf, *size); + if (ret < 0) + return ret; + } + + av_memcpy_backptr(p, off, l); + + p += l; + len += l; + } + } + + *size = len; + + return 0; +} diff --git a/libavcodec/lzf.h b/libavcodec/lzf.h new file mode 100644 index 0000000000..4951f2511f --- /dev/null +++ b/libavcodec/lzf.h @@ -0,0 +1,29 @@ +/* + * lzf decompression algorithm + * Copyright (c) 2015 Luca Barbato + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_LZF_H +#define AVCODEC_LZF_H + +#include "bytestream.h" + +int ff_lzf_uncompress(GetByteContext *gb, uint8_t **buf, int64_t *size); + +#endif /* AVCODEC_LZF_H */