From ce1c8413a2db9d084b8dc56edabc890ecbce05ca Mon Sep 17 00:00:00 2001 From: "chao.an" Date: Tue, 23 Nov 2021 18:33:20 +0800 Subject: [PATCH] libc/lzfcompress: add lzf compress stream compress stream based on lzf algorithm: struct lib_rawoutstream_s rawstream; struct lib_lzfoutstream_s lzfstream; lib_rawoutstream(&rawstream, fd); lib_lzfoutstream(&lzfstream, &rawstream); Signed-off-by: chao.an --- include/lzf.h | 10 ++ include/nuttx/streams.h | 45 +++++++++ libs/libc/Kconfig | 1 + libs/libc/stream/Kconfig | 24 +++++ libs/libc/stream/Make.defs | 4 + libs/libc/stream/lib_lzfcompress.c | 143 +++++++++++++++++++++++++++++ 6 files changed, 227 insertions(+) create mode 100644 libs/libc/stream/Kconfig create mode 100644 libs/libc/stream/lib_lzfcompress.c diff --git a/include/lzf.h b/include/lzf.h index 151c84af83..f73b85b295 100644 --- a/include/lzf.h +++ b/include/lzf.h @@ -32,10 +32,19 @@ #ifndef __INCLUDE_LZF_H #define __INCLUDE_LZF_H +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ +#ifdef CONFIG_LIBC_LZF + #define LZF_VERSION 0x0105 /* 1.5, API version */ #define HLOG CONFIG_LIBC_LZF_HLOG @@ -151,4 +160,5 @@ unsigned int lzf_decompress(FAR const void *const in_data, unsigned int in_len, FAR void *out_data, unsigned int out_len); +#endif /* CONFIG_LIBC_LZF */ #endif /* __INCLUDE_LZF_H */ diff --git a/include/nuttx/streams.h b/include/nuttx/streams.h index f4c2e55529..4d53114211 100644 --- a/include/nuttx/streams.h +++ b/include/nuttx/streams.h @@ -26,8 +26,18 @@ ****************************************************************************/ #include + +#include #include +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef CONFIG_LIBC_LZF +#define LZF_STREAM_BLOCKSIZE ((1 << CONFIG_STREAM_LZF_BLOG) - 1) +#endif + /**************************************************************************** * Public Types ****************************************************************************/ @@ -173,6 +183,20 @@ struct lib_rawsostream_s int fd; }; +/* LZF compressed stream pipeline */ + +#ifdef CONFIG_LIBC_LZF +struct lib_lzfoutstream_s +{ + struct lib_outstream_s public; + FAR struct lib_outstream_s *backend; + lzf_state_t state; + size_t offset; + char in[LZF_STREAM_BLOCKSIZE]; + char out[LZF_MAX_HDR_SIZE + LZF_STREAM_BLOCKSIZE]; +}; +#endif + /**************************************************************************** * Public Data ****************************************************************************/ @@ -329,6 +353,27 @@ void lib_zeroinstream(FAR struct lib_instream_s *zeroinstream); void lib_nullinstream(FAR struct lib_instream_s *nullinstream); void lib_nulloutstream(FAR struct lib_outstream_s *nulloutstream); +/**************************************************************************** + * Name: lib_lzfoutstream + * + * Description: + * LZF compressed pipeline stream + * + * Input Parameters: + * stream - User allocated, uninitialized instance of struct + * lib_lzfoutstream_s to be initialized. + * backend - Stream backend port. + * + * Returned Value: + * None (User allocated instance initialized). + * + ****************************************************************************/ + +#ifdef CONFIG_LIBC_LZF +void lib_lzfoutstream(FAR struct lib_lzfoutstream_s *stream, + FAR struct lib_outstream_s *backend); +#endif + /**************************************************************************** * Name: lib_noflush * diff --git a/libs/libc/Kconfig b/libs/libc/Kconfig index 963c974d07..cf512d886a 100644 --- a/libs/libc/Kconfig +++ b/libs/libc/Kconfig @@ -30,3 +30,4 @@ source "libs/libc/hex2bin/Kconfig" source "libs/libc/userfs/Kconfig" source "libs/libc/builtin/Kconfig" source "libs/libc/symtab/Kconfig" +source "libs/libc/stream/Kconfig" diff --git a/libs/libc/stream/Kconfig b/libs/libc/stream/Kconfig new file mode 100644 index 0000000000..90554aa661 --- /dev/null +++ b/libs/libc/stream/Kconfig @@ -0,0 +1,24 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +menu "Stream C I/O" + +if LIBC_LZF + +config STREAM_LZF_BLOG + int "Log2 of block size" + default 10 + range 9 12 + ---help--- + This stream uses two buffers of size a little more than + (1 << CONFIG_STREAM_LZF_BLOG) to compress and decompress data in + chunks. Slightly better compression should be obtainable with larger + + NOTE: This is a pairing option for using the decompression tool, + chunks must match with compression + +endif + +endmenu # Locale Support diff --git a/libs/libc/stream/Make.defs b/libs/libc/stream/Make.defs index c5409e2c97..7af465dc09 100644 --- a/libs/libc/stream/Make.defs +++ b/libs/libc/stream/Make.defs @@ -34,6 +34,10 @@ CSRCS += lib_stdinstream.c lib_stdoutstream.c lib_stdsistream.c CSRCS += lib_stdsostream.c endif +ifeq ($(CONFIG_LIBC_LZF),y) +CSRCS += lib_lzfcompress.c +endif + # Add the stdio directory to the build DEPPATH += --dep-path stream diff --git a/libs/libc/stream/lib_lzfcompress.c b/libs/libc/stream/lib_lzfcompress.c new file mode 100644 index 0000000000..b508a9d175 --- /dev/null +++ b/libs/libc/stream/lib_lzfcompress.c @@ -0,0 +1,143 @@ +/**************************************************************************** + * libs/libc/stream/lib_lzfcompress.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lzfoutstream_flush + ****************************************************************************/ + +static int lzfoutstream_flush(FAR struct lib_outstream_s *this) +{ + FAR struct lib_lzfoutstream_s *stream = + (FAR struct lib_lzfoutstream_s *)this; + FAR struct lzf_header_s *header; + size_t outlen; + + if (stream->offset > 0) + { + outlen = lzf_compress(stream->in, stream->offset, + &stream->out[LZF_MAX_HDR_SIZE], + stream->offset, stream->state, &header); + if (outlen > 0) + { + stream->backend->puts(stream->backend, header, outlen); + } + + stream->offset = 0; + } + + return stream->backend->flush(stream->backend); +} + +/**************************************************************************** + * Name: lzfoutstream_puts + ****************************************************************************/ + +static int lzfoutstream_puts(FAR struct lib_outstream_s *this, + FAR const void *buf, int len) +{ + FAR struct lib_lzfoutstream_s *stream = + (FAR struct lib_lzfoutstream_s *)this; + FAR struct lzf_header_s *header; + FAR const char *ptr = buf; + size_t total = len; + size_t copyin; + size_t outlen; + int ret; + + while (total > 0) + { + copyin = stream->offset + total > LZF_STREAM_BLOCKSIZE ? + LZF_STREAM_BLOCKSIZE - stream->offset : total; + + memcpy(stream->in + stream->offset, ptr, copyin); + + ptr += copyin; + stream->offset += copyin; + this->nput += copyin; + total -= copyin; + + if (stream->offset == LZF_STREAM_BLOCKSIZE) + { + outlen = lzf_compress(stream->in, stream->offset, + &stream->out[LZF_MAX_HDR_SIZE], + stream->offset, stream->state, + &header); + if (outlen > 0) + { + ret = stream->backend->puts(stream->backend, header, outlen); + if (ret < 0) + { + return ret; + } + } + + stream->offset = 0; + } + } + + return len; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lib_lzfoutstream + * + * Description: + * LZF compressed pipeline stream + * + * Input Parameters: + * stream - User allocated, uninitialized instance of struct + * lib_lzfoutstream_s to be initialized. + * backend - Stream backend port. + * + * Returned Value: + * None (User allocated instance initialized). + * + ****************************************************************************/ + +void lib_lzfoutstream(FAR struct lib_lzfoutstream_s *stream, + FAR struct lib_outstream_s *backend) +{ + if (stream == NULL || backend == NULL) + { + return; + } + + memset(stream, 0, sizeof(*stream)); + stream->public.puts = lzfoutstream_puts; + stream->public.flush = lzfoutstream_flush; + stream->backend = backend; +}