diff --git a/src/gmio_amf/amf_io.c b/src/gmio_amf/amf_io.c index 2d51e2a..d3e7531 100644 --- a/src/gmio_amf/amf_io.c +++ b/src/gmio_amf/amf_io.c @@ -37,6 +37,7 @@ #include "../gmio_core/internal/helper_stream.h" #include "../gmio_core/internal/helper_task_iface.h" #include "../gmio_core/internal/ostringstream.h" +#include "../gmio_core/internal/zlib_utils.h" #include #include @@ -638,21 +639,6 @@ static bool gmio_amf_check_error( return gmio_no_error(*error); } -/* Converts zlib error to gmio "zlib-specific" error */ -static int zlib_error_to_gmio_error(int error) -{ - switch (error) { - case Z_OK: return GMIO_ERROR_OK; - case Z_ERRNO: return GMIO_ERROR_ZLIB_ERRNO; - case Z_STREAM_ERROR: return GMIO_ERROR_ZLIB_STREAM; - case Z_DATA_ERROR: return GMIO_ERROR_ZLIB_DATA; - case Z_MEM_ERROR: return GMIO_ERROR_ZLIB_MEM; - case Z_BUF_ERROR: return GMIO_ERROR_ZLIB_BUF; - case Z_VERSION_ERROR: return GMIO_ERROR_ZLIB_VERSION; - } - return GMIO_ERROR_UNKNOWN; -} - /* Helper for gmio_amf_ostringstream_write() to write zlib compressed data */ static size_t gmio_amf_ostringstream_write_zlib( struct gmio_amf_wcontext* context, @@ -872,28 +858,18 @@ int gmio_amf_write( /* Initialize internal zlib stream for compression */ if (opts->compress) { - const struct gmio_zlib_compress_options* z_opts = - &opts->z_compress_options; const size_t mblock_halfsize = memblock->size / 2; - int z_init_error = Z_OK; context.sstream->strbuff.capacity = mblock_halfsize; context.z_memblock = gmio_memblock( (uint8_t*)memblock->ptr + mblock_halfsize, mblock_halfsize, NULL); - z_init_error = - deflateInit2( - &context.z_stream, - z_opts->level, - Z_DEFLATED, /* Method */ - 15, /* Window bits(default value) */ - z_opts->memory_usage, - z_opts->strategy); - if (z_init_error != Z_OK) { - context.error = zlib_error_to_gmio_error(z_init_error); + context.error = + gmio_zlib_compress_init( + &context.z_stream, &opts->z_compress_options); + if (gmio_error(context.error)) goto label_end; - } context.z_flush = Z_NO_FLUSH; } } diff --git a/src/gmio_amf/amf_io_options.h b/src/gmio_amf/amf_io_options.h index 722a205..74cd9ad 100644 --- a/src/gmio_amf/amf_io_options.h +++ b/src/gmio_amf/amf_io_options.h @@ -41,58 +41,7 @@ #include "../gmio_core/memblock.h" #include "../gmio_core/task_iface.h" #include "../gmio_core/text_format.h" - -/*! zlib compression level, specific values */ -enum gmio_zlib_compress_level -{ - GMIO_ZLIB_COMPRESS_LEVEL_NONE = -1, /*! Maps to Z_NO_COMPRESSION */ - GMIO_ZLIB_COMPRESS_LEVEL_DEFAULT = 0, /*! Maps to Z_DEFAULT_COMPRESSION */ - GMIO_ZLIB_COMPRESS_LEVEL_BEST_SPEED = 1, /*! Maps to Z_BEST_SPEED */ - GMIO_ZLIB_COMPRESS_LEVEL_BEST_SIZE = 9 /*! Maps to Z_BEST_COMPRESSION */ -}; - -/*! zlib compression strategy */ -enum gmio_zlib_compress_strategy -{ - GMIO_ZLIB_COMPRESSION_STRATEGY_DEFAULT = 0, - GMIO_ZLIB_COMPRESSION_STRATEGY_FILTERED = 1, - GMIO_ZLIB_COMPRESSION_STRATEGY_HUFFMAN_ONLY = 2, - GMIO_ZLIB_COMPRESSION_STRATEGY_RLE = 3, - GMIO_ZLIB_COMPRESSION_STRATEGY_FIXED = 4 -}; - -/*! zlib compression options - * - * Initialising gmio_zlib_compress_options with \c {0} (or \c {} in C++) is the - * convenient way to set default values. - */ -struct gmio_zlib_compress_options -{ - /*! Compression level - * - * \c 0 : default compression - * \c 1 : best speed - * \c 9 : best compression */ - uint8_t level; - - /*! Compression strategy - * - * \c 0 : default strategy - * \c 1 : filtered - * \c 9 : best compression */ - enum gmio_zlib_compress_strategy strategy; - - /*! Specifies how much memory should be allocated for the internal - * compression state - * - * The value must belongs to \c [1..9] or equals to \c 0 which maps to the - * default usage. - * - * \c 1 uses minimum memory but is slow and reduces compression ratio - * \c 9 uses maximum memory for optimal speed - */ - uint8_t memory_usage; -}; +#include "../gmio_core/zlib_compress.h" /*! Options of function gmio_amf_write() * diff --git a/src/gmio_core/error.h b/src/gmio_core/error.h index f9ca6f5..4783c77 100644 --- a/src/gmio_core/error.h +++ b/src/gmio_core/error.h @@ -92,7 +92,14 @@ enum gmio_error /*! See \c Z_VERSION_ERROR (zlib library version is incompatible with the * version assumed by the caller) */ - GMIO_ERROR_ZLIB_VERSION + GMIO_ERROR_ZLIB_VERSION, + + /*! Invalid compression level, see gmio_zlib_compress_options::level */ + GMIO_ERROR_ZLIB_INVALID_COMPRESS_LEVEL, + + /*! Invalid compression memory usage, see + * gmio_zlib_compress_options::memory_usage */ + GMIO_ERROR_ZLIB_INVALID_COMPRESS_MEMORY_USAGE }; /*! Returns true if code == GMIO_NO_ERROR */ diff --git a/src/gmio_core/internal/zlib_utils.c b/src/gmio_core/internal/zlib_utils.c new file mode 100644 index 0000000..e458ad8 --- /dev/null +++ b/src/gmio_core/internal/zlib_utils.c @@ -0,0 +1,95 @@ +/**************************************************************************** +** Copyright (c) 2016, Fougue Ltd. +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** 2. 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. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE 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. +****************************************************************************/ + +#include "zlib_utils.h" +#include "../error.h" + +/* Converts zlib error to gmio "zlib-specific" error */ +int zlib_error_to_gmio_error(int z_error) +{ + switch (z_error) { + case Z_OK: return GMIO_ERROR_OK; + case Z_ERRNO: return GMIO_ERROR_ZLIB_ERRNO; + case Z_STREAM_ERROR: return GMIO_ERROR_ZLIB_STREAM; + case Z_DATA_ERROR: return GMIO_ERROR_ZLIB_DATA; + case Z_MEM_ERROR: return GMIO_ERROR_ZLIB_MEM; + case Z_BUF_ERROR: return GMIO_ERROR_ZLIB_BUF; + case Z_VERSION_ERROR: return GMIO_ERROR_ZLIB_VERSION; + } + return GMIO_ERROR_UNKNOWN; +} + +static int gmio_to_zlib_compress_level(int gmio_compress_level) +{ + if (gmio_compress_level == GMIO_ZLIB_COMPRESS_LEVEL_DEFAULT) + return Z_DEFAULT_COMPRESSION; + else if (gmio_compress_level == GMIO_ZLIB_COMPRESS_LEVEL_NONE) + return Z_NO_COMPRESSION; + return gmio_compress_level; +} + +static int gmio_to_zlib_compress_memusage(int gmio_compress_memusage) +{ + if (gmio_compress_memusage == 0) + return 8; + return gmio_compress_memusage; +} + +int gmio_zlib_compress_init( + struct z_stream_s* z_stream, + const struct gmio_zlib_compress_options* z_opts) +{ + const int zlib_compress_level = + gmio_to_zlib_compress_level(z_opts->level); + const int zlib_compress_memusage = + gmio_to_zlib_compress_memusage(z_opts->memory_usage); + const int z_init_error = + deflateInit2_( + z_stream, + zlib_compress_level, + Z_DEFLATED, /* Method */ + 15, /* Window bits(default value) */ + zlib_compress_memusage, + z_opts->strategy, + ZLIB_VERSION, + sizeof(struct z_stream_s)); + return zlib_error_to_gmio_error(z_init_error); +} + +bool gmio_check_zlib_compress_options( + int* error, const struct gmio_zlib_compress_options* z_opts) +{ + if (z_opts != NULL) { + if (!(-1 <= z_opts->level && z_opts->level <= 9)) + *error = GMIO_ERROR_ZLIB_INVALID_COMPRESS_LEVEL; + if (!(0 <= z_opts->memory_usage && z_opts->memory_usage <= 9)) + *error = GMIO_ERROR_ZLIB_INVALID_COMPRESS_MEMORY_USAGE; + } + return gmio_no_error(*error); +} diff --git a/src/gmio_core/internal/zlib_utils.h b/src/gmio_core/internal/zlib_utils.h new file mode 100644 index 0000000..6957ede --- /dev/null +++ b/src/gmio_core/internal/zlib_utils.h @@ -0,0 +1,49 @@ +/**************************************************************************** +** Copyright (c) 2016, Fougue Ltd. +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** 2. 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. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE 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 GMIO_INTERNAL_ZLIB_UTILS_H +#define GMIO_INTERNAL_ZLIB_UTILS_H + +#include "../global.h" +#include "../zlib_compress.h" +#include + +/* Converts zlib error to gmio "zlib-specific" error */ +int zlib_error_to_gmio_error(int z_error); + +/* Wrapper around deflateInit2(), returns a converted gmio error code */ +int gmio_zlib_compress_init( + struct z_stream_s* z_stream, + const struct gmio_zlib_compress_options* z_opts); + +/* Checks zlib compression options */ +bool gmio_check_zlib_compress_options( + int* error, const struct gmio_zlib_compress_options* z_opts); + +#endif /* GMIO_INTERNAL_ZLIB_UTILS_H */ diff --git a/src/gmio_core/zlib_compress.h b/src/gmio_core/zlib_compress.h new file mode 100644 index 0000000..2bdcf90 --- /dev/null +++ b/src/gmio_core/zlib_compress.h @@ -0,0 +1,96 @@ +/**************************************************************************** +** Copyright (c) 2016, Fougue Ltd. +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** 2. 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. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE 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. +****************************************************************************/ + +/*! \file zlib_compress.h + * Options for using compression with zlib + * + * \addtogroup gmio_core + * @{ + */ + +#ifndef GMIO_ZLIB_COMPRESS_H +#define GMIO_ZLIB_COMPRESS_H + +#include "global.h" + +/* TODO: check enum values in unit tests*/ +/*! zlib compression level, specific values */ +enum gmio_zlib_compress_level +{ + GMIO_ZLIB_COMPRESS_LEVEL_NONE = -1, /*! -> Z_NO_COMPRESSION */ + GMIO_ZLIB_COMPRESS_LEVEL_DEFAULT = 0, /*! -> Z_DEFAULT_COMPRESSION */ + GMIO_ZLIB_COMPRESS_LEVEL_BEST_SPEED = 1, /*! -> Z_BEST_SPEED */ + GMIO_ZLIB_COMPRESS_LEVEL_BEST_SIZE = 9 /*! -> Z_BEST_COMPRESSION */ +}; + +/* TODO: check enum values in unit tests*/ +/*! zlib compression strategy */ +enum gmio_zlib_compress_strategy +{ + GMIO_ZLIB_COMPRESSION_STRATEGY_DEFAULT = 0, /*! -> Z_DEFAULT_STRATEGY */ + GMIO_ZLIB_COMPRESSION_STRATEGY_FILTERED = 1, /*! -> Z_FILTERED */ + GMIO_ZLIB_COMPRESSION_STRATEGY_HUFFMAN_ONLY = 2, /*! -> Z_HUFFMAN_ONLY */ + GMIO_ZLIB_COMPRESSION_STRATEGY_RLE = 3, /*! -> Z_RLE */ + GMIO_ZLIB_COMPRESSION_STRATEGY_FIXED = 4 /*! -> Z_FIXED */ +}; + +/*! zlib compression options + * + * Initialising gmio_zlib_compress_options with \c {0} (or \c {} in C++) is the + * convenient way to set default values. + */ +struct gmio_zlib_compress_options +{ + /*! Compression level + * + * \c 0 : default compression + * \c 1 : best speed + * \c 9 : best compression */ + uint8_t level; + + /*! Compression strategy + * + * \c 0 : default strategy + * \c 1 : filtered + * \c 9 : best compression */ + enum gmio_zlib_compress_strategy strategy; + + /*! Specifies how much memory should be allocated for the internal + * compression state + * + * The value must belongs to \c [1..9] or equals to \c 0 which maps to the + * default usage. + * + * \c 1 uses minimum memory but is slow and reduces compression ratio + * \c 9 uses maximum memory for optimal speed + */ + uint8_t memory_usage; +}; + +#endif /* GMIO_ZLIB_COMPRESS_H */