diff --git a/examples/example_compress_chunk.c b/examples/example_compress_chunk.c index 4dac0d85186eb68c8769ef9e23502d8dac5f44c3..900eb0177373f7dc4b87b17b89b3b0f54b8c1b25 100644 --- a/examples/example_compress_chunk.c +++ b/examples/example_compress_chunk.c @@ -63,7 +63,7 @@ static int demo_comperss_chunk_1d(void) uint8_t chunk[CHUNK_SIZE] = {0}; /* Do not put large amount of data on the stack! */ uint32_t *compressed_data; - int cmp_size_bytes; + uint32_t cmp_size_bytes; { /* build a chunk of a background and an offset collection */ struct collection_hdr *col = (struct collection_hdr *)chunk; @@ -99,11 +99,17 @@ static int demo_comperss_chunk_1d(void) cmp_par.nc_background_mean = 3; cmp_par.nc_background_variance = 4; cmp_par.nc_background_outlier_pixels = 5; + /* Only the compression parameters needed to compress offset and + * background collections are set. + */ /* prepare the buffer for the compressed data */ cmp_size_bound = compress_chunk_cmp_size_bound(chunk, CHUNK_SIZE); - if (!cmp_size_bound) { + if (cmp_is_error(cmp_size_bound)) { printf("Error occurred during compress_chunk_cmp_size_bound()\n"); + printf("Failed with error code %d: %s\n", + cmp_get_error_code(cmp_size_bound), + cmp_get_error_name(cmp_size_bound)); /* error handling */ return -1; } @@ -117,17 +123,23 @@ static int demo_comperss_chunk_1d(void) cmp_size_bytes = compress_chunk(chunk, CHUNK_SIZE, NULL, NULL, compressed_data, cmp_size_bound, &cmp_par); - if (cmp_size_bytes < 0) { + /* this is another way to check if a function failed */ + if (cmp_get_error_code(cmp_size_bytes) != CMP_ERROR_NO_ERROR) { printf("Error occurred during compress_chunk()\n"); - if (cmp_size_bytes == CMP_ERROR_SMALL_BUF) - printf("The compressed data buffer is too small to hold all compressed data!\n"); + printf("Failed with error code %d: %s\n", + cmp_get_error_code(cmp_size_bytes), + cmp_get_error_name(cmp_size_bytes)); free(compressed_data); /* error handling */ return -1; } - if (compress_chunk_set_model_id_and_counter(compressed_data, cmp_size_bytes, - MODEL_ID, 0)) { + cmp_size_bytes = compress_chunk_set_model_id_and_counter(compressed_data, + cmp_size_bytes, MODEL_ID, 0); + if (cmp_is_error(cmp_size_bytes)) { printf("Error occurred during compress_chunk_set_model_id_and_counter()\n"); + printf("we get error code %d: %s\n", + cmp_get_error_code(cmp_size_bytes), + cmp_get_error_name(cmp_size_bytes)); free(compressed_data); /* error handling */ return -1; @@ -135,7 +147,7 @@ static int demo_comperss_chunk_1d(void) } { /* have a look at the compressed data */ - int i; + uint32_t i; printf("Here's the compressed data including the compression entity header (size %d):\n", cmp_size_bytes); for (i = 0; i < cmp_size_bytes; i++) { @@ -176,7 +188,7 @@ static int demo_comperss_chunk_model(void) * the number of collections in the chunk (2 in this demo) */ uint32_t compressed_data[COMPRESS_CHUNK_BOUND(CHUNK_SIZE, 2)/4]; /* Do not put large amount of data on the stack! */ - int cmp_size_bytes; + uint32_t cmp_size_bytes; { /* build a chunk of a background and an offset collection */ struct collection_hdr *col = (struct collection_hdr *)chunk; @@ -228,27 +240,35 @@ static int demo_comperss_chunk_model(void) cmp_par.nc_background_mean = 3; cmp_par.nc_background_variance = 4; cmp_par.nc_background_outlier_pixels = 5; + /* Only the compression parameters needed to compress offset and + * background collections are set. + */ cmp_size_bytes = compress_chunk(chunk, CHUNK_SIZE, model_chunk, updated_chunk_model, compressed_data, sizeof(compressed_data), &cmp_par); - if (cmp_size_bytes < 0) { + if (cmp_is_error(cmp_size_bytes)) { printf("Error occurred during compress_chunk()\n"); - if (cmp_size_bytes == CMP_ERROR_SMALL_BUF) - printf("The compressed data buffer is too small to hold all compressed data!\n"); + printf("Failed with error code %d: %s\n", + cmp_get_error_code(cmp_size_bytes), + cmp_get_error_name(cmp_size_bytes)); /* error handling */ return -1; } - if (compress_chunk_set_model_id_and_counter(compressed_data, cmp_size_bytes, - MODEL_ID, MODEL_COUNTER)) { + cmp_size_bytes = compress_chunk_set_model_id_and_counter(compressed_data, + cmp_size_bytes, MODEL_ID, MODEL_COUNTER); + if (cmp_is_error(cmp_size_bytes)) { printf("Error occurred during compress_chunk_set_model_id_and_counter()\n"); + printf("Failed with error code %d: %s\n", + cmp_get_error_code(cmp_size_bytes), + cmp_get_error_name(cmp_size_bytes)); /* error handling */ return -1; } } { /* have a look at the compressed data */ - int i; + uint32_t i; printf("Here's the compressed data including the compression entity header (size %d):\n", cmp_size_bytes); for (i = 0; i < cmp_size_bytes; i++) { diff --git a/lib/cmp_chunk.h b/lib/cmp_chunk.h index ea305e52a31a48eaee146a4ba7bf6a1d469c6fb3..114c95202440cc1c920ffd498148cea459bc8802 100644 --- a/lib/cmp_chunk.h +++ b/lib/cmp_chunk.h @@ -22,6 +22,7 @@ #include "common/cmp_support.h" #include "common/cmp_entity.h" +#include "common/cmp_error_list.h" #define ROUND_UP_TO_4(x) ((((x)+3)/4)*4) @@ -112,10 +113,11 @@ struct cmp_par { * COMPRESS_CHUNK_BOUND macro for compilation-time evaluation * (stack memory allocation for example) * - * @param chunk pointer to the chunk you want compress + * @param chunk pointer to the chunk you want to compress * @param chunk_size size of the chunk in bytes * - * @returns maximum compressed size for a chunk compression; 0 on error + * @returns maximum compressed size for a chunk compression on success or an + * error code if it fails (which can be tested with cmp_is_error()) */ uint32_t compress_chunk_cmp_size_bound(const void *chunk, size_t chunk_size); @@ -129,7 +131,7 @@ uint32_t compress_chunk_cmp_size_bound(const void *chunk, size_t chunk_size); * * @param return_timestamp pointer to a function returning a current 48-bit * timestamp - * @param version_id version identifier of the applications software + * @param version_id application software version identifier */ void compress_chunk_init(uint64_t(return_timestamp)(void), uint32_t version_id); @@ -156,35 +158,79 @@ void compress_chunk_init(uint64_t(return_timestamp)(void), uint32_t version_id); * compress_chunk_cmp_size_bound(chunk, chunk_size) * as it eliminates one potential failure scenario: * not enough space in the dst buffer to write the - * compressed data; size is internally round down + * compressed data; size is internally rounded down * to a multiple of 4 - * @returns the byte size of the compressed_data buffer on success; negative on - * error, CMP_ERROR_SMALL_BUF (-2) if the compressed data buffer is too - * small to hold the whole compressed data; the compressed and updated - * model are only valid on positive return values + * @returns the byte size of the compressed data or an error code if it + * fails (which can be tested with cmp_is_error()) */ -int32_t compress_chunk(void *chunk, uint32_t chunk_size, - void *chunk_model, void *updated_chunk_model, - uint32_t *dst, uint32_t dst_capacity, - const struct cmp_par *cmp_par); +uint32_t compress_chunk(void *chunk, uint32_t chunk_size, + void *chunk_model, void *updated_chunk_model, + uint32_t *dst, uint32_t dst_capacity, + const struct cmp_par *cmp_par); /** * @brief set the model id and model counter in the compression entity header * - * @param dst pointer to the compressed data starting with a - * compression entity header + * @param dst pointer to the compressed data (starting with a + * compression entity header) * @param dst_size byte size of the dst buffer * @param model_id model identifier; for identifying entities that originate * from the same starting model * @param model_counter model_counter; counts how many times the model was * updated; for non model mode compression use 0 * - * @returns 0 on success, otherwise error + * @returns the byte size of the dst buffer (= dst_size) on success or an error + * code if it fails (which can be tested with cmp_is_error()) */ -int compress_chunk_set_model_id_and_counter(void *dst, int dst_size, - uint16_t model_id, uint8_t model_counter); +uint32_t compress_chunk_set_model_id_and_counter(void *dst, uint32_t dst_size, + uint16_t model_id, uint8_t model_counter); + + +/** + * @brief tells if a result is an error code + * + * @param code return value to check + * + * @returns non-zero if the code is an error + */ + +unsigned int cmp_is_error(uint32_t code); + + +/** + * @brief provides a readable string from a compression return value (useful for debugging) + * + * @param code compression return value to describe + * + * @returns a pointer to a string literal that describes the error code. + */ + +const char* cmp_get_error_name(uint32_t code); + + +/** + * @brief convert a function result into a cmp_error enum + * + * @param code compression return value to get the error code + * + * @returns error code + */ + +enum cmp_error cmp_get_error_code(uint32_t code); + + +/** + * @brief get a string describing an error code + * + * @param code the error code to describe, obtain with cmp_get_error_code() + * + * @returns a pointer to a string literal that describes the error code. + */ + +const char* cmp_get_error_string(enum cmp_error code); + #endif /* CMP_CHUNK_H */ diff --git a/lib/common/byteorder.h b/lib/common/byteorder.h index fc5ff3512c3be848dcb709c893321720cdf15e7e..0e0b022bbffcd6b3dd139191ecf25d7a4bace61a 100644 --- a/lib/common/byteorder.h +++ b/lib/common/byteorder.h @@ -109,7 +109,7 @@ #endif /* USE_BUILTIN_BSWAP */ -static inline __attribute__((const)) uint16_t __fswab16(uint16_t val) +static __inline __attribute__((const)) uint16_t __fswab16(uint16_t val) { #ifdef __HAVE_BUILTIN_BSWAP16__ return __builtin_bswap16(val); @@ -119,7 +119,7 @@ static inline __attribute__((const)) uint16_t __fswab16(uint16_t val) } -static inline __attribute__((const)) uint32_t __fswab32(uint32_t val) +static __inline __attribute__((const)) uint32_t __fswab32(uint32_t val) { #ifdef __HAVE_BUILTIN_BSWAP32__ return __builtin_bswap32(val); @@ -129,7 +129,7 @@ static inline __attribute__((const)) uint32_t __fswab32(uint32_t val) } -static inline __attribute__((const)) uint64_t __fswab64(uint64_t val) +static __inline __attribute__((const)) uint64_t __fswab64(uint64_t val) { #ifdef __HAVE_BUILTIN_BSWAP64__ return __builtin_bswap64(val); @@ -174,7 +174,7 @@ static inline __attribute__((const)) uint64_t __fswab64(uint64_t val) * @brief return a byteswapped 16-bit value from a pointer * @param p a pointer to a naturally-aligned 16-bit value */ -static inline uint16_t __swab16p(const uint16_t *p) +static __inline uint16_t __swab16p(const uint16_t *p) { return __swab16(*p); } @@ -184,7 +184,7 @@ static inline uint16_t __swab16p(const uint16_t *p) * @brief return a byteswapped 32-bit value from a pointer * @param p a pointer to a naturally-aligned 32-bit value */ -static inline uint32_t __swab32p(const uint32_t *p) +static __inline uint32_t __swab32p(const uint32_t *p) { return __swab32(*p); } @@ -194,7 +194,7 @@ static inline uint32_t __swab32p(const uint32_t *p) * @brief return a byteswapped 64-bit value from a pointer * @param p a pointer to a naturally-aligned 64-bit value */ -static inline uint64_t __swab64p(const uint64_t *p) +static __inline uint64_t __swab64p(const uint64_t *p) { return __swab64(*p); } @@ -205,7 +205,7 @@ static inline uint64_t __swab64p(const uint64_t *p) * @param p a pointer to a naturally-aligned 16-bit value */ -static inline void __swab16s(uint16_t *p) +static __inline void __swab16s(uint16_t *p) { *p = __swab16p(p); } @@ -216,7 +216,7 @@ static inline void __swab16s(uint16_t *p) * @param p a pointer to a naturally-aligned 32-bit value */ -static inline void __swab32s(uint32_t *p) +static __inline void __swab32s(uint32_t *p) { *p = __swab32p(p); } @@ -227,7 +227,7 @@ static inline void __swab32s(uint32_t *p) * @param p a pointer to a naturally-aligned 64-bit value */ -static inline void __swab64s(uint64_t *p) +static __inline void __swab64s(uint64_t *p) { *p = __swab64p(p); } diff --git a/lib/common/cmp_cal_up_model.h b/lib/common/cmp_cal_up_model.h index afd8e0c8f15e1c321c6f4b5c3151763fcda7c4ba..b1124778fda5e18259fdddc19312b809090c3d09 100644 --- a/lib/common/cmp_cal_up_model.h +++ b/lib/common/cmp_cal_up_model.h @@ -84,7 +84,7 @@ /* fast calculation for data size smaller that uint32_t */ -static inline uint16_t cmp_up_model16(uint32_t data, uint32_t model, +static __inline uint16_t cmp_up_model16(uint32_t data, uint32_t model, unsigned int model_value, unsigned int round) { /* round and round back input because for decompression the accurate @@ -100,7 +100,7 @@ static inline uint16_t cmp_up_model16(uint32_t data, uint32_t model, /* slow calculation for uint32_t data size */ -static inline uint32_t cmp_up_model32(uint32_t data, uint32_t model, +static __inline uint32_t cmp_up_model32(uint32_t data, uint32_t model, unsigned int model_value, unsigned int round) { /* round and round back input because for decompression the accurate diff --git a/lib/common/cmp_debug.h b/lib/common/cmp_debug.h index 5d950932b7b8f40f6ac9715be5decd96937ccd01..1261289366ad362aef4052852d75f8a3560d618a 100644 --- a/lib/common/cmp_debug.h +++ b/lib/common/cmp_debug.h @@ -41,5 +41,13 @@ void cmp_debug_print_impl(const char *fmt, ...); # define debug_print(...) do {} while (0) #endif +__extension__ +#define debug_print_level(level, ...) \ + do { \ + if (level <= DEBUGLEVEL) \ + debug_print(__VA_ARGS__); \ + } while (0) + + #endif /* CMP_DEBUG_H */ diff --git a/lib/common/cmp_error.c b/lib/common/cmp_error.c new file mode 100644 index 0000000000000000000000000000000000000000..1579151a028294c9498e1f077aa41ec2f297529e --- /dev/null +++ b/lib/common/cmp_error.c @@ -0,0 +1,143 @@ +/** + * @file cmp_error.c + * @author Dominik Loidolt (dominik.loidolt@univie.ac.at) + * @date 2024 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @brief handling errors functions + */ + +#include <stdint.h> + +#include "cmp_error.h" +#include "cmp_error_list.h" +#include "../cmp_chunk.h" + + +/** + * @brief tells if a result is an error code + * + * @param code return value to check + * + * @returns non-zero if the code is an error + */ + +unsigned int cmp_is_error(uint32_t code) +{ + return (code > CMP_ERROR(MAX_CODE)); +} + + +/** + * @brief convert a function result into a cmp_error enum + * + * @param code compression return value to get the error code + * + * @returns error code + */ + +enum cmp_error cmp_get_error_code(uint32_t code) +{ + if (cmp_is_error(code)) + return (enum cmp_error)(0-code); + + return CMP_ERROR_NO_ERROR; +} + + +/** + * @brief get a string describing an error code + * + * @param code the error code to describe, obtain with cmp_get_error_code() + * + * @returns a pointer to a string literal that describes the error code. + */ + +const char* cmp_get_error_string(enum cmp_error code) +{ +#ifdef CMP_STRIP_ERROR_STRINGS + (void)code; + return "Error strings stripped"; +#else + static const char* const notErrorCode = "Unspecified error code"; + switch (code) { + case CMP_ERROR_NO_ERROR: + return "No error detected"; + case CMP_ERROR_GENERIC: + return "Error (generic)"; + case CMP_ERROR_SMALL_BUF_: + return "Destination buffer is too small to hold the whole compressed data"; + case CMP_ERROR_DATA_VALUE_TOO_LARGE: + return "Data value is larger than expected"; + + + case CMP_ERROR_PAR_GENERIC: + return "Compression mode or model value or lossy rounding parameter is unsupported"; + case CMP_ERROR_PAR_SPECIFIC: + return "Specific compression parameters or combination is unsupported"; + case CMP_ERROR_PAR_BUFFERS: + return "Buffer related parameter is not valid"; + case CMP_ERROR_PAR_MAX_USED_BITS: + return "Maximum used bits parameters are not valid"; + + case CMP_ERROR_CHUNK_NULL: + return "Pointer to the chunk is NULL. No data, no compression"; + case CMP_ERROR_CHUNK_TOO_LARGE: + return "Chunk size too large"; + case CMP_ERROR_CHUNK_TOO_SMALL: + return "Chunk size too small. Minimum size is the size of a collection header"; + case CMP_ERROR_CHUNK_SIZE_INCONSISTENT: + return "Chunk size is not consistent with the sum of the sizes in the compression headers. Chunk size may be wrong?"; + case CMP_ERROR_CHUNK_SUBSERVICE_INCONSISTENT: + return "The chunk contains collections with an incompatible combination of subservices"; + + case CMP_ERROR_COL_SUBSERVICE_UNSUPPORTED: + return "Unsupported collection subservice"; + case CMP_ERROR_COL_SIZE_INCONSISTENT: + return "Inconsistency detected between the collection subservice and data length"; + + case CMP_ERROR_ENTITY_NULL: + return "Compression entity pointer is NULL"; + case CMP_ERROR_ENTITY_TOO_SMALL: + return "Compression entity size is too small"; + case CMP_ERROR_ENTITY_HEADER: + return "An error occurred while generating the compression entity header"; + case CMP_ERROR_ENTITY_TIMESTAMP: + return "Timestamp too large for the compression entity header"; + + case CMP_ERROR_INT_DECODER: + return "Internal decoder error occurred"; + case CMP_ERROR_INT_DATA_TYPE_UNSUPPORTED: + return "Internal error: Data type not supported"; + case CMP_ERROR_INT_CMP_COL_TOO_LARGE: + return "Internal error: compressed collection to large"; + + case CMP_ERROR_MAX_CODE: + default: + return notErrorCode; + } +#endif +} + + +/** + * @brief provides a readable string from a compression return value (useful for debugging) + * + * @param code compression return value to describe + * + * @returns a pointer to a string literal that describes the error code. + */ + +const char* cmp_get_error_name(uint32_t code) +{ + return cmp_get_error_string(cmp_get_error_code(code)); +} diff --git a/lib/common/cmp_error.h b/lib/common/cmp_error.h new file mode 100644 index 0000000000000000000000000000000000000000..333bbc9565e4c8a574540f957c6ba932f3cc6400 --- /dev/null +++ b/lib/common/cmp_error.h @@ -0,0 +1,149 @@ +/** + * @file cmp_error.h + * @author Dominik Loidolt (dominik.loidolt@univie.ac.at) + * @date 2024 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @brief collection of macros to handling errors + * This is heavy inspired by the error handling of zstd (lib/common/error_private.h) by + * @author Yann Collet et al. + * https://github.com/facebook/zstd/blob/dev/ + */ + +#ifndef CMP_ERROR_H +#define CMP_ERROR_H + + +#include <stdint.h> +#include "cmp_error_list.h" + + +/** + * @brief add the CMP_ERROR prefix to the error name + * + * @param name the name to concatenate with cmp error prefix + */ + +#define PREFIX_CMP_ERRROR(name) CMP_ERROR_##name + + +/** + * @brief generate a return value of a error + * + * @param name error name without CMP_ERROR prefix to create an error code for + */ + +#define CMP_ERROR(name) ((uint32_t)-PREFIX_CMP_ERRROR(name)) + + +/** + * @brief ignore this is an internal helper + * + * this is a helper function to help force c99-correctness during compilation + * under strict compilation modes variadic macro arguments can't be empty + * however variadic function arguments can be using a function therefore lets + * us statically check that at least one string argument was passed + * independent of the compilation flags + */ + +static __inline void _force_has_format_string(const char *format, ...) { + (void)format; +} + + +/** + * @brief ignore this is an internal helper + * + * we want to force this function invocation to be syntactically correct but + * we don't want to force runtime evaluation of its arguments + */ + +__extension__ +#define _FORCE_HAS_FORMAT_STRING(...) \ + do { \ + if (0) { \ + _force_has_format_string(__VA_ARGS__); \ + } \ + } while (0) + +#define ERR_QUOTE(str) #str + + +/** + * @brief return the specified error if the condition evaluates to true + * + * @param cond the condition to evaluate + * @param err the error to return if the condition is true + * @param ... additional arguments for error logging + * + * in debug modes (DEBUGLEVEL>=3) prints additional information + */ + +__extension__ +#define RETURN_ERROR_IF(cond, err, ...) \ + do { \ + if (cond) { \ + debug_print_level(3, "%s:%d: Error: check %s failed, returning %s", \ + __FILE__, __LINE__, ERR_QUOTE(cond), \ + ERR_QUOTE(CMP_ERROR(err))); \ + _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \ + debug_print_level(3, "-> " __VA_ARGS__); \ + return CMP_ERROR(err); \ + } \ + } while (0) + + +/** + * @brief unconditionally return the specified error + * + * @param err the error to return unconditionally + * @param ... additional arguments for error logging + * + * in debug modes (DEBUGLEVEL>=3) prints additional information + */ + +__extension__ +#define RETURN_ERROR(err, ...) \ + do { \ + debug_print_level(3, "%s:%d: Error: unconditional check failed, returning %s", \ + __FILE__, __LINE__, ERR_QUOTE(ERROR(err))); \ + _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \ + debug_print_level(3, "-> " __VA_ARGS__); \ + return CMP_ERROR(err); \ + } while(0) + + +/** + * @brief if the provided expression evaluates to an error code returns that error code + * + * @param err the error expression to evaluate + * @param ... additional arguments for error logging + * + * in debug modes (DEBUGLEVEL>=3) prints additional information + */ + +__extension__ +#define FORWARD_IF_ERROR(err, ...) \ + do { \ + uint32_t const err_code = (err); \ + if (cmp_is_error(err_code)) { \ + debug_print_level(3, "%s:%d: Error: forwarding error in %s: %s",\ + __FILE__, __LINE__, ERR_QUOTE(err), \ + cmp_get_error_name(err_code)); \ + _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \ + debug_print_level(3, "--> " __VA_ARGS__); \ + return err_code; \ + } \ + } while(0) + + +#endif /* CMP_ERROR_H */ diff --git a/lib/common/cmp_error_list.h b/lib/common/cmp_error_list.h new file mode 100644 index 0000000000000000000000000000000000000000..e28eb940b90f468f942754f8dd8b54c9cab6ead9 --- /dev/null +++ b/lib/common/cmp_error_list.h @@ -0,0 +1,60 @@ +/** + * @file cmp_error_list.h + * @author Dominik Loidolt (dominik.loidolt@univie.ac.at) + * @date 2024 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @brief definition of the compression error codes + */ + +#ifndef CMP_ERROR_LIST_H +#define CMP_ERROR_LIST_H + + +/** + * @brief compression error codes + * @warning error codes (name and value) are TBC + */ + +enum cmp_error { + CMP_ERROR_NO_ERROR = 0, + CMP_ERROR_GENERIC = 1, + CMP_ERROR_SMALL_BUF_ = 2, + CMP_ERROR_DATA_VALUE_TOO_LARGE = 3, + /* compression parameter errors */ + CMP_ERROR_PAR_GENERIC = 20, + CMP_ERROR_PAR_SPECIFIC = 21, + CMP_ERROR_PAR_BUFFERS = 22, + CMP_ERROR_PAR_MAX_USED_BITS = 23, + /* chunk errors */ + CMP_ERROR_CHUNK_NULL = 40, + CMP_ERROR_CHUNK_TOO_LARGE = 41, + CMP_ERROR_CHUNK_TOO_SMALL = 42, + CMP_ERROR_CHUNK_SIZE_INCONSISTENT = 43, + CMP_ERROR_CHUNK_SUBSERVICE_INCONSISTENT = 44, + /* collection errors */ + CMP_ERROR_COL_SUBSERVICE_UNSUPPORTED = 60, + CMP_ERROR_COL_SIZE_INCONSISTENT = 61, + /* compression entity errors */ + CMP_ERROR_ENTITY_NULL = 80, + CMP_ERROR_ENTITY_TOO_SMALL = 81, + CMP_ERROR_ENTITY_HEADER = 82, + CMP_ERROR_ENTITY_TIMESTAMP = 83, + /* internal compressor errors */ + CMP_ERROR_INT_DECODER = 100, + CMP_ERROR_INT_DATA_TYPE_UNSUPPORTED = 101, + CMP_ERROR_INT_CMP_COL_TOO_LARGE = 102, + + CMP_ERROR_MAX_CODE = 127 /* Prefer using cmp_is_error() for error checking. */ +}; + +#endif /* CMP_ERROR_LIST_H */ diff --git a/lib/common/cmp_support.c b/lib/common/cmp_support.c index a211c3c4acad03e11b3f8b1e8780a32de2de6000..b3abb675264d042696fd043d028e5c898f91fbef 100644 --- a/lib/common/cmp_support.c +++ b/lib/common/cmp_support.c @@ -128,7 +128,6 @@ int rdcu_supported_cmp_mode_is_used(enum cmp_mode cmp_mode) case CMP_MODE_MODEL_MULTI: case CMP_MODE_DIFF_MULTI: return 1; - case CMP_MODE_STUFF: default: return 0; } @@ -169,16 +168,7 @@ int rdcu_supported_data_type_is_used(enum cmp_data_type data_type) int cmp_mode_is_supported(enum cmp_mode cmp_mode) { - switch (cmp_mode) { - case CMP_MODE_RAW: - case CMP_MODE_MODEL_ZERO: - case CMP_MODE_DIFF_ZERO: - case CMP_MODE_MODEL_MULTI: - case CMP_MODE_DIFF_MULTI: - case CMP_MODE_STUFF: - return 1; - } - return 0; + return rdcu_supported_cmp_mode_is_used(cmp_mode); } @@ -665,13 +655,6 @@ static int cmp_pars_are_invalid(uint32_t cmp_par, uint32_t spill, enum cmp_mode cfg_invalid++; } - break; - case CMP_MODE_STUFF: - if (cmp_par > MAX_STUFF_CMP_PAR) { - debug_print("Error: The selected %s stuff mode compression parameter: %" PRIu32 " is too large. The largest possible value in the selected compression mode is: %u.", - par_name, cmp_par, MAX_STUFF_CMP_PAR); - cfg_invalid++; - } break; default: debug_print("Error: The compression mode is not supported."); diff --git a/lib/common/cmp_support.h b/lib/common/cmp_support.h index 693d7c6267465e7153315a5828cdc84b961d2e2f..3c4d37f7b203d4acb4fa5fe8006218586df30c7f 100644 --- a/lib/common/cmp_support.h +++ b/lib/common/cmp_support.h @@ -53,7 +53,6 @@ #define MIN_NON_IMA_SPILL 2U /* for maximum spill value look at cmp_icu_max_spill function */ #define MAX_ICU_ROUND 3U -#define MAX_STUFF_CMP_PAR 32U /* default imagette RDCU compression parameters for model compression */ @@ -145,8 +144,7 @@ enum cmp_mode { CMP_MODE_MODEL_ZERO, CMP_MODE_DIFF_ZERO, CMP_MODE_MODEL_MULTI, - CMP_MODE_DIFF_MULTI, - CMP_MODE_STUFF + CMP_MODE_DIFF_MULTI }; diff --git a/lib/common/list.h b/lib/common/list.h index 5613c64f0e6d53782407924f189d7c70e96dc6a0..a05803139a75738f7ddfba05048ae9c85ea91d78 100644 --- a/lib/common/list.h +++ b/lib/common/list.h @@ -78,7 +78,7 @@ struct list_head { #define LIST_HEAD(name) \ struct list_head name = LIST_HEAD_INIT(name) -static inline void __list_add(struct list_head *new, struct list_head *prev, struct list_head *next) +static __inline void __list_add(struct list_head *new, struct list_head *prev, struct list_head *next) { next->prev = new; new->next = next; @@ -95,12 +95,12 @@ static inline void __list_add(struct list_head *new, struct list_head *prev, str * This is good for implementing stacks. */ -static inline void list_add(struct list_head *new, struct list_head *head) +static __inline void list_add(struct list_head *new, struct list_head *head) { __list_add(new, head, head->next); } -static inline void INIT_LIST_HEAD(struct list_head *list) +static __inline void INIT_LIST_HEAD(struct list_head *list) { list->next = list; list->prev = list; @@ -278,7 +278,7 @@ static inline void INIT_LIST_HEAD(struct list_head *list) * This is only for internal list manipulation where we know * the prev/next entries already! */ -static inline void __list_del(struct list_head *prev, struct list_head *next) +static __inline void __list_del(struct list_head *prev, struct list_head *next) { next->prev = prev; prev->next = next; @@ -292,7 +292,7 @@ static inline void __list_del(struct list_head *prev, struct list_head *next) * the entry is in an undefined state. */ -static inline void list_del(struct list_head *entry) +static __inline void list_del(struct list_head *entry) { __list_del(entry->prev, entry->next); entry->next = (void *) 0; @@ -307,7 +307,7 @@ static inline void list_del(struct list_head *entry) * in an undefined state. */ -static inline void __list_del_entry(struct list_head *entry) +static __inline void __list_del_entry(struct list_head *entry) { __list_del(entry->prev, entry->next); } @@ -316,7 +316,7 @@ static inline void __list_del_entry(struct list_head *entry) * @brief deletes entry from list and reinitialize it. * @param entry the element to delete from the list. */ -static inline void list_del_init(struct list_head *entry) +static __inline void list_del_init(struct list_head *entry) { __list_del_entry(entry); INIT_LIST_HEAD(entry); @@ -327,7 +327,7 @@ static inline void list_del_init(struct list_head *entry) * @param list the entry to move * @param head the head that will precede our entry */ -static inline void list_move(struct list_head *list, struct list_head *head) +static __inline void list_move(struct list_head *list, struct list_head *head) { __list_del_entry(list); list_add(list, head); @@ -343,7 +343,7 @@ static inline void list_move(struct list_head *list, struct list_head *head) * This is useful for implementing queues. */ -static inline void list_add_tail(struct list_head *new, struct list_head *head) +static __inline void list_add_tail(struct list_head *new, struct list_head *head) { __list_add(new, head->prev, head); } @@ -357,7 +357,7 @@ static inline void list_add_tail(struct list_head *new, struct list_head *head) * If the old parameter was empty, it will be overwritten. */ -static inline void list_replace(struct list_head *old, +static __inline void list_replace(struct list_head *old, struct list_head *new) { new->next = old->next; @@ -372,7 +372,7 @@ static inline void list_replace(struct list_head *old, * @param entry1 the location to place entry2 * @param entry2 the location to place entry1 */ -static inline void list_swap(struct list_head *entry1, +static __inline void list_swap(struct list_head *entry1, struct list_head *entry2) { struct list_head *pos = entry2->prev; @@ -389,7 +389,7 @@ static inline void list_swap(struct list_head *entry1, * @param head the list to test. */ -static inline int list_empty(struct list_head *head) +static __inline int list_empty(struct list_head *head) { return head->next == head; } @@ -399,7 +399,7 @@ static inline int list_empty(struct list_head *head) * @param head the list to test. */ -static inline int list_filled(struct list_head *head) +static __inline int list_filled(struct list_head *head) { return head->next != head; } @@ -411,7 +411,7 @@ static inline int list_filled(struct list_head *head) * @param head the head that will follow our entry */ -static inline void list_move_tail(struct list_head *list, +static __inline void list_move_tail(struct list_head *list, struct list_head *head) { __list_del(list->prev, list->next); @@ -424,7 +424,7 @@ static inline void list_move_tail(struct list_head *list, * @param head the head of the list */ -static inline void list_rotate_left(struct list_head *head) +static __inline void list_rotate_left(struct list_head *head) { struct list_head *first; diff --git a/lib/common/meson.build b/lib/common/meson.build index f24b91bfd2db2b20694b5f6fd2312f2a448e26a9..1214439e01f215e2fd00920b6032b281209258a5 100644 --- a/lib/common/meson.build +++ b/lib/common/meson.build @@ -2,6 +2,7 @@ common_sources = files([ 'cmp_data_types.c', 'cmp_debug.c', 'cmp_entity.c', + 'cmp_error.c', 'cmp_max_used_bits.c', 'cmp_support.c', 'vsnprintf.c' diff --git a/lib/common/vsnprintf.c b/lib/common/vsnprintf.c index eb3894b478291f90ee230c637c60ab1972f573f4..b1cefe0ed8f19c2d29d8f4ff3cb9e5cfdd36a1c4 100644 --- a/lib/common/vsnprintf.c +++ b/lib/common/vsnprintf.c @@ -29,7 +29,6 @@ #if (DEBUGLEVEL > 0) -#include <stdbool.h> #include <stdint.h> #include <stddef.h> #include <stdarg.h> @@ -150,7 +149,7 @@ typedef struct { /* internal buffer output */ -static inline void _out_buffer(char character, void* buffer, size_t idx, size_t maxlen) +static __inline void _out_buffer(char character, void* buffer, size_t idx, size_t maxlen) { if (idx < maxlen) { ((char*)buffer)[idx] = character; @@ -158,7 +157,7 @@ static inline void _out_buffer(char character, void* buffer, size_t idx, size_t } /* internal null output */ -static inline void _out_null(char character, void* buffer, size_t idx, size_t maxlen) +static __inline void _out_null(char character, void* buffer, size_t idx, size_t maxlen) { (void)character; (void)buffer; (void)idx; (void)maxlen; } @@ -168,7 +167,7 @@ static inline void _out_null(char character, void* buffer, size_t idx, size_t ma * internal secure strlen * @returns The length of the string (excluding the terminating 0) limited by 'maxsize' */ -static inline unsigned int _strnlen_s(const char* str, size_t maxsize) +static __inline unsigned int _strnlen_s(const char* str, size_t maxsize) { const char* s; for (s = str; *s && maxsize--; ++s); @@ -180,7 +179,7 @@ static inline unsigned int _strnlen_s(const char* str, size_t maxsize) * internal test if char is a digit (0-9) * @returns true if char is a digit */ -static inline bool _is_digit(char ch) +static __inline int _is_digit(char ch) { return (ch >= '0') && (ch <= '9'); } @@ -227,7 +226,7 @@ static size_t _out_rev(out_fct_type out, char* buffer, size_t idx, size_t maxlen /* internal itoa format */ -static size_t _ntoa_format(out_fct_type out, char* buffer, size_t idx, size_t maxlen, char* buf, size_t len, bool negative, unsigned int base, unsigned int prec, unsigned int width, unsigned int flags) +static size_t _ntoa_format(out_fct_type out, char* buffer, size_t idx, size_t maxlen, char* buf, size_t len, int negative, unsigned int base, unsigned int prec, unsigned int width, unsigned int flags) { /* pad leading zeros */ if (!(flags & FLAGS_LEFT)) { @@ -281,7 +280,7 @@ static size_t _ntoa_format(out_fct_type out, char* buffer, size_t idx, size_t ma /* internal itoa for 'long' type */ -static size_t _ntoa_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, unsigned long value, bool negative, unsigned long base, unsigned int prec, unsigned int width, unsigned int flags) +static size_t _ntoa_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, unsigned long value, int negative, unsigned long base, unsigned int prec, unsigned int width, unsigned int flags) { char buf[PRINTF_NTOA_BUFFER_SIZE]; size_t len = 0U; @@ -306,7 +305,7 @@ static size_t _ntoa_long(out_fct_type out, char* buffer, size_t idx, size_t maxl /* internal itoa for 'long long' type */ #if defined(PRINTF_SUPPORT_LONG_LONG) -static size_t _ntoa_long_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, unsigned long long value, bool negative, unsigned long long base, unsigned int prec, unsigned int width, unsigned int flags) +static size_t _ntoa_long_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, unsigned long long value, int negative, unsigned long long base, unsigned int prec, unsigned int width, unsigned int flags) { char buf[PRINTF_NTOA_BUFFER_SIZE]; size_t len = 0U; @@ -344,7 +343,7 @@ static size_t _ftoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, d char buf[PRINTF_FTOA_BUFFER_SIZE]; size_t len = 0U; double diff = 0.0; - bool negative = false; + int negative = 0; int whole; double tmp; unsigned long frac; @@ -372,7 +371,7 @@ static size_t _ftoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, d /* test for negative */ if (value < 0) { - negative = true; + negative = 1; value = 0 - value; } @@ -472,7 +471,7 @@ static size_t _ftoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, d /* internal ftoa variant for exponential floating-point type, contributed by Martijn Jasperse <m.jasperse@gmail.com> */ static size_t _etoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags) { - const bool negative = value < 0; + const int negative = value < 0; union { uint64_t U; double F; @@ -750,15 +749,15 @@ static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const /* unsigned */ if (flags & FLAGS_LONG_LONG) { #if defined(PRINTF_SUPPORT_LONG_LONG) - idx = _ntoa_long_long(out, buffer, idx, maxlen, va_arg(va, unsigned long long), false, base, precision, width, flags); + idx = _ntoa_long_long(out, buffer, idx, maxlen, va_arg(va, unsigned long long), 0, base, precision, width, flags); #endif } else if (flags & FLAGS_LONG) { - idx = _ntoa_long(out, buffer, idx, maxlen, va_arg(va, unsigned long), false, base, precision, width, flags); + idx = _ntoa_long(out, buffer, idx, maxlen, va_arg(va, unsigned long), 0, base, precision, width, flags); } else { const unsigned int value = (flags & FLAGS_CHAR) ? (unsigned char)va_arg(va, unsigned int) : (flags & FLAGS_SHORT) ? (unsigned short int)va_arg(va, unsigned int) : va_arg(va, unsigned int); - idx = _ntoa_long(out, buffer, idx, maxlen, value, false, base, precision, width, flags); + idx = _ntoa_long(out, buffer, idx, maxlen, value, 0, base, precision, width, flags); } } format++; @@ -834,11 +833,11 @@ static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const flags |= FLAGS_ZEROPAD | FLAGS_UPPERCASE; #if defined(PRINTF_SUPPORT_LONG_LONG) if (sizeof(uintptr_t) == sizeof(long long)) { - idx = _ntoa_long_long(out, buffer, idx, maxlen, (uintptr_t)va_arg(va, void*), false, 16U, precision, width, flags); + idx = _ntoa_long_long(out, buffer, idx, maxlen, (uintptr_t)va_arg(va, void*), 0, 16U, precision, width, flags); } else { #endif - idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)((uintptr_t)va_arg(va, void*)), false, 16U, precision, width, flags); + idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)((uintptr_t)va_arg(va, void*)), 0, 16U, precision, width, flags); #if defined(PRINTF_SUPPORT_LONG_LONG) } #endif diff --git a/lib/decompress/decmp.c b/lib/decompress/decmp.c index 6d7cf065bc886964e44d13c6453def18603aecf3..82150371abf1d48a293e707da98cf5dc8c316479 100644 --- a/lib/decompress/decmp.c +++ b/lib/decompress/decmp.c @@ -274,24 +274,6 @@ static int decode_multi(const struct decoder_setup *setup, uint32_t *decoded_val } -/** - * @brief get the value unencoded with setup->cmp_par_1 bits without any - * additional changes from the bitstream - * - * @param setup pointer to the decoder setup - * @param decoded_value points to the location where the decoded value is stored - * - * @returns 0 on success; otherwise error - */ - -static int decode_none(const struct decoder_setup *setup, uint32_t *decoded_value) -{ - *decoded_value = bit_read_bits32(setup->dec, setup->encoder_par1); - - return bit_refill(setup->dec) == BIT_OVERFLOW; -} - - /** * @brief remap an unsigned value back to a signed value * @note this is the reverse function of map_to_pos() @@ -331,10 +313,6 @@ static int decode_value(const struct decoder_setup *setup, uint32_t *decoded_val /* decode the next value from the bitstream */ int err = setup->decode_method_f(setup, decoded_value); - if (setup->decode_method_f == decode_none) - /* we are done here in stuff mode */ - return err; - /* map the unsigned decode value back to a signed value */ *decoded_value = re_map_to_pos(*decoded_value); @@ -377,8 +355,6 @@ static void configure_decoder_setup(struct decoder_setup *setup, struct bit_deco setup->decode_method_f = &decode_multi; else if (zero_escape_mech_is_used(cmp_mode)) setup->decode_method_f = &decode_zero; - else if (cmp_mode == CMP_MODE_STUFF) - setup->decode_method_f = &decode_none; else { debug_print("Error: Compression mode not supported."); assert(0); diff --git a/lib/icu_compress/cmp_icu.c b/lib/icu_compress/cmp_icu.c index 22919272f034cc8d64da0a9a7dc98a8d7d8deb71..b0fd6cd2caba1588b1f88eac378b93217da3edf9 100644 --- a/lib/icu_compress/cmp_icu.c +++ b/lib/icu_compress/cmp_icu.c @@ -15,16 +15,6 @@ * * @brief software compression library * @see Data Compression User Manual PLATO-UVIE-PL-UM-0001 - * - * To compress data, first create a compression configuration with the - * cmp_cfg_icu_create() function. - * Then set the different data buffers with the data to compressed, the model - * data and the compressed data with the cmp_cfg_icu_buffers() function. - * Then set the compression data type specific compression parameters. For - * imagette data use the cmp_cfg_icu_imagette() function. For flux and center of - * brightness data use the cmp_cfg_fx_cob() function. And for background, offset - * and smearing data use the cmp_cfg_aux() function. - * Finally, you can compress the data with the icu_compress_data() function. */ @@ -37,6 +27,8 @@ #include "../common/cmp_data_types.h" #include "../common/cmp_support.h" #include "../common/cmp_entity.h" +#include "../common/cmp_error.h" +#include "../common/leon_inttypes.h" #include "../cmp_icu.h" #include "../cmp_chunk.h" @@ -82,10 +74,10 @@ typedef uint32_t (*generate_cw_f_pt)(uint32_t value, uint32_t encoder_par1, * @brief structure to hold a setup to encode a value */ -struct encoder_setupt { +struct encoder_setup { generate_cw_f_pt generate_cw_f; /**< function pointer to a code word encoder */ - int (*encode_method_f)(uint32_t data, uint32_t model, int stream_len, - const struct encoder_setupt *setup); /**< pointer to the encoding function */ + uint32_t (*encode_method_f)(uint32_t data, uint32_t model, uint32_t stream_len, + const struct encoder_setup *setup); /**< pointer to the encoding function */ uint32_t *bitstream_adr; /**< start address of the compressed data bitstream */ uint32_t max_stream_len; /**< maximum length of the bitstream/icu_output_buf in bits */ uint32_t encoder_par1; /**< encoding parameter 1 */ @@ -96,23 +88,6 @@ struct encoder_setupt { }; -/** - * @brief types of chunks containing different types of collections - * according to DetailedBudgetWorking_2023-10-11 - */ - -enum chunk_type { - CHUNK_TYPE_UNKNOWN, - CHUNK_TYPE_NCAM_IMAGETTE, - CHUNK_TYPE_SHORT_CADENCE, - CHUNK_TYPE_LONG_CADENCE, - CHUNK_TYPE_SAT_IMAGETTE, - CHUNK_TYPE_OFFSET_BACKGROUND, /* N-CAM */ - CHUNK_TYPE_SMEARING, - CHUNK_TYPE_F_CHAIN -}; - - /** * @brief create an ICU compression configuration * @@ -217,13 +192,13 @@ uint32_t cmp_cfg_icu_buffers(struct cmp_cfg *cfg, void *data_to_compress, /** - * @brief set up the maximum length of the different data products types for + * @brief set up the maximum length of the different data product types for * an ICU compression * * @param cfg pointer to a compression configuration (created with the * cmp_cfg_icu_create() function) * @param max_used_bits pointer to a max_used_bits struct containing the maximum - * length of the different data products types + * length of the different data product types * * @returns 0 if all max_used_bits parameters are valid, non-zero if parameters are invalid * @@ -330,7 +305,7 @@ int cmp_cfg_fx_cob(struct cmp_cfg *cfg, * @brief set up the configuration parameters for an auxiliary science data compression * @note auxiliary compression data types are: DATA_TYPE_OFFSET, DATA_TYPE_BACKGROUND, DATA_TYPE_SMEARING, DATA_TYPE_F_CAM_OFFSET, DATA_TYPE_F_CAM_BACKGROUND - * @note not all parameters are needed for the every auxiliary compression data type + * @note not all parameters are needed for every auxiliary compression data type * * @param cfg pointer to a compression configuration (created * with the cmp_cfg_icu_create() function) @@ -419,7 +394,7 @@ static uint32_t map_to_pos(uint32_t value_to_map, unsigned int max_data_bits) /** - * @brief put the value of up to 32 bits into a big endian bitstream + * @brief put the value of up to 32 bits into a big-endian bitstream * * @param value the value to put into the bitstream * @param n_bits number of bits to put into the bitstream @@ -430,12 +405,13 @@ static uint32_t map_to_pos(uint32_t value_to_map, unsigned int max_data_bits) * @param max_stream_len maximum length of the bitstream in *bits*; is * ignored if bitstream_adr is NULL * - * @returns length in bits of the generated bitstream on success; returns - * negative in case of erroneous input; returns CMP_ERROR_SMALL_BUF if - * the bitstream buffer is too small to put the value in the bitstream + * @returns the length of the generated bitstream in bits on success or an error + * code (which can be tested with cmp_is_error()) in the event of an + * incorrect input or if the bitstream buffer is too small to put the + * value in the bitstream. */ -static int put_n_bits32(uint32_t value, unsigned int n_bits, int bit_offset, +static uint32_t put_n_bits32(uint32_t value, unsigned int n_bits, uint32_t bit_offset, uint32_t *bitstream_adr, unsigned int max_stream_len) { /* @@ -448,29 +424,25 @@ static int put_n_bits32(uint32_t value, unsigned int n_bits, int bit_offset, * |-----------------------------|XXX|XXX|-----------------------------| * |----------bits_left----------|n_bits-|---------bits_right----------| */ - unsigned int bits_left = bit_offset & 0x1F; - unsigned int bits_right = 64 - bits_left - n_bits; - unsigned int shift_left = 32 - n_bits; - int stream_len = (int)(n_bits + (unsigned int)bit_offset); + uint32_t bits_left = bit_offset & 0x1F; + uint32_t bits_right = 64 - bits_left - n_bits; + uint32_t shift_left = 32 - n_bits; + uint32_t stream_len = n_bits + bit_offset; /* no check for overflow */ uint32_t *local_adr; uint32_t mask, tmp; /* Leave in case of erroneous input */ - if (bit_offset < 0) - return -1; + RETURN_ERROR_IF((int)shift_left < 0, INT_DECODER, "cannot insert more than 32 bits into the bit stream"); /* check n_bits <= 32 */ if (n_bits == 0) return stream_len; - if ((int)shift_left < 0) /* check n_bits <= 32 */ - return -1; - if (!bitstream_adr) /* Do we need to write data to the bitstream? */ return stream_len; - /* Check if bitstream buffer is large enough */ - if ((unsigned int)stream_len > max_stream_len) - return CMP_ERROR_SMALL_BUF; + /* Check if the bitstream buffer is large enough */ + if (stream_len > max_stream_len) + return CMP_ERROR(SMALL_BUF_); local_adr = bitstream_adr + (bit_offset >> 5); @@ -502,15 +474,15 @@ static int put_n_bits32(uint32_t value, unsigned int n_bits, int bit_offset, * @brief forms the codeword according to the Rice code * * @param value value to be encoded (must be smaller or equal than cmp_ima_max_spill(m)) - * @param m Golomb parameter, only m's which are power of 2 are allowed + * @param m Golomb parameter, only m's which are a power of 2 are allowed * maximum allowed Golomb parameter is 0x80000000 * @param log2_m Rice parameter, is ilog_2(m) calculate outside function * for better performance * @param cw address where the code word is stored * * @warning no check of the validity of the input parameters! - * @returns the length of the formed code word in bits; code word is invalid if - * the return value is greater than 32 + * @returns the length of the formed code word in bits; the code word is invalid + * if the return value is greater than 32 */ static uint32_t rice_encoder(uint32_t value, uint32_t m, uint32_t log2_m, @@ -543,8 +515,8 @@ static uint32_t rice_encoder(uint32_t value, uint32_t m, uint32_t log2_m, * @param cw address where the code word is stored * * @warning no check of the validity of the input parameters! - * @returns the length of the formed code word in bits; code word is invalid if - * the return value is greater than 32 + * @returns the length of the formed code word in bits; the code word is invalid + * if the return value is greater than 32 */ static uint32_t golomb_encoder(uint32_t value, uint32_t m, uint32_t log2_m, @@ -571,7 +543,7 @@ static uint32_t golomb_encoder(uint32_t value, uint32_t m, uint32_t log2_m, /** - * @brief generate a code word without an outlier mechanism and put in the + * @brief generate a code word without an outlier mechanism and put it in the * bitstream * * @param value value to encode in the bitstream @@ -583,8 +555,8 @@ static uint32_t golomb_encoder(uint32_t value, uint32_t m, uint32_t log2_m, * is too small to put the value in the bitstream */ -static int encode_normal(uint32_t value, int stream_len, - const struct encoder_setupt *setup) +static uint32_t encode_normal(uint32_t value, uint32_t stream_len, + const struct encoder_setup *setup) { uint32_t code_word, cw_len; @@ -597,7 +569,7 @@ static int encode_normal(uint32_t value, int stream_len, /** - * @brief subtract the model from the data, encode the result and put it into + * @brief subtract the model from the data, encode the result and puts it into * bitstream, for encoding outlier use the zero escape symbol mechanism * * @param data data to encode @@ -613,8 +585,8 @@ static int encode_normal(uint32_t value, int stream_len, * @note no check if the setup->spillover_par is in the allowed range */ -static int encode_value_zero(uint32_t data, uint32_t model, int stream_len, - const struct encoder_setupt *setup) +static uint32_t encode_value_zero(uint32_t data, uint32_t model, uint32_t stream_len, + const struct encoder_setup *setup) { data -= model; /* possible underflow is intended */ @@ -635,13 +607,12 @@ static int encode_value_zero(uint32_t data, uint32_t model, int stream_len, /* use zero as escape symbol */ stream_len = encode_normal(0, stream_len, setup); - if (stream_len <= 0) + if (cmp_is_error(stream_len)) return stream_len; /* put the data unencoded in the bitstream */ stream_len = put_n_bits32(data, setup->max_data_bits, stream_len, setup->bitstream_adr, setup->max_stream_len); - return stream_len; } @@ -663,8 +634,8 @@ static int encode_value_zero(uint32_t data, uint32_t model, int stream_len, * @note no check if the setup->spillover_par is in the allowed range */ -static int encode_value_multi(uint32_t data, uint32_t model, int stream_len, - const struct encoder_setupt *setup) +static uint32_t encode_value_multi(uint32_t data, uint32_t model, uint32_t stream_len, + const struct encoder_setup *setup) { uint32_t unencoded_data; unsigned int unencoded_data_len; @@ -680,9 +651,9 @@ static int encode_value_multi(uint32_t data, uint32_t model, int stream_len, /* * In this mode we put the difference between the data and the spillover * threshold value (unencoded_data) after an encoded escape symbol, which - * indicate that the next codeword is unencoded. - * We use different escape symbol depended on the size the needed bit of - * unencoded data: + * indicates that the next codeword is unencoded. + * We use different escape symbols depending on the size of the needed + * bit of unencoded data: * 0, 1, 2 bits needed for unencoded data -> escape symbol is spillover_par + 0 * 3, 4 bits needed for unencoded data -> escape symbol is spillover_par + 1 * 5, 6 bits needed for unencoded data -> escape symbol is spillover_par + 2 @@ -700,43 +671,16 @@ static int encode_value_multi(uint32_t data, uint32_t model, int stream_len, /* put the escape symbol in the bitstream */ stream_len = encode_normal(escape_sym, stream_len, setup); - if (stream_len <= 0) + if (cmp_is_error(stream_len)) return stream_len; /* put the unencoded data in the bitstream */ stream_len = put_n_bits32(unencoded_data, unencoded_data_len, stream_len, setup->bitstream_adr, setup->max_stream_len); - return stream_len; } -/** - * @brief put the value unencoded with setup->cmp_par_1 bits without any changes - * in the bitstream - * - * @param value value to put unchanged in the bitstream - * (setup->cmp_par_1 how many bits of the value are used) - * @param unused this parameter is ignored - * @param stream_len length of the bitstream in bits - * @param setup pointer to the encoder setup - * - * @returns the bit length of the bitstream with the added unencoded value on - * success; negative on error, CMP_ERROR_SMALL_BUF if the bitstream buffer - * is too small to put the value in the bitstream - * - */ - -static int encode_value_none(uint32_t value, uint32_t unused, int stream_len, - const struct encoder_setupt *setup) -{ - (void)(unused); - - return put_n_bits32(value, setup->encoder_par1, stream_len, - setup->bitstream_adr, setup->max_stream_len); -} - - /** * @brief encodes the data with the model and the given setup and put it into * the bitstream @@ -752,8 +696,8 @@ static int encode_value_none(uint32_t value, uint32_t unused, int stream_len, * the value or the model is bigger than the max_used_bits parameter allows */ -static int encode_value(uint32_t data, uint32_t model, int stream_len, - const struct encoder_setupt *setup) +static uint32_t encode_value(uint32_t data, uint32_t model, uint32_t stream_len, + const struct encoder_setup *setup) { uint32_t mask = ~(0xFFFFFFFFU >> (32-setup->max_data_bits)); @@ -761,10 +705,7 @@ static int encode_value(uint32_t data, uint32_t model, int stream_len, data = round_fwd(data, setup->lossy_par); model = round_fwd(model, setup->lossy_par); - if (data & mask || model & mask) { - debug_print("Error: The data or the model of the data are bigger than expected."); - return CMP_ERROR_HIGH_VALUE; - } + RETURN_ERROR_IF(data & mask || model & mask, DATA_VALUE_TOO_LARGE, ""); return setup->encode_method_f(data, model, stream_len, setup); } @@ -799,29 +740,26 @@ static uint32_t cmp_buffer_length_to_bits(uint32_t buffer_length) * @warning input parameters are not checked for validity */ -static void configure_encoder_setup(struct encoder_setupt *setup, +static void configure_encoder_setup(struct encoder_setup *setup, uint32_t cmp_par, uint32_t spillover, uint32_t lossy_par, uint32_t max_data_bits, const struct cmp_cfg *cfg) { - memset(setup, 0, sizeof(struct encoder_setupt)); + memset(setup, 0, sizeof(struct encoder_setup)); setup->encoder_par1 = cmp_par; setup->max_data_bits = max_data_bits; setup->lossy_par = lossy_par; setup->bitstream_adr = cfg->icu_output_buf; setup->max_stream_len = cmp_buffer_length_to_bits(cfg->buffer_length); + setup->encoder_par2 = ilog_2(cmp_par); + setup->spillover_par = spillover; - if (cfg->cmp_mode != CMP_MODE_STUFF) { - setup->encoder_par2 = ilog_2(cmp_par); - setup->spillover_par = spillover; - - /* for encoder_par1 which are a power of two we can use the faster rice_encoder */ - if (is_a_pow_of_2(setup->encoder_par1)) - setup->generate_cw_f = &rice_encoder; - else - setup->generate_cw_f = &golomb_encoder; - } + /* for encoder_par1 which are a power of two we can use the faster rice_encoder */ + if (is_a_pow_of_2(setup->encoder_par1)) + setup->generate_cw_f = &rice_encoder; + else + setup->generate_cw_f = &golomb_encoder; switch (cfg->cmp_mode) { case CMP_MODE_MODEL_ZERO: @@ -832,10 +770,6 @@ static void configure_encoder_setup(struct encoder_setupt *setup, case CMP_MODE_DIFF_MULTI: setup->encode_method_f = &encode_value_multi; break; - case CMP_MODE_STUFF: - setup->encode_method_f = &encode_value_none; - setup->max_data_bits = cmp_par; - break; /* LCOV_EXCL_START */ case CMP_MODE_RAW: /* CMP_MODE_RAW is already handled before; nothing to do here */ @@ -856,10 +790,10 @@ static void configure_encoder_setup(struct encoder_setupt *setup, * bigger than the max_used_bits parameter allows */ -static int compress_imagette(const struct cmp_cfg *cfg, int stream_len) +static uint32_t compress_imagette(const struct cmp_cfg *cfg, uint32_t stream_len) { size_t i; - struct encoder_setupt setup; + struct encoder_setup setup; uint32_t max_data_bits; uint16_t *data_buf = cfg->input_buf; @@ -896,7 +830,7 @@ static int compress_imagette(const struct cmp_cfg *cfg, int stream_len) for (i = 0;; i++) { stream_len = encode_value(get_unaligned(&data_buf[i]), model, stream_len, &setup); - if (stream_len <= 0) + if (cmp_is_error(stream_len)) break; if (up_model_buf) { @@ -923,7 +857,7 @@ static int compress_imagette(const struct cmp_cfg *cfg, int stream_len) * value in the bitstream */ -static int compress_s_fx(const struct cmp_cfg *cfg, int stream_len) +static uint32_t compress_s_fx(const struct cmp_cfg *cfg, uint32_t stream_len) { size_t i; @@ -932,7 +866,7 @@ static int compress_s_fx(const struct cmp_cfg *cfg, int stream_len) struct s_fx *up_model_buf = NULL; struct s_fx *next_model_p; struct s_fx model; - struct encoder_setupt setup_exp_flag, setup_fx; + struct encoder_setup setup_exp_flag, setup_fx; if (model_mode_is_used(cfg->cmp_mode)) { model = model_buf[0]; @@ -951,12 +885,12 @@ static int compress_s_fx(const struct cmp_cfg *cfg, int stream_len) for (i = 0;; i++) { stream_len = encode_value(data_buf[i].exp_flags, model.exp_flags, stream_len, &setup_exp_flag); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; stream_len = encode_value(data_buf[i].fx, model.fx, stream_len, &setup_fx); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; if (up_model_buf) { up_model_buf[i].exp_flags = cmp_up_model(data_buf[i].exp_flags, model.exp_flags, @@ -984,7 +918,7 @@ static int compress_s_fx(const struct cmp_cfg *cfg, int stream_len) * value in the bitstream */ -static int compress_s_fx_efx(const struct cmp_cfg *cfg, int stream_len) +static uint32_t compress_s_fx_efx(const struct cmp_cfg *cfg, uint32_t stream_len) { size_t i; @@ -993,7 +927,7 @@ static int compress_s_fx_efx(const struct cmp_cfg *cfg, int stream_len) struct s_fx_efx *up_model_buf = NULL; struct s_fx_efx *next_model_p; struct s_fx_efx model; - struct encoder_setupt setup_exp_flag, setup_fx, setup_efx; + struct encoder_setup setup_exp_flag, setup_fx, setup_efx; if (model_mode_is_used(cfg->cmp_mode)) { model = model_buf[0]; @@ -1014,15 +948,15 @@ static int compress_s_fx_efx(const struct cmp_cfg *cfg, int stream_len) for (i = 0;; i++) { stream_len = encode_value(data_buf[i].exp_flags, model.exp_flags, stream_len, &setup_exp_flag); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; stream_len = encode_value(data_buf[i].fx, model.fx, stream_len, &setup_fx); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; stream_len = encode_value(data_buf[i].efx, model.efx, stream_len, &setup_efx); - if (stream_len <= 0) + if (cmp_is_error(stream_len)) return stream_len; if (up_model_buf) { @@ -1053,7 +987,7 @@ static int compress_s_fx_efx(const struct cmp_cfg *cfg, int stream_len) * value in the bitstream */ -static int compress_s_fx_ncob(const struct cmp_cfg *cfg, int stream_len) +static uint32_t compress_s_fx_ncob(const struct cmp_cfg *cfg, uint32_t stream_len) { size_t i; @@ -1062,7 +996,7 @@ static int compress_s_fx_ncob(const struct cmp_cfg *cfg, int stream_len) struct s_fx_ncob *up_model_buf = NULL; struct s_fx_ncob *next_model_p; struct s_fx_ncob model; - struct encoder_setupt setup_exp_flag, setup_fx, setup_ncob; + struct encoder_setup setup_exp_flag, setup_fx, setup_ncob; if (model_mode_is_used(cfg->cmp_mode)) { model = model_buf[0]; @@ -1083,20 +1017,20 @@ static int compress_s_fx_ncob(const struct cmp_cfg *cfg, int stream_len) for (i = 0;; i++) { stream_len = encode_value(data_buf[i].exp_flags, model.exp_flags, stream_len, &setup_exp_flag); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; stream_len = encode_value(data_buf[i].fx, model.fx, stream_len, &setup_fx); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; stream_len = encode_value(data_buf[i].ncob_x, model.ncob_x, stream_len, &setup_ncob); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; stream_len = encode_value(data_buf[i].ncob_y, model.ncob_y, stream_len, &setup_ncob); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; if (up_model_buf) { up_model_buf[i].exp_flags = cmp_up_model(data_buf[i].exp_flags, model.exp_flags, @@ -1128,7 +1062,7 @@ static int compress_s_fx_ncob(const struct cmp_cfg *cfg, int stream_len) * value in the bitstream */ -static int compress_s_fx_efx_ncob_ecob(const struct cmp_cfg *cfg, int stream_len) +static uint32_t compress_s_fx_efx_ncob_ecob(const struct cmp_cfg *cfg, uint32_t stream_len) { size_t i; @@ -1137,7 +1071,7 @@ static int compress_s_fx_efx_ncob_ecob(const struct cmp_cfg *cfg, int stream_len struct s_fx_efx_ncob_ecob *up_model_buf = NULL; struct s_fx_efx_ncob_ecob *next_model_p; struct s_fx_efx_ncob_ecob model; - struct encoder_setupt setup_exp_flag, setup_fx, setup_ncob, setup_efx, + struct encoder_setup setup_exp_flag, setup_fx, setup_ncob, setup_efx, setup_ecob; if (model_mode_is_used(cfg->cmp_mode)) { @@ -1163,32 +1097,32 @@ static int compress_s_fx_efx_ncob_ecob(const struct cmp_cfg *cfg, int stream_len for (i = 0;; i++) { stream_len = encode_value(data_buf[i].exp_flags, model.exp_flags, stream_len, &setup_exp_flag); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; stream_len = encode_value(data_buf[i].fx, model.fx, stream_len, &setup_fx); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; stream_len = encode_value(data_buf[i].ncob_x, model.ncob_x, stream_len, &setup_ncob); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; stream_len = encode_value(data_buf[i].ncob_y, model.ncob_y, stream_len, &setup_ncob); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; stream_len = encode_value(data_buf[i].efx, model.efx, stream_len, &setup_efx); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; stream_len = encode_value(data_buf[i].ecob_x, model.ecob_x, stream_len, &setup_ecob); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; stream_len = encode_value(data_buf[i].ecob_y, model.ecob_y, stream_len, &setup_ecob); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; if (up_model_buf) { up_model_buf[i].exp_flags = cmp_up_model(data_buf[i].exp_flags, model.exp_flags, @@ -1226,7 +1160,7 @@ static int compress_s_fx_efx_ncob_ecob(const struct cmp_cfg *cfg, int stream_len * value in the bitstream */ -static int compress_f_fx(const struct cmp_cfg *cfg, int stream_len) +static uint32_t compress_f_fx(const struct cmp_cfg *cfg, uint32_t stream_len) { size_t i; @@ -1235,7 +1169,7 @@ static int compress_f_fx(const struct cmp_cfg *cfg, int stream_len) struct f_fx *up_model_buf = NULL; struct f_fx *next_model_p; struct f_fx model; - struct encoder_setupt setup_fx; + struct encoder_setup setup_fx; if (model_mode_is_used(cfg->cmp_mode)) { model = model_buf[0]; @@ -1252,8 +1186,8 @@ static int compress_f_fx(const struct cmp_cfg *cfg, int stream_len) for (i = 0;; i++) { stream_len = encode_value(data_buf[i].fx, model.fx, stream_len, &setup_fx); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; if (up_model_buf) { up_model_buf[i].fx = cmp_up_model(data_buf[i].fx, model.fx, @@ -1279,7 +1213,7 @@ static int compress_f_fx(const struct cmp_cfg *cfg, int stream_len) * value in the bitstream */ -static int compress_f_fx_efx(const struct cmp_cfg *cfg, int stream_len) +static uint32_t compress_f_fx_efx(const struct cmp_cfg *cfg, uint32_t stream_len) { size_t i; @@ -1288,7 +1222,7 @@ static int compress_f_fx_efx(const struct cmp_cfg *cfg, int stream_len) struct f_fx_efx *up_model_buf = NULL; struct f_fx_efx *next_model_p; struct f_fx_efx model; - struct encoder_setupt setup_fx, setup_efx; + struct encoder_setup setup_fx, setup_efx; if (model_mode_is_used(cfg->cmp_mode)) { model = model_buf[0]; @@ -1307,12 +1241,12 @@ static int compress_f_fx_efx(const struct cmp_cfg *cfg, int stream_len) for (i = 0;; i++) { stream_len = encode_value(data_buf[i].fx, model.fx, stream_len, &setup_fx); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; stream_len = encode_value(data_buf[i].efx, model.efx, stream_len, &setup_efx); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; if (up_model_buf) { up_model_buf[i].fx = cmp_up_model(data_buf[i].fx, model.fx, @@ -1340,7 +1274,7 @@ static int compress_f_fx_efx(const struct cmp_cfg *cfg, int stream_len) * value in the bitstream */ -static int compress_f_fx_ncob(const struct cmp_cfg *cfg, int stream_len) +static uint32_t compress_f_fx_ncob(const struct cmp_cfg *cfg, uint32_t stream_len) { size_t i; @@ -1349,7 +1283,7 @@ static int compress_f_fx_ncob(const struct cmp_cfg *cfg, int stream_len) struct f_fx_ncob *up_model_buf = NULL; struct f_fx_ncob *next_model_p; struct f_fx_ncob model; - struct encoder_setupt setup_fx, setup_ncob; + struct encoder_setup setup_fx, setup_ncob; if (model_mode_is_used(cfg->cmp_mode)) { model = model_buf[0]; @@ -1368,16 +1302,16 @@ static int compress_f_fx_ncob(const struct cmp_cfg *cfg, int stream_len) for (i = 0;; i++) { stream_len = encode_value(data_buf[i].fx, model.fx, stream_len, &setup_fx); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; stream_len = encode_value(data_buf[i].ncob_x, model.ncob_x, stream_len, &setup_ncob); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; stream_len = encode_value(data_buf[i].ncob_y, model.ncob_y, stream_len, &setup_ncob); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; if (up_model_buf) { up_model_buf[i].fx = cmp_up_model(data_buf[i].fx, model.fx, @@ -1407,7 +1341,7 @@ static int compress_f_fx_ncob(const struct cmp_cfg *cfg, int stream_len) * value in the bitstream */ -static int compress_f_fx_efx_ncob_ecob(const struct cmp_cfg *cfg, int stream_len) +static uint32_t compress_f_fx_efx_ncob_ecob(const struct cmp_cfg *cfg, uint32_t stream_len) { size_t i; @@ -1416,7 +1350,7 @@ static int compress_f_fx_efx_ncob_ecob(const struct cmp_cfg *cfg, int stream_len struct f_fx_efx_ncob_ecob *up_model_buf = NULL; struct f_fx_efx_ncob_ecob *next_model_p; struct f_fx_efx_ncob_ecob model; - struct encoder_setupt setup_fx, setup_ncob, setup_efx, setup_ecob; + struct encoder_setup setup_fx, setup_ncob, setup_efx, setup_ecob; if (model_mode_is_used(cfg->cmp_mode)) { model = model_buf[0]; @@ -1439,28 +1373,28 @@ static int compress_f_fx_efx_ncob_ecob(const struct cmp_cfg *cfg, int stream_len for (i = 0;; i++) { stream_len = encode_value(data_buf[i].fx, model.fx, stream_len, &setup_fx); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; stream_len = encode_value(data_buf[i].ncob_x, model.ncob_x, stream_len, &setup_ncob); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; stream_len = encode_value(data_buf[i].ncob_y, model.ncob_y, stream_len, &setup_ncob); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; stream_len = encode_value(data_buf[i].efx, model.efx, stream_len, &setup_efx); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; stream_len = encode_value(data_buf[i].ecob_x, model.ecob_x, stream_len, &setup_ecob); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; stream_len = encode_value(data_buf[i].ecob_y, model.ecob_y, stream_len, &setup_ecob); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; if (up_model_buf) { up_model_buf[i].fx = cmp_up_model(data_buf[i].fx, model.fx, @@ -1496,7 +1430,7 @@ static int compress_f_fx_efx_ncob_ecob(const struct cmp_cfg *cfg, int stream_len * value in the bitstream */ -static int compress_l_fx(const struct cmp_cfg *cfg, int stream_len) +static uint32_t compress_l_fx(const struct cmp_cfg *cfg, uint32_t stream_len) { size_t i; @@ -1505,7 +1439,7 @@ static int compress_l_fx(const struct cmp_cfg *cfg, int stream_len) struct l_fx *up_model_buf = NULL; struct l_fx *next_model_p; struct l_fx model; - struct encoder_setupt setup_exp_flag, setup_fx, setup_fx_var; + struct encoder_setup setup_exp_flag, setup_fx, setup_fx_var; if (model_mode_is_used(cfg->cmp_mode)) { model = model_buf[0]; @@ -1526,16 +1460,16 @@ static int compress_l_fx(const struct cmp_cfg *cfg, int stream_len) for (i = 0;; i++) { stream_len = encode_value(data_buf[i].exp_flags, model.exp_flags, stream_len, &setup_exp_flag); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; stream_len = encode_value(data_buf[i].fx, model.fx, stream_len, &setup_fx); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; stream_len = encode_value(data_buf[i].fx_variance, model.fx_variance, stream_len, &setup_fx_var); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; if (up_model_buf) { up_model_buf[i].exp_flags = cmp_up_model32(data_buf[i].exp_flags, model.exp_flags, @@ -1565,7 +1499,7 @@ static int compress_l_fx(const struct cmp_cfg *cfg, int stream_len) * value in the bitstream */ -static int compress_l_fx_efx(const struct cmp_cfg *cfg, int stream_len) +static uint32_t compress_l_fx_efx(const struct cmp_cfg *cfg, uint32_t stream_len) { size_t i; @@ -1574,7 +1508,7 @@ static int compress_l_fx_efx(const struct cmp_cfg *cfg, int stream_len) struct l_fx_efx *up_model_buf = NULL; struct l_fx_efx *next_model_p; struct l_fx_efx model; - struct encoder_setupt setup_exp_flag, setup_fx, setup_efx, setup_fx_var; + struct encoder_setup setup_exp_flag, setup_fx, setup_efx, setup_fx_var; if (model_mode_is_used(cfg->cmp_mode)) { model = model_buf[0]; @@ -1597,20 +1531,20 @@ static int compress_l_fx_efx(const struct cmp_cfg *cfg, int stream_len) for (i = 0;; i++) { stream_len = encode_value(data_buf[i].exp_flags, model.exp_flags, stream_len, &setup_exp_flag); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; stream_len = encode_value(data_buf[i].fx, model.fx, stream_len, &setup_fx); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; stream_len = encode_value(data_buf[i].efx, model.efx, stream_len, &setup_efx); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; stream_len = encode_value(data_buf[i].fx_variance, model.fx_variance, stream_len, &setup_fx_var); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; if (up_model_buf) { up_model_buf[i].exp_flags = cmp_up_model32(data_buf[i].exp_flags, model.exp_flags, @@ -1642,7 +1576,7 @@ static int compress_l_fx_efx(const struct cmp_cfg *cfg, int stream_len) * value in the bitstream */ -static int compress_l_fx_ncob(const struct cmp_cfg *cfg, int stream_len) +static uint32_t compress_l_fx_ncob(const struct cmp_cfg *cfg, uint32_t stream_len) { size_t i; @@ -1651,7 +1585,7 @@ static int compress_l_fx_ncob(const struct cmp_cfg *cfg, int stream_len) struct l_fx_ncob *up_model_buf = NULL; struct l_fx_ncob *next_model_p; struct l_fx_ncob model; - struct encoder_setupt setup_exp_flag, setup_fx, setup_ncob, + struct encoder_setup setup_exp_flag, setup_fx, setup_ncob, setup_fx_var, setup_cob_var; if (model_mode_is_used(cfg->cmp_mode)) { @@ -1669,7 +1603,7 @@ static int compress_l_fx_ncob(const struct cmp_cfg *cfg, int stream_len) cfg->round, cfg->max_used_bits->l_fx, cfg); configure_encoder_setup(&setup_ncob, cfg->cmp_par_ncob, cfg->spill_ncob, cfg->round, cfg->max_used_bits->l_ncob, cfg); - /* we use compression parameter for both variance data fields */ + /* we use the cmp_par_fx_cob_variance parameter for fx and cob variance data */ configure_encoder_setup(&setup_fx_var, cfg->cmp_par_fx_cob_variance, cfg->spill_fx_cob_variance, cfg->round, cfg->max_used_bits->l_fx_variance, cfg); configure_encoder_setup(&setup_cob_var, cfg->cmp_par_fx_cob_variance, cfg->spill_fx_cob_variance, @@ -1678,32 +1612,32 @@ static int compress_l_fx_ncob(const struct cmp_cfg *cfg, int stream_len) for (i = 0;; i++) { stream_len = encode_value(data_buf[i].exp_flags, model.exp_flags, stream_len, &setup_exp_flag); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; stream_len = encode_value(data_buf[i].fx, model.fx, stream_len, &setup_fx); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; stream_len = encode_value(data_buf[i].ncob_x, model.ncob_x, stream_len, &setup_ncob); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; stream_len = encode_value(data_buf[i].ncob_y, model.ncob_y, stream_len, &setup_ncob); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; stream_len = encode_value(data_buf[i].fx_variance, model.fx_variance, stream_len, &setup_fx_var); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; stream_len = encode_value(data_buf[i].cob_x_variance, model.cob_x_variance, stream_len, &setup_cob_var); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; stream_len = encode_value(data_buf[i].cob_y_variance, model.cob_y_variance, stream_len, &setup_cob_var); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; if (up_model_buf) { up_model_buf[i].exp_flags = cmp_up_model32(data_buf[i].exp_flags, model.exp_flags, @@ -1741,7 +1675,7 @@ static int compress_l_fx_ncob(const struct cmp_cfg *cfg, int stream_len) * value in the bitstream */ -static int compress_l_fx_efx_ncob_ecob(const struct cmp_cfg *cfg, int stream_len) +static uint32_t compress_l_fx_efx_ncob_ecob(const struct cmp_cfg *cfg, uint32_t stream_len) { size_t i; @@ -1750,7 +1684,7 @@ static int compress_l_fx_efx_ncob_ecob(const struct cmp_cfg *cfg, int stream_len struct l_fx_efx_ncob_ecob *up_model_buf = NULL; struct l_fx_efx_ncob_ecob *next_model_p; struct l_fx_efx_ncob_ecob model; - struct encoder_setupt setup_exp_flag, setup_fx, setup_ncob, setup_efx, + struct encoder_setup setup_exp_flag, setup_fx, setup_ncob, setup_efx, setup_ecob, setup_fx_var, setup_cob_var; if (model_mode_is_used(cfg->cmp_mode)) { @@ -1781,44 +1715,44 @@ static int compress_l_fx_efx_ncob_ecob(const struct cmp_cfg *cfg, int stream_len for (i = 0;; i++) { stream_len = encode_value(data_buf[i].exp_flags, model.exp_flags, stream_len, &setup_exp_flag); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; stream_len = encode_value(data_buf[i].fx, model.fx, stream_len, &setup_fx); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; stream_len = encode_value(data_buf[i].ncob_x, model.ncob_x, stream_len, &setup_ncob); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; stream_len = encode_value(data_buf[i].ncob_y, model.ncob_y, stream_len, &setup_ncob); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; stream_len = encode_value(data_buf[i].efx, model.efx, stream_len, &setup_efx); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; stream_len = encode_value(data_buf[i].ecob_x, model.ecob_x, stream_len, &setup_ecob); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; stream_len = encode_value(data_buf[i].ecob_y, model.ecob_y, stream_len, &setup_ecob); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; stream_len = encode_value(data_buf[i].fx_variance, model.fx_variance, stream_len, &setup_fx_var); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; stream_len = encode_value(data_buf[i].cob_x_variance, model.cob_x_variance, stream_len, &setup_cob_var); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; stream_len = encode_value(data_buf[i].cob_y_variance, model.cob_y_variance, stream_len, &setup_cob_var); - if (stream_len <= 0) - return stream_len; + if (cmp_is_error(stream_len)) + break; if (up_model_buf) { up_model_buf[i].exp_flags = cmp_up_model32(data_buf[i].exp_flags, model.exp_flags, @@ -1861,7 +1795,7 @@ static int compress_l_fx_efx_ncob_ecob(const struct cmp_cfg *cfg, int stream_len * value in the bitstream */ -static int compress_offset(const struct cmp_cfg *cfg, int stream_len) +static uint32_t compress_offset(const struct cmp_cfg *cfg, uint32_t stream_len) { size_t i; @@ -1870,7 +1804,7 @@ static int compress_offset(const struct cmp_cfg *cfg, int stream_len) struct offset *up_model_buf = NULL; struct offset *next_model_p; struct offset model; - struct encoder_setupt setup_mean, setup_var; + struct encoder_setup setup_mean, setup_var; if (model_mode_is_used(cfg->cmp_mode)) { model = model_buf[0]; @@ -1904,11 +1838,11 @@ static int compress_offset(const struct cmp_cfg *cfg, int stream_len) for (i = 0;; i++) { stream_len = encode_value(data_buf[i].mean, model.mean, stream_len, &setup_mean); - if (stream_len <= 0) + if (cmp_is_error(stream_len)) return stream_len; stream_len = encode_value(data_buf[i].variance, model.variance, stream_len, &setup_var); - if (stream_len <= 0) + if (cmp_is_error(stream_len)) return stream_len; if (up_model_buf) { @@ -1936,7 +1870,7 @@ static int compress_offset(const struct cmp_cfg *cfg, int stream_len) * value in the bitstream */ -static int compress_background(const struct cmp_cfg *cfg, int stream_len) +static uint32_t compress_background(const struct cmp_cfg *cfg, uint32_t stream_len) { size_t i; @@ -1945,7 +1879,7 @@ static int compress_background(const struct cmp_cfg *cfg, int stream_len) struct background *up_model_buf = NULL; struct background *next_model_p; struct background model; - struct encoder_setupt setup_mean, setup_var, setup_pix; + struct encoder_setup setup_mean, setup_var, setup_pix; if (model_mode_is_used(cfg->cmp_mode)) { model = model_buf[0]; @@ -1983,15 +1917,15 @@ static int compress_background(const struct cmp_cfg *cfg, int stream_len) for (i = 0;; i++) { stream_len = encode_value(data_buf[i].mean, model.mean, stream_len, &setup_mean); - if (stream_len <= 0) + if (cmp_is_error(stream_len)) return stream_len; stream_len = encode_value(data_buf[i].variance, model.variance, stream_len, &setup_var); - if (stream_len <= 0) + if (cmp_is_error(stream_len)) return stream_len; stream_len = encode_value(data_buf[i].outlier_pixels, model.outlier_pixels, stream_len, &setup_pix); - if (stream_len <= 0) + if (cmp_is_error(stream_len)) return stream_len; if (up_model_buf) { @@ -2022,7 +1956,7 @@ static int compress_background(const struct cmp_cfg *cfg, int stream_len) * value in the bitstream */ -static int compress_smearing(const struct cmp_cfg *cfg, int stream_len) +static uint32_t compress_smearing(const struct cmp_cfg *cfg, uint32_t stream_len) { size_t i; @@ -2031,7 +1965,7 @@ static int compress_smearing(const struct cmp_cfg *cfg, int stream_len) struct smearing *up_model_buf = NULL; struct smearing *next_model_p; struct smearing model; - struct encoder_setupt setup_mean, setup_var_mean, setup_pix; + struct encoder_setup setup_mean, setup_var_mean, setup_pix; if (model_mode_is_used(cfg->cmp_mode)) { model = model_buf[0]; @@ -2052,15 +1986,15 @@ static int compress_smearing(const struct cmp_cfg *cfg, int stream_len) for (i = 0;; i++) { stream_len = encode_value(data_buf[i].mean, model.mean, stream_len, &setup_mean); - if (stream_len <= 0) + if (cmp_is_error(stream_len)) return stream_len; stream_len = encode_value(data_buf[i].variance_mean, model.variance_mean, stream_len, &setup_var_mean); - if (stream_len <= 0) + if (cmp_is_error(stream_len)) return stream_len; stream_len = encode_value(data_buf[i].outlier_pixels, model.outlier_pixels, stream_len, &setup_pix); - if (stream_len <= 0) + if (cmp_is_error(stream_len)) return stream_len; if (up_model_buf) { @@ -2081,6 +2015,38 @@ static int compress_smearing(const struct cmp_cfg *cfg, int stream_len) } +/** + * @brief checks if the ICU compression configuration is valid + * + * @param cfg pointer to the cmp_cfg structure to be validated + * + * @returns an error code if any of the configuration parameters are invalid, + * otherwise returns CMP_ERROR_NO_ERROR on valid configuration + */ + +static uint32_t cmp_cfg_icu_is_invalid_error_code(const struct cmp_cfg *cfg) +{ + + RETURN_ERROR_IF(cmp_cfg_gen_par_is_invalid(cfg, ICU_CHECK) , PAR_GENERIC, ""); + RETURN_ERROR_IF(cmp_cfg_icu_buffers_is_invalid(cfg), PAR_BUFFERS, ""); + + if (cfg->cmp_mode != CMP_MODE_RAW) + RETURN_ERROR_IF(cmp_cfg_icu_max_used_bits_out_of_limit(cfg->max_used_bits), PAR_MAX_USED_BITS, ""); + + if (cmp_imagette_data_type_is_used(cfg->data_type)) { + RETURN_ERROR_IF(cmp_cfg_imagette_is_invalid(cfg, ICU_CHECK), PAR_SPECIFIC, ""); + } else if (cmp_fx_cob_data_type_is_used(cfg->data_type)) { + RETURN_ERROR_IF(cmp_cfg_fx_cob_is_invalid(cfg), PAR_SPECIFIC, ""); + } else if (cmp_aux_data_type_is_used(cfg->data_type)) { + RETURN_ERROR_IF(cmp_cfg_aux_is_invalid(cfg), PAR_SPECIFIC, ""); + } else { + RETURN_ERROR(INT_DATA_TYPE_UNSUPPORTED, ""); + } + + return CMP_ERROR(NO_ERROR); +} + + /** * @brief fill the last part of the bitstream with zeros * @@ -2092,13 +2058,10 @@ static int compress_smearing(const struct cmp_cfg *cfg, int stream_len) * value in the bitstream */ -static int pad_bitstream(const struct cmp_cfg *cfg, int cmp_size) +static uint32_t pad_bitstream(const struct cmp_cfg *cfg, uint32_t cmp_size) { unsigned int output_buf_len_bits, n_pad_bits; - if (cmp_size < 0) - return cmp_size; - if (!cfg->icu_output_buf) return cmp_size; @@ -2109,12 +2072,10 @@ static int pad_bitstream(const struct cmp_cfg *cfg, int cmp_size) /* maximum length of the bitstream/icu_output_buf in bits */ output_buf_len_bits = cmp_buffer_length_to_bits(cfg->buffer_length); - n_pad_bits = 32 - ((unsigned int)cmp_size & 0x1FU); + n_pad_bits = 32 - (cmp_size & 0x1FU); if (n_pad_bits < 32) { - int n_bits = put_n_bits32(0, n_pad_bits, cmp_size, cfg->icu_output_buf, - output_buf_len_bits); - if (n_bits < 0) - return n_bits; + FORWARD_IF_ERROR(put_n_bits32(0, n_pad_bits, cmp_size, + cfg->icu_output_buf, output_buf_len_bits), ""); } return cmp_size; @@ -2131,36 +2092,30 @@ static int pad_bitstream(const struct cmp_cfg *cfg, int cmp_size) * @note the validity of the cfg structure is checked before the compression is * started * - * @returns the bit length of the bitstream on success; negative on error, - * CMP_ERROR_SMALL_BUF (-2) if the compressed data buffer is too small to - * hold the whole compressed data, CMP_ERROR_HIGH_VALUE (-3) if a data or - * model value is bigger than the max_used_bits parameter + * @returns the bit length of the bitstream on success or an error code if it + * fails (which can be tested with cmp_is_error()) */ -static int compress_data_internal(const struct cmp_cfg *cfg, int stream_len) +static uint32_t compress_data_internal(const struct cmp_cfg *cfg, uint32_t stream_len) { - int bitsize = 0; + uint32_t bitsize = 0; - if (!cfg) - return -1; + FORWARD_IF_ERROR(stream_len, ""); + RETURN_ERROR_IF(cfg == NULL, GENERIC, ""); + RETURN_ERROR_IF(stream_len & 0x7, GENERIC, "The stream_len parameter must be a multiple of 8."); - if (stream_len < 0) - return stream_len; + if (raw_mode_is_used(cfg->cmp_mode) && cfg->icu_output_buf) { + uint32_t raw_stream_size = (stream_len >> 3) + + cfg->samples * (uint32_t)size_of_a_sample(cfg->data_type); + /* TODO: move this check to the memcpy */ + RETURN_ERROR_IF(raw_stream_size > cfg->buffer_length, SMALL_BUF_, ""); + } if (cfg->samples == 0) /* nothing to compress we are done */ return stream_len; - if (stream_len & 0x7) { - debug_print("Error: The stream_len parameter must be a multiple of 8."); - return -1; - } + FORWARD_IF_ERROR(cmp_cfg_icu_is_invalid_error_code(cfg), ""); - if (raw_mode_is_used(cfg->cmp_mode) && cfg->icu_output_buf) - if (((uint32_t)stream_len >> 3) + cfg->samples * size_of_a_sample(cfg->data_type) > cfg->buffer_length) - return CMP_ERROR_SMALL_BUF; - - if (cmp_cfg_icu_is_invalid(cfg)) - return -1; if (raw_mode_is_used(cfg->cmp_mode)) { uint32_t raw_size = cfg->samples * (uint32_t)size_of_a_sample(cfg->data_type); @@ -2169,14 +2124,10 @@ static int compress_data_internal(const struct cmp_cfg *cfg, int stream_len) uint8_t *p = (uint8_t *)cfg->icu_output_buf + (stream_len >> 3); memcpy(p, cfg->input_buf, raw_size); - if (cpu_to_be_data_type(p, raw_size, cfg->data_type)) - return -1; + RETURN_ERROR_IF(cpu_to_be_data_type(p, raw_size, cfg->data_type), GENERIC, ""); } - bitsize += stream_len + (int)raw_size*8; /* convert to bits */ + bitsize += stream_len + raw_size*8; /* convert to bits */ } else { - if (cfg->icu_output_buf && cfg->samples/3 > cfg->buffer_length) - debug_print("Warning: The size of the compressed_data buffer is 3 times smaller than the data_to_compress. This is probably unintended."); - switch (cfg->data_type) { case DATA_TYPE_IMAGETTE: case DATA_TYPE_IMAGETTE_ADAPTIVE: @@ -2241,12 +2192,14 @@ static int compress_data_internal(const struct cmp_cfg *cfg, int stream_len) /* LCOV_EXCL_START */ case DATA_TYPE_UNKNOWN: default: - debug_print("Error: Data type not supported."); - bitsize = -1; + RETURN_ERROR(INT_DATA_TYPE_UNSUPPORTED, ""); } /* LCOV_EXCL_STOP */ } + if (cmp_is_error(bitsize)) + return bitsize; + bitsize = pad_bitstream(cfg, bitsize); return bitsize; @@ -2272,14 +2225,14 @@ static int compress_data_internal(const struct cmp_cfg *cfg, int stream_len) int icu_compress_data(const struct cmp_cfg *cfg) { struct cmp_cfg cfg_cpy; - int dst_capacity_used = 0; + uint32_t dst_capacity_used = 0; if (cfg) { if (cfg->samples == 0) return 0; cfg_cpy = *cfg; cfg_cpy.buffer_length = cmp_cal_size_of_data(cfg->buffer_length, cfg->data_type); - if (!cfg_cpy.buffer_length) + if (cfg_cpy.icu_output_buf && !cfg_cpy.buffer_length) return -1; if (!rdcu_supported_data_type_is_used(cfg->data_type) && !cmp_data_type_is_invalid(cfg->data_type)) { @@ -2296,9 +2249,9 @@ int icu_compress_data(const struct cmp_cfg *cfg) cfg_cpy.model_buf = (uint8_t *)cfg->model_buf + COLLECTION_HDR_SIZE; dst_capacity_used = COLLECTION_HDR_SIZE*8; } - return compress_data_internal(&cfg_cpy, dst_capacity_used); + return (int)compress_data_internal(&cfg_cpy, dst_capacity_used); } - return compress_data_internal(NULL, dst_capacity_used); + return (int)compress_data_internal(NULL, dst_capacity_used); } @@ -2328,18 +2281,17 @@ static uint32_t cmp_guess_good_spill(uint32_t golomb_par) * size of the compressed collection size field * itself) * - * @returns 0 on success; -1 on failure + * @returns error code */ -static int set_cmp_col_size(uint8_t *cmp_col_size_field, int32_t cmp_col_size) +static uint32_t set_cmp_col_size(uint8_t *cmp_col_size_field, uint32_t cmp_col_size) { uint16_t const v = cpu_to_be16((uint16_t)cmp_col_size); - if (cmp_col_size > UINT16_MAX) - return -1; + RETURN_ERROR_IF(cmp_col_size > UINT16_MAX, INT_CMP_COL_TOO_LARGE, + "%"PRIu32" is bigger than the maximum allowed compression collection size", cmp_col_size_field); - if (cmp_col_size_field) - memcpy(cmp_col_size_field, &v, CMP_COLLECTION_FILD_SIZE); + memcpy(cmp_col_size_field, &v, CMP_COLLECTION_FILD_SIZE); return 0; } @@ -2360,26 +2312,32 @@ static int set_cmp_col_size(uint8_t *cmp_col_size_field, int32_t cmp_col_size) * @param dst_size the already used size of the dst buffer in bytes * * @returns the size of the compressed data in bytes (new dst_size) on - * success; negative on error, CMP_ERROR_SMALL_BUF (-2) if the compressed - * data buffer is too small to hold the whole compressed data; the - * compressed and updated model are only valid on positive return - * values + * success or an error code if it fails (which can be tested with + * cmp_is_error()) */ -static int32_t cmp_collection(uint8_t *col, uint8_t *model, uint8_t *updated_model, - uint32_t *dst, uint32_t dst_capacity, - struct cmp_cfg *cfg, int32_t dst_size) +static uint32_t cmp_collection(uint8_t *col, uint8_t *model, uint8_t *updated_model, + uint32_t *dst, uint32_t dst_capacity, + struct cmp_cfg *cfg, uint32_t dst_size) { - int32_t dst_size_begin = dst_size; - int dst_size_bits; + uint32_t dst_size_begin = dst_size; + uint32_t dst_size_bits; + struct collection_hdr *col_hdr = (struct collection_hdr *)col; + uint16_t col_data_length = cmp_col_get_data_length(col_hdr); + uint16_t sample_size; + + /* sanity check of the collection header */ + cfg->data_type = convert_subservice_to_cmp_data_type(cmp_col_get_subservice(col_hdr)); + sample_size = (uint16_t)size_of_a_sample(cfg->data_type); + RETURN_ERROR_IF(sample_size == 0, COL_SUBSERVICE_UNSUPPORTED, + "unsupported subservice: %u", cmp_col_get_subservice(col_hdr)); + RETURN_ERROR_IF(col_data_length % sample_size, COL_SIZE_INCONSISTENT, + "col_data_length: %u %% sample_size: %u != 0", col_data_length, sample_size); + cfg->samples = col_data_length/sample_size; - if (dst_size < 0) - return dst_size; - if (!col) - return -1; if (cfg->cmp_mode != CMP_MODE_RAW) { - /* we put the compressed data size be */ + /* hear we reserve space for the compressed data size field */ dst_size += CMP_COLLECTION_FILD_SIZE; } @@ -2387,12 +2345,11 @@ static int32_t cmp_collection(uint8_t *col, uint8_t *model, uint8_t *updated_mod * into the compressed data */ if (dst) { - if ((uint32_t)dst_size + COLLECTION_HDR_SIZE > dst_capacity) - return CMP_ERROR_SMALL_BUF; + RETURN_ERROR_IF(dst_size + COLLECTION_HDR_SIZE > dst_capacity, + SMALL_BUF_, ""); memcpy((uint8_t *)dst + dst_size, col, COLLECTION_HDR_SIZE); } dst_size += COLLECTION_HDR_SIZE; - if (model_mode_is_used(cfg->cmp_mode) && updated_model) memcpy(updated_model, col, COLLECTION_HDR_SIZE); @@ -2404,51 +2361,42 @@ static int32_t cmp_collection(uint8_t *col, uint8_t *model, uint8_t *updated_mod if (updated_model) cfg->icu_new_model_buf = updated_model + COLLECTION_HDR_SIZE; - { - struct collection_hdr *col_hdr = (struct collection_hdr *)col; - uint8_t subservice = cmp_col_get_subservice(col_hdr); - uint16_t col_data_length = cmp_col_get_data_length(col_hdr); - - cfg->data_type = convert_subservice_to_cmp_data_type(subservice); - - if (!size_of_a_sample(cfg->data_type)) - return -1; - if (col_data_length % size_of_a_sample(cfg->data_type)) - return -1; - cfg->samples = col_data_length/size_of_a_sample(cfg->data_type); - if ((dst && (uint32_t)dst_size + col_data_length > dst_capacity) || - cfg->cmp_mode == CMP_MODE_RAW) { - cfg->buffer_length = dst_capacity; + /* is enough capacity in the dst buffer to store the data uncompressed */ + if ((!dst || dst_capacity >= dst_size + col_data_length) && + cfg->cmp_mode != CMP_MODE_RAW) { + /* we set the compressed buffer size to the data size -1 to provoke + * a CMP_ERROR_SMALL_BUF_ error if the data are not compressible + */ + cfg->buffer_length = dst_size + col_data_length - 1; + dst_size_bits = compress_data_internal(cfg, dst_size<<3); + + if (cmp_get_error_code(dst_size_bits) == CMP_ERROR_SMALL_BUF_ || + (!dst && cmp_bit_to_byte(dst_size_bits)-dst_size > col_data_length)) { /* if dst == NULL compress_data_internal will not return a CMP_ERROR_SMALL_BUF */ + /* can not compress the data with the given parameters; + * put them uncompressed (raw) into the dst buffer */ + enum cmp_mode cmp_mode_cpy = cfg->cmp_mode; + + cfg->buffer_length = dst_size + col_data_length; + cfg->cmp_mode = CMP_MODE_RAW; dst_size_bits = compress_data_internal(cfg, dst_size<<3); - if (dst_size < 0) - return dst_size_bits; - } else { - /* we limit the size of the compressed data buffer */ - cfg->buffer_length = (uint32_t)dst_size + col_data_length-1; - dst_size_bits = compress_data_internal(cfg, dst_size<<3); - if (dst_size_bits == CMP_ERROR_SMALL_BUF || - (!dst && (int)cmp_bit_to_byte((unsigned int)dst_size_bits)-dst_size > col_data_length)) { /* if dst == NULL icu_compress_data_2 will not return a CMP_ERROR_SMALL_BUF */ - enum cmp_mode cmp_mode_cpy = cfg->cmp_mode; - - cfg->buffer_length = (uint32_t)dst_size + col_data_length; - cfg->cmp_mode = CMP_MODE_RAW; - dst_size_bits = compress_data_internal(cfg, dst_size<<3); - cfg->cmp_mode = cmp_mode_cpy; - if (model_mode_is_used(cfg->cmp_mode) && cfg->icu_new_model_buf) - memcpy(cfg->icu_new_model_buf, cfg->input_buf, col_data_length); - } + cfg->cmp_mode = cmp_mode_cpy; + /* updated model is in this case a copy of the data to compress */ + if (model_mode_is_used(cfg->cmp_mode) && cfg->icu_new_model_buf) + memcpy(cfg->icu_new_model_buf, cfg->input_buf, col_data_length); } - if (dst_size_bits < 0) - return dst_size_bits; + } else { + cfg->buffer_length = dst_capacity; + dst_size_bits = compress_data_internal(cfg, dst_size<<3); } + FORWARD_IF_ERROR(dst_size_bits, "compression failed"); - dst_size = (int32_t)cmp_bit_to_byte((unsigned int)dst_size_bits); /*TODO: fix casts */ - if (dst && cfg->cmp_mode != CMP_MODE_RAW) { - int32_t cmp_col_size = dst_size - dst_size_begin - + dst_size = cmp_bit_to_byte(dst_size_bits); + if (cfg->cmp_mode != CMP_MODE_RAW && dst) { + uint8_t *cmp_col_size_field = (uint8_t *)dst+dst_size_begin; + uint32_t cmp_col_size = dst_size - dst_size_begin - COLLECTION_HDR_SIZE - CMP_COLLECTION_FILD_SIZE; - if (set_cmp_col_size((uint8_t *)dst+dst_size_begin, cmp_col_size)) - return -1; + FORWARD_IF_ERROR(set_cmp_col_size(cmp_col_size_field, cmp_col_size), ""); } return dst_size; @@ -2458,7 +2406,7 @@ static int32_t cmp_collection(uint8_t *col, uint8_t *model, uint8_t *updated_mod /** * @brief builds a compressed entity header for a compressed chunk * - * @param ent start address of the compression entity header + * @param entity start address of the compression entity header * (can be NULL if you only want the entity header * size) * @param chunk_size the original size of the chunk in bytes @@ -2468,29 +2416,25 @@ static int32_t cmp_collection(uint8_t *col, uint8_t *model, uint8_t *updated_mod * @param cmp_ent_size_byte the size of the compression entity (entity * header plus compressed data) * - * @return the size of the compressed entity header in bytes, or -1 if an error - * occurred + * @return the size of the compressed entity header in bytes or an error code + * if it fails (which can be tested with cmp_is_error()) */ -static int cmp_ent_build_chunk_header(struct cmp_entity *ent, uint32_t chunk_size, - const struct cmp_cfg *cfg, uint64_t start_timestamp, - int32_t cmp_ent_size_byte) +static uint32_t cmp_ent_build_chunk_header(uint32_t *entity, uint32_t chunk_size, + const struct cmp_cfg *cfg, uint64_t start_timestamp, + uint32_t cmp_ent_size_byte) { - if (ent) { /* setup the compressed entity header */ + if (entity) { /* setup the compressed entity header */ + struct cmp_entity *ent = (struct cmp_entity *)entity; int err = 0; - if (cmp_ent_size_byte < 0) - cmp_ent_size_byte = 0; - err |= cmp_ent_set_version_id(ent, version_identifier); - err |= cmp_ent_set_size(ent, (uint32_t)cmp_ent_size_byte); - if (cmp_ent_set_original_size(ent, chunk_size)) { - debug_print("Error: The size of the chunk is too."); - return -1; - } - err |= cmp_ent_set_start_timestamp(ent, start_timestamp); + err |= cmp_ent_set_version_id(ent, version_identifier); /* set by compress_chunk_init */ + err |= cmp_ent_set_size(ent, cmp_ent_size_byte); + err |= cmp_ent_set_original_size(ent, chunk_size); err |= cmp_ent_set_data_type(ent, DATA_TYPE_CHUNK, cfg->cmp_mode == CMP_MODE_RAW); err |= cmp_ent_set_cmp_mode(ent, cfg->cmp_mode); err |= cmp_ent_set_model_value(ent, cfg->model_value); + /* model id/counter are set by the user with the compress_chunk_set_model_id_and_counter() */ err |= cmp_ent_set_model_id(ent, 0); err |= cmp_ent_set_model_counter(ent, 0); if (cfg->max_used_bits) @@ -2512,9 +2456,11 @@ static int cmp_ent_build_chunk_header(struct cmp_entity *ent, uint32_t chunk_siz err |= cmp_ent_set_non_ima_spill6(ent, cfg->spill_par_6); err |= cmp_ent_set_non_ima_cmp_par6(ent, cfg->cmp_par_6); } - err |= cmp_ent_set_end_timestamp(ent, get_timestamp()); - if (err) - return -1; + RETURN_ERROR_IF(err, ENTITY_HEADER, ""); + RETURN_ERROR_IF(cmp_ent_set_start_timestamp(ent, start_timestamp), + ENTITY_TIMESTAMP, ""); + RETURN_ERROR_IF(cmp_ent_set_end_timestamp(ent, get_timestamp()), + ENTITY_TIMESTAMP, ""); } if (cfg->cmp_mode == CMP_MODE_RAW) @@ -2525,20 +2471,38 @@ static int cmp_ent_build_chunk_header(struct cmp_entity *ent, uint32_t chunk_siz /** - * @brief map a sub-service to a chunk service according to + * @brief types of chunks containing different types of collections + * according to DetailedBudgetWorking_2023-10-11 + */ + +enum chunk_type { + CHUNK_TYPE_UNKNOWN, + CHUNK_TYPE_NCAM_IMAGETTE, + CHUNK_TYPE_SHORT_CADENCE, + CHUNK_TYPE_LONG_CADENCE, + CHUNK_TYPE_SAT_IMAGETTE, + CHUNK_TYPE_OFFSET_BACKGROUND, /* N-CAM */ + CHUNK_TYPE_SMEARING, + CHUNK_TYPE_F_CHAIN +}; + + +/** + * @brief get the chunk_type of a collection + * @details map a sub-service to a chunk service according to * DetailedBudgetWorking_2023-10-11 * - * @param subservice subservice of a science data product + * @param col pointer to a collection header * - * @returns the chunk type of the subservice on success, CHUNK_TYPE_UNKNOWN on + * @returns chunk type of the collection, CHUNK_TYPE_UNKNOWN on * failure */ -static enum chunk_type get_chunk_type(uint8_t subservice) +static enum chunk_type cmp_col_get_chunk_type(const struct collection_hdr *col) { - enum chunk_type chunk_type = CHUNK_TYPE_UNKNOWN; + enum chunk_type chunk_type; - switch (subservice) { + switch (cmp_col_get_subservice(col)) { case SST_NCxx_S_SCIENCE_IMAGETTE: chunk_type = CHUNK_TYPE_NCAM_IMAGETTE; break; @@ -2574,32 +2538,16 @@ static enum chunk_type get_chunk_type(uint8_t subservice) case SST_NCxx_S_SCIENCE_F_FX_NCOB: case SST_NCxx_S_SCIENCE_F_FX_EFX_NCOB_ECOB: debug_print("Error: No chunk is defined for fast cadence subservices"); - chunk_type = CHUNK_TYPE_UNKNOWN; - break; + /* fall through */ default: - debug_print("Error: Unknown subservice: %i.", subservice); chunk_type = CHUNK_TYPE_UNKNOWN; break; - }; + } return chunk_type; } -/** - * @brief get the chunk_type of a collection - * - * @param col pointer to a collection header - * - * @returns chunk type of the collection - */ - -static enum chunk_type cmp_col_get_chunk_type(const struct collection_hdr *col) -{ - return get_chunk_type(cmp_col_get_subservice(col)); -} - - /** * @brief Set the compression configuration from the compression parameters * based on the chunk type @@ -2607,15 +2555,14 @@ static enum chunk_type cmp_col_get_chunk_type(const struct collection_hdr *col) * @param[in] par pointer to a compression parameters struct * @param[in] chunk_type the type of the chunk to be compressed * @param[out] cfg pointer to a compression configuration - * - * @returns 0 success; -1 on failure */ -static int init_cmp_cfg_from_cmp_par(const struct cmp_par *par, enum chunk_type chunk_type, +static void init_cmp_cfg_from_cmp_par(const struct cmp_par *par, enum chunk_type chunk_type, struct cmp_cfg *cfg) { memset(cfg, 0, sizeof(struct cmp_cfg)); + /* the ranges of the parameters are checked in cmp_cfg_icu_is_invalid() */ cfg->cmp_mode = par->cmp_mode; cfg->model_value = par->model_value; cfg->round = par->lossy_par; @@ -2669,9 +2616,8 @@ static int init_cmp_cfg_from_cmp_par(const struct cmp_par *par, enum chunk_type cfg->cmp_par_background_pixels_error = par->fc_background_outlier_pixels; break; case CHUNK_TYPE_UNKNOWN: - default: - return -1; - }; + break; + } cfg->spill_par_1 = cmp_guess_good_spill(cfg->cmp_par_1); cfg->spill_par_2 = cmp_guess_good_spill(cfg->cmp_par_2); @@ -2679,7 +2625,6 @@ static int init_cmp_cfg_from_cmp_par(const struct cmp_par *par, enum chunk_type cfg->spill_par_4 = cmp_guess_good_spill(cfg->cmp_par_4); cfg->spill_par_5 = cmp_guess_good_spill(cfg->cmp_par_5); cfg->spill_par_6 = cmp_guess_good_spill(cfg->cmp_par_6); - return 0; } @@ -2691,7 +2636,7 @@ static int init_cmp_cfg_from_cmp_par(const struct cmp_par *par, enum chunk_type * * @param return_timestamp pointer to a function returning a current 48-bit * timestamp - * @param version_id version identifier of the applications software + * @param version_id application software version identifier */ void compress_chunk_init(uint64_t(return_timestamp)(void), uint32_t version_id) @@ -2724,59 +2669,54 @@ void compress_chunk_init(uint64_t(return_timestamp)(void), uint32_t version_id) * compress_chunk_cmp_size_bound(chunk, chunk_size) * as it eliminates one potential failure scenario: * not enough space in the dst buffer to write the - * compressed data; size is internally round down + * compressed data; size is internally rounded down * to a multiple of 4 - * @returns the byte size of the compressed_data buffer on success; negative on - * error, CMP_ERROR_SMALL_BUF (-2) if the compressed data buffer is too - * small to hold the whole compressed data; the compressed and updated - * model are only valid on non negative return values + * @returns the byte size of the compressed data or an error code if it + * fails (which can be tested with cmp_is_error()) */ -int32_t compress_chunk(void *chunk, uint32_t chunk_size, - void *chunk_model, void *updated_chunk_model, - uint32_t *dst, uint32_t dst_capacity, - const struct cmp_par *cmp_par) +uint32_t compress_chunk(void *chunk, uint32_t chunk_size, + void *chunk_model, void *updated_chunk_model, + uint32_t *dst, uint32_t dst_capacity, + const struct cmp_par *cmp_par) { uint64_t start_timestamp = get_timestamp(); - size_t read_bytes; struct collection_hdr *col = (struct collection_hdr *)chunk; - int32_t cmp_size_byte; /* size of the compressed data in bytes */ enum chunk_type chunk_type; struct cmp_cfg cfg; - int err; + uint32_t cmp_size_byte; /* size of the compressed data in bytes */ + size_t read_bytes; - if (!chunk) { - debug_print("Error: Pointer to the data chunk is NULL. No data no compression."); - return -1; - } - if (chunk_size < COLLECTION_HDR_SIZE) { - debug_print("Error: The chunk size is smaller than the minimum size."); - return -1; - } - if (chunk_size > CMP_ENTITY_MAX_ORIGINAL_SIZE) { - debug_print("Error: The chunk size is bigger than the maximum allowed chunk size."); - return -1; - } + RETURN_ERROR_IF(chunk == NULL, CHUNK_NULL, ""); + RETURN_ERROR_IF(chunk_size < COLLECTION_HDR_SIZE, CHUNK_SIZE_INCONSISTENT, + "chunk_size: %"PRIu32"", chunk_size); + RETURN_ERROR_IF(chunk_size > CMP_ENTITY_MAX_ORIGINAL_SIZE, CHUNK_TOO_LARGE, + "chunk_size: %"PRIu32"", chunk_size); chunk_type = cmp_col_get_chunk_type(col); - if (init_cmp_cfg_from_cmp_par(cmp_par, chunk_type, &cfg)) - return -1; + RETURN_ERROR_IF(chunk_type == CHUNK_TYPE_UNKNOWN, COL_SUBSERVICE_UNSUPPORTED, + "unsupported subservice: %u", cmp_col_get_subservice(col)); + + init_cmp_cfg_from_cmp_par(cmp_par, chunk_type, &cfg); - /* we will build the compression header after the compression of the chunk */ + /* reserve space for the compression entity header, we will build the + * header after the compression of the chunk + */ cmp_size_byte = cmp_ent_build_chunk_header(NULL, chunk_size, &cfg, start_timestamp, 0); if (dst) { - if (dst_capacity < (uint32_t)cmp_size_byte) { - debug_print("Error: The destination capacity is smaller than the minimum compression entity size."); - return CMP_ERROR_SMALL_BUF; - } - memset(dst, 0, (uint32_t)cmp_size_byte); + RETURN_ERROR_IF(dst_capacity < cmp_size_byte, SMALL_BUF_, + "dst_capacity must be at least as large as the minimum size of the compression unit."); + memset(dst, 0, cmp_size_byte); } + /* compress one collection after another */ for (read_bytes = 0; read_bytes <= chunk_size - COLLECTION_HDR_SIZE; - read_bytes += cmp_col_get_size(col)) { + read_bytes += cmp_col_get_size(col)) + { uint8_t *col_model = NULL; uint8_t *col_up_model = NULL; + /* setup pointers for the next collection we want to compress */ col = (struct collection_hdr *)((uint8_t *)chunk + read_bytes); if (chunk_model) @@ -2784,26 +2724,21 @@ int32_t compress_chunk(void *chunk, uint32_t chunk_size, if (updated_chunk_model) col_up_model = ((uint8_t *)updated_chunk_model + read_bytes); - if (cmp_col_get_chunk_type(col) != chunk_type) { - debug_print("Error: The chunk contains collections with an incompatible mix of subservices."); - return -1; - } + RETURN_ERROR_IF(cmp_col_get_chunk_type(col) != chunk_type, CHUNK_SUBSERVICE_INCONSISTENT, ""); + + /* chunk size is inconsistent with the sum of sizes in the collection headers */ if (read_bytes + cmp_col_get_size(col) > chunk_size) break; cmp_size_byte = cmp_collection((uint8_t *)col, col_model, col_up_model, dst, dst_capacity, &cfg, cmp_size_byte); + FORWARD_IF_ERROR(cmp_size_byte, "error occurred when compressing the collection with offset %u", read_bytes); } - if (read_bytes != chunk_size) { - debug_print("Error: The sum of the compressed collections does not match the size of the data in the compression header."); - return -1; - } + RETURN_ERROR_IF(read_bytes != chunk_size, CHUNK_SIZE_INCONSISTENT, ""); - err = cmp_ent_build_chunk_header((struct cmp_entity *)dst, chunk_size, - &cfg, start_timestamp, cmp_size_byte); - if (err < 0) - return err; + FORWARD_IF_ERROR(cmp_ent_build_chunk_header(dst, chunk_size, &cfg, + start_timestamp, cmp_size_byte), ""); return cmp_size_byte; } @@ -2811,7 +2746,6 @@ int32_t compress_chunk(void *chunk, uint32_t chunk_size, /** * @brief returns the maximum compressed size in a worst case scenario - * * In case the input data is not compressible * This function is primarily useful for memory allocation purposes * (destination buffer size). @@ -2820,56 +2754,67 @@ int32_t compress_chunk(void *chunk, uint32_t chunk_size, * COMPRESS_CHUNK_BOUND macro for compilation-time evaluation * (stack memory allocation for example) * - * @param chunk pointer to the chunk you want compress + * @param chunk pointer to the chunk you want to compress * @param chunk_size size of the chunk in bytes * - * @returns maximum compressed size for a chunk compression; 0 on error + * @returns maximum compressed size for a chunk compression on success or an + * error code if it fails (which can be tested with cmp_is_error()) */ uint32_t compress_chunk_cmp_size_bound(const void *chunk, size_t chunk_size) { int32_t read_bytes; uint32_t num_col = 0; + size_t bound; + size_t const max_chunk_size = CMP_ENTITY_MAX_ORIGINAL_SIZE + - NON_IMAGETTE_HEADER_SIZE - CMP_COLLECTION_FILD_SIZE; - if (chunk_size > CMP_ENTITY_MAX_ORIGINAL_SIZE-NON_IMAGETTE_HEADER_SIZE-CMP_COLLECTION_FILD_SIZE) { - debug_print("Error: The chunk size is bigger than the maximum allowed chunk size."); - return 0; - } + RETURN_ERROR_IF(chunk == NULL, CHUNK_NULL, ""); + RETURN_ERROR_IF(chunk_size < COLLECTION_HDR_SIZE, CHUNK_SIZE_INCONSISTENT, ""); + RETURN_ERROR_IF(chunk_size > max_chunk_size, CHUNK_TOO_LARGE, + "chunk_size: %"PRIu32" > max_chunk_size: %"PRIu32"", + chunk_size, max_chunk_size); + /* count the number of collections in the chunk */ for (read_bytes = 0; - read_bytes <= (int32_t)chunk_size-COLLECTION_HDR_SIZE; + read_bytes <= (int32_t)(chunk_size-COLLECTION_HDR_SIZE); read_bytes += cmp_col_get_size((const struct collection_hdr *)((const uint8_t *)chunk + read_bytes))) num_col++; + RETURN_ERROR_IF((uint32_t)read_bytes != chunk_size, CHUNK_SIZE_INCONSISTENT, ""); - if ((uint32_t)read_bytes != chunk_size) { - debug_print("Error: The sum of the compressed collections does not match the size of the data in the compression header."); - return 0; - } + bound = COMPRESS_CHUNK_BOUND_UNSAFE(chunk_size, num_col); + RETURN_ERROR_IF(bound > CMP_ENTITY_MAX_SIZE, CHUNK_TOO_LARGE, "bound: %lu", bound); - return (uint32_t)COMPRESS_CHUNK_BOUND(chunk_size, num_col); + return (uint32_t)bound; } /** * @brief set the model id and model counter in the compression entity header * - * @param dst pointer to the compressed data starting with a - * compression entity header + * @param dst pointer to the compressed data (starting with a + * compression entity header) * @param dst_size byte size of the dst buffer * @param model_id model identifier; for identifying entities that originate * from the same starting model * @param model_counter model_counter; counts how many times the model was * updated; for non model mode compression use 0 * - * @returns 0 on success, otherwise error + * @returns the byte size of the dst buffer (= dst_size) on success or an error + * code if it fails (which can be tested with cmp_is_error()) */ -int compress_chunk_set_model_id_and_counter(void *dst, int dst_size, - uint16_t model_id, uint8_t model_counter) +uint32_t compress_chunk_set_model_id_and_counter(void *dst, uint32_t dst_size, + uint16_t model_id, uint8_t model_counter) { - if (dst_size < GENERIC_HEADER_SIZE) - return 1; + RETURN_ERROR_IF(dst == NULL, ENTITY_NULL, ""); + FORWARD_IF_ERROR(dst_size, ""); + RETURN_ERROR_IF(dst_size < GENERIC_HEADER_SIZE, ENTITY_TOO_SMALL, + "dst_size: %"PRIu32"", dst_size); - return cmp_ent_set_model_id(dst, model_id) || cmp_ent_set_model_counter(dst, model_counter); + cmp_ent_set_model_id(dst, model_id); + cmp_ent_set_model_counter(dst, model_counter); + + return dst_size; } diff --git a/programs/cmp_io.c b/programs/cmp_io.c index da755f7c56845ed9d374494ab297a1f0f07ad2d2..81931f19b9a294c7c8b43e90a159f747b4deaa72 100644 --- a/programs/cmp_io.c +++ b/programs/cmp_io.c @@ -552,9 +552,10 @@ static int parse_cfg(FILE *fp, struct cmp_cfg *cfg, struct cmp_par *par) if (!fp) abort(); - if (!cfg) abort(); + if(!par) + abort(); while (fgets(line, sizeof(line), fp) != NULL) { if (line[0] == '#' || line[0] == '\n') diff --git a/programs/cmp_tool.c b/programs/cmp_tool.c index 8f77e6293c7baac45f10762435a766902256a36b..aaa947d1acd65fa590e01117e6881fd0e33b5f50 100644 --- a/programs/cmp_tool.c +++ b/programs/cmp_tool.c @@ -731,7 +731,8 @@ static int compression_of_chunk(void *chunk, uint32_t size, void *model, struct { uint32_t bound = compress_chunk_cmp_size_bound(chunk, size); uint32_t *cmp_data; - int32_t cmp_size; + uint32_t cmp_size; + enum cmp_error cmp_error; int error; if (!bound) @@ -745,10 +746,9 @@ static int compression_of_chunk(void *chunk, uint32_t size, void *model, struct printf("Compress chunk data ... "); cmp_size = compress_chunk(chunk, size, model, model, cmp_data, bound, chunk_par); - - if (cmp_size < 0) { - if (cmp_size == CMP_ERROR_SMALL_BUF) - fprintf(stderr, "Error: The buffer for the compressed data is too small to hold the compressed data. Try a larger buffer_length parameter.\n"); + cmp_error = cmp_get_error_code(cmp_size); + if (cmp_error != CMP_ERROR_NO_ERROR) { + fprintf(stderr, "%s\n", cmp_get_error_string(cmp_error)); free(cmp_data); cmp_data = NULL; printf("FAILED\n"); diff --git a/test/cmp_data_types/test_cmp_data_types.c b/test/cmp_data_types/test_cmp_data_types.c index a09c50c568a3787ddb92a8a03f140e4bd255dcda..ebb858893bca7978215eb7e275ff0cf6f8320e0c 100644 --- a/test/cmp_data_types/test_cmp_data_types.c +++ b/test/cmp_data_types/test_cmp_data_types.c @@ -145,7 +145,24 @@ void test_cmp_col_get_and_set(void) TEST_ASSERT_EQUAL_HEX8(i, u8_p[i]); } free(col); +} + + +/** + * @test convert_subservice_to_cmp_data_type + * @test convert_cmp_data_type_to_subservice + */ +void test_convert_subservice_functions(void) +{ + enum cmp_data_type data_type; + + for (data_type = 0; data_type <= DATA_TYPE_CHUNK; data_type++) { + uint8_t sst = convert_cmp_data_type_to_subservice(data_type); + enum cmp_data_type data_type_convert = convert_subservice_to_cmp_data_type(sst); + uint8_t sst_convert = convert_cmp_data_type_to_subservice(data_type_convert); + TEST_ASSERT_EQUAL(sst_convert, sst); + } } @@ -267,22 +284,32 @@ void test_cmp_input_size_to_samples(void) size = COLLECTION_HDR_SIZE + 4*sizeof(struct s_fx_ncob) - 1; samples_get = cmp_input_size_to_samples(size, data_type); TEST_ASSERT_EQUAL(-1, samples_get); + + data_type = DATA_TYPE_UNKNOWN; + size = 32; + samples_get = cmp_input_size_to_samples(size, data_type); + TEST_ASSERT_EQUAL(-1, samples_get); } -static void check_endianness(void* data, size_t size, enum cmp_data_type data_type) +static void check_endianness(void *data, uint16_t size, enum cmp_data_type data_type) { int error; uint8_t *p_8 = data; - size_t i; + int i; + uint8_t hdr_cpy[COLLECTION_HDR_SIZE]; TEST_ASSERT_TRUE(size > COLLECTION_HDR_SIZE); - error = cmp_input_big_to_cpu_endianness(data, (uint32_t)size, data_type); + cmp_col_set_subservice(data, convert_cmp_data_type_to_subservice(data_type)); + cmp_col_set_data_length(data, size-COLLECTION_HDR_SIZE); + + memcpy(hdr_cpy, data, sizeof(hdr_cpy)); + + error = be_to_cpu_chunk(data, size); TEST_ASSERT_FALSE(error); - for (i = 0; i < COLLECTION_HDR_SIZE; i++) - TEST_ASSERT_EQUAL(0, p_8[i]); + TEST_ASSERT_EQUAL_HEX8_ARRAY(hdr_cpy, data, COLLECTION_HDR_SIZE); for (i = 0; i < size-COLLECTION_HDR_SIZE; i++) TEST_ASSERT_EQUAL((uint8_t)i, p_8[COLLECTION_HDR_SIZE+i]); @@ -296,9 +323,9 @@ static void check_endianness(void* data, size_t size, enum cmp_data_type data_ty void test_cmp_input_big_to_cpu_endianness(void) { enum cmp_data_type data_type; + int error; { - int error; uint16_t data[2] = {0x0001, 0x0203}; uint8_t data_cmp[4] = {0x00, 0x01, 0x02, 0x03}; @@ -308,6 +335,41 @@ void test_cmp_input_big_to_cpu_endianness(void) TEST_ASSERT_FALSE(error); TEST_ASSERT_EQUAL_MEMORY(data, data_cmp, sizeof(data_cmp)); } + { + struct { + uint8_t hdr[COLLECTION_HDR_SIZE]; + struct offset entry[2]; + } __attribute__((packed)) data = {0}; + size_t i; + uint8_t *p_8 = (uint8_t *)&data; + + data_type = DATA_TYPE_OFFSET; + + data.entry[0].mean = 0x00010203; + data.entry[0].variance = 0x04050607; + data.entry[1].mean = 0x08090A0B; + data.entry[1].variance = 0x0C0D0E0F; + + error = cmp_input_big_to_cpu_endianness(&data, sizeof(data), data_type); + TEST_ASSERT_FALSE(error); + + for (i = 0; i < COLLECTION_HDR_SIZE; i++) + TEST_ASSERT_EQUAL(0, p_8[i]); + for (i = 0; i < sizeof(data)-COLLECTION_HDR_SIZE; i++) + TEST_ASSERT_EQUAL((uint8_t)i, p_8[COLLECTION_HDR_SIZE+i]); + } +} + + +/** + * @test be_to_cpu_chunk + * @test cpu_to_be_chunk + */ + +void test_be_to_cpu_chunk(void) +{ + enum cmp_data_type data_type; + { struct { uint8_t hdr[COLLECTION_HDR_SIZE]; @@ -616,6 +678,61 @@ void test_cmp_input_big_to_cpu_endianness(void) } +/** + * @test be_to_cpu_chunk + */ + +void test_be_to_cpu_chunk_error_cases(void) +{ + int error; + uint8_t *chunk; + size_t chunk_size; + uint8_t chunk_hdr_cpy[COLLECTION_HDR_SIZE]; + + /* data = NULL test */ + chunk = NULL; + chunk_size = 43; + error = be_to_cpu_chunk(chunk, chunk_size); + TEST_ASSERT_FALSE(error); + + chunk = calloc(1, COLLECTION_HDR_SIZE + 3*sizeof(struct background)); + cmp_col_set_subservice((void *)chunk, SST_NCxx_S_SCIENCE_BACKGROUND); + cmp_col_set_data_length((void *)chunk, 0); + memcpy(chunk_hdr_cpy, chunk, sizeof(chunk_hdr_cpy)); + + /* size to small */ + chunk_size = COLLECTION_HDR_SIZE - 1; + error = be_to_cpu_chunk(chunk, chunk_size); + TEST_ASSERT_TRUE(error); + + /* chunk without data */ + chunk_size = COLLECTION_HDR_SIZE; + error = be_to_cpu_chunk(chunk, chunk_size); + TEST_ASSERT_FALSE(error); + TEST_ASSERT_EQUAL_HEX8_ARRAY(chunk_hdr_cpy, chunk, COLLECTION_HDR_SIZE); + + /* wrong chunk size */ + cmp_col_set_data_length((void *)chunk, 3*sizeof(struct background)); + chunk_size = COLLECTION_HDR_SIZE + 2*sizeof(struct background); + error = be_to_cpu_chunk(chunk, chunk_size); + TEST_ASSERT_TRUE(error); + + /* unknown subservice */ + cmp_col_set_subservice((void *)chunk, 43); + chunk_size = COLLECTION_HDR_SIZE + 3*sizeof(struct background); + error = be_to_cpu_chunk(chunk, chunk_size); + TEST_ASSERT_TRUE(error); + + /* unknown subservice zero data length */ + cmp_col_set_data_length((void *)chunk, 0); + chunk_size = COLLECTION_HDR_SIZE; + error = be_to_cpu_chunk(chunk, chunk_size); + TEST_ASSERT_TRUE(error); + + free(chunk); +} + + /** * @test cmp_input_big_to_cpu_endianness */ diff --git a/test/cmp_decmp/test_cmp_decmp.c b/test/cmp_decmp/test_cmp_decmp.c index d4959caafe5dfd124cbdc1eab17c3bd900a339db..0a9d21ce9c1b4be9a2f726e6c19484a921fbcf90 100644 --- a/test/cmp_decmp/test_cmp_decmp.c +++ b/test/cmp_decmp/test_cmp_decmp.c @@ -33,6 +33,7 @@ #include <cmp_data_types.h> #include <leon_inttypes.h> #include <byteorder.h> +#include <cmp_error.h> #if defined __has_include # if __has_include(<time.h>) @@ -42,7 +43,7 @@ # endif #endif -#define ROUND_UP_TO_MULTIPLE_OF_4(x) (((x) + 3) & ~3) +#define ROUND_UP_TO_MULTIPLE_OF_4(x) (((x) + 3U) & ~3U) /** @@ -56,6 +57,7 @@ void setUp(void) #ifdef HAS_TIME_H seed = (uint64_t)(time(NULL) ^ getpid() ^ (intptr_t)&setUp); + seed = 0; #else seed = 1; #endif @@ -584,25 +586,6 @@ void generate_random_cmp_cfg(struct cmp_cfg *cfg) cfg->spill_par_5 = cmp_rand_between(MIN_NON_IMA_SPILL, cmp_icu_max_spill(cfg->cmp_par_ecob)); cfg->spill_par_6 = cmp_rand_between(MIN_NON_IMA_SPILL, cmp_icu_max_spill(cfg->cmp_par_fx_cob_variance)); } - -#if 0 - if (cfg->cmp_mode == CMP_MODE_STUFF) { - /* cfg->golomb_par = cmp_rand_between(16, MAX_STUFF_CMP_PAR); */ - cfg->golomb_par = 16; - cfg->ap1_golomb_par = cmp_rand_between(0, MAX_STUFF_CMP_PAR); - cfg->ap2_golomb_par = cmp_rand_between(0, MAX_STUFF_CMP_PAR); - cfg->cmp_par_exp_flags = cmp_rand_between(0, MAX_STUFF_CMP_PAR); - cfg->cmp_par_fx = cmp_rand_between(0, MAX_STUFF_CMP_PAR); - cfg->cmp_par_ncob = cmp_rand_between(0, MAX_STUFF_CMP_PAR); - cfg->cmp_par_efx = cmp_rand_between(0, MAX_STUFF_CMP_PAR); - cfg->cmp_par_ecob = cmp_rand_between(0, MAX_STUFF_CMP_PAR); - cfg->cmp_par_fx_cob_variance = cmp_rand_between(0, MAX_STUFF_CMP_PAR); - cfg->cmp_par_mean = cmp_rand_between(0, MAX_STUFF_CMP_PAR); - cfg->cmp_par_variance = cmp_rand_between(0, MAX_STUFF_CMP_PAR); - cfg->cmp_par_pixels_error = cmp_rand_between(0, MAX_STUFF_CMP_PAR); - return; - } -#endif } @@ -877,12 +860,12 @@ void test_random_compression_decompress_rdcu_data(void) } -static int32_t chunk_round_trip(void *data, uint32_t data_size, - void *model, void *up_model, - uint32_t *cmp_data, uint32_t cmp_data_capacity, - struct cmp_par *cmp_par, int use_decmp_buf, int use_decmp_up_model) +static uint32_t chunk_round_trip(void *data, uint32_t data_size, + void *model, void *up_model, + uint32_t *cmp_data, uint32_t cmp_data_capacity, + struct cmp_par *cmp_par, int use_decmp_buf, int use_decmp_up_model) { - int32_t cmp_size; + uint32_t cmp_size; void *model_cpy = NULL; /* if in-place model update is used (up_model == model), the model @@ -899,7 +882,6 @@ static int32_t chunk_round_trip(void *data, uint32_t data_size, cmp_size = compress_chunk(data, data_size, model, up_model, cmp_data, cmp_data_capacity, cmp_par); - TEST_ASSERT(cmp_size != CMP_ERROR_HIGH_VALUE); #if 0 { /* Compress a second time and check for determinism */ @@ -921,7 +903,7 @@ static int32_t chunk_round_trip(void *data, uint32_t data_size, free(up_model2); } #endif - if (cmp_size >= 0 && cmp_data) { + if (!cmp_is_error(cmp_size) && cmp_data) { void *decmp_data = NULL; void *up_model_decmp = NULL; int decmp_size; @@ -1012,7 +994,7 @@ void test_random_collection_round_trip(void) for (cmp_mode = CMP_MODE_RAW; cmp_mode <= CMP_MODE_DIFF_MULTI; cmp_mode++) { struct cmp_par par; - int32_t cmp_size; + uint32_t cmp_size; generate_random_cmp_par(&par); par.cmp_mode = cmp_mode; @@ -1024,9 +1006,9 @@ void test_random_collection_round_trip(void) /* No chunk is defined for fast cadence subservices */ if (data_type == DATA_TYPE_F_FX || data_type == DATA_TYPE_F_FX_EFX || data_type == DATA_TYPE_F_FX_NCOB || data_type == DATA_TYPE_F_FX_EFX_NCOB_ECOB) - TEST_ASSERT(cmp_size == -1); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_COL_SUBSERVICE_UNSUPPORTED, cmp_get_error_code(cmp_size)); else - TEST_ASSERT(cmp_size > 0); + TEST_ASSERT_FALSE(cmp_is_error(cmp_size)); } } #ifndef __sparc__ @@ -1053,7 +1035,7 @@ void test_cmp_collection_raw(void) struct cmp_par par = {0}; const uint32_t col_size = COLLECTION_HDR_SIZE+2*sizeof(struct s_fx); const size_t exp_cmp_size_byte = GENERIC_HEADER_SIZE + col_size; - int cmp_size_byte; + uint32_t cmp_size_byte; par.cmp_mode = CMP_MODE_RAW; @@ -1100,7 +1082,8 @@ void test_cmp_collection_raw(void) /* error case: buffer for the compressed data is to small */ dst_capacity -= 1; - TEST_ASSERT_EQUAL_INT(CMP_ERROR_SMALL_BUF, compress_chunk(col, col_size, NULL, NULL, dst, dst_capacity, &par)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_SMALL_BUF_, + cmp_get_error_code(compress_chunk(col, col_size, NULL, NULL, dst, dst_capacity, &par))); free(col); free(dst); @@ -1135,7 +1118,7 @@ void test_cmp_collection_diff(void) { /* compress data */ - int cmp_size_byte; + uint32_t cmp_size_byte; const int exp_cmp_size_byte = NON_IMAGETTE_HEADER_SIZE + CMP_COLLECTION_FILD_SIZE + COLLECTION_HDR_SIZE + cmp_size_byte_exp; @@ -1184,7 +1167,7 @@ void test_cmp_collection_diff(void) /* error cases dst buffer to small */ dst_capacity -= 1; - TEST_ASSERT_EQUAL_INT(CMP_ERROR_SMALL_BUF, compress_chunk(col, col_size, NULL, NULL, dst, dst_capacity, &par)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_SMALL_BUF_, cmp_get_error_code(compress_chunk(col, col_size, NULL, NULL, dst, dst_capacity, &par))); free(col); free(dst); @@ -1203,7 +1186,7 @@ void test_cmp_collection_worst_case(void) uint32_t dst_capacity = 0; struct cmp_par par = {0}; const uint16_t cmp_size_byte_exp = 2*sizeof(struct s_fx); - int cmp_size_byte; + uint32_t cmp_size_byte; struct s_fx *data; uint32_t samples = 2; const uint32_t col_size = COLLECTION_HDR_SIZE+samples*sizeof(*data); @@ -1289,7 +1272,7 @@ void test_cmp_collection_imagette_worst_case(void) uint32_t *dst = NULL; struct cmp_par par = {0}; uint16_t const cmp_size_byte_exp = 10*sizeof(uint16_t); - int cmp_size_byte; + uint32_t cmp_size_byte; uint32_t const col_size = COLLECTION_HDR_SIZE + cmp_size_byte_exp; { /* generate test data */ @@ -1359,6 +1342,8 @@ void test_cmp_collection_imagette_worst_case(void) TEST_ASSERT_EQUAL_HEX8_ARRAY(col, decompressed_data, decmp_size); free(decompressed_data); } + free(dst); + free(col); } @@ -1388,7 +1373,7 @@ void test_cmp_decmp_chunk_raw(void) /* "compress" data */ { size_t cmp_size_exp = GENERIC_HEADER_SIZE + chunk_size_exp; - int cmp_size; + uint32_t cmp_size; par.cmp_mode = CMP_MODE_RAW; @@ -1455,13 +1440,14 @@ void test_cmp_decmp_chunk_raw(void) free(decompressed_data); } { /* error case: buffer to small for compressed data */ - int cmp_size; + uint32_t cmp_size; dst_capacity -= 1; cmp_size = compress_chunk(chunk, chunk_size, NULL, NULL, dst, dst_capacity, &par); - TEST_ASSERT_EQUAL_INT(CMP_ERROR_SMALL_BUF, cmp_size); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_SMALL_BUF_, cmp_get_error_code(cmp_size)); } + free(dst); free(chunk); } @@ -1473,7 +1459,7 @@ void test_cmp_decmp_chunk_worst_case(void) uint32_t chunk_size = CHUNK_SIZE_EXP; void *chunk = NULL; uint32_t dst[COMPRESS_CHUNK_BOUND(CHUNK_SIZE_EXP, ARRAY_SIZE(chunk_def))/sizeof(uint32_t)]; - int cmp_size_byte = 0; + uint32_t cmp_size_byte = 0; struct cmp_par par = {0}; { /* generate test data */ @@ -1571,7 +1557,7 @@ void test_cmp_decmp_chunk_worst_case(void) /* error case: buffer to small for compressed data */ cmp_size_byte = compress_chunk(chunk, chunk_size, NULL, NULL, dst, chunk_size, &par); - TEST_ASSERT_EQUAL_INT(CMP_ERROR_SMALL_BUF, cmp_size_byte); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_SMALL_BUF_, cmp_get_error_code(cmp_size_byte)); free(chunk); } @@ -1632,7 +1618,7 @@ void test_cmp_decmp_diff(void) { /* compress data */ struct cmp_par par = {0}; uint32_t dst_capacity = 0; - int cmp_size; + uint32_t cmp_size; par.cmp_mode = CMP_MODE_DIFF_ZERO; par.s_exp_flags = 1; @@ -1664,4 +1650,5 @@ void test_cmp_decmp_diff(void) free(decompressed_data); } free(dst); + free(chunk); } diff --git a/test/cmp_entity/test_cmp_entity.c b/test/cmp_entity/test_cmp_entity.c index 5bd6b1ef9297218cee9275da673b76a4a9071c51..89c3534547421e60d3f0677371cd2eeb8c4970a3 100644 --- a/test/cmp_entity/test_cmp_entity.c +++ b/test/cmp_entity/test_cmp_entity.c @@ -464,7 +464,7 @@ void test_cmp_ent_data_type(void) /* error cases */ raw_mode_flag = 0; - data_type = 0x8000; + data_type = (enum cmp_data_type)0x8000; error = cmp_ent_set_data_type(&ent, data_type, raw_mode_flag); TEST_ASSERT_TRUE(error); error = cmp_ent_set_data_type(NULL, data_type, raw_mode_flag); @@ -488,7 +488,7 @@ void test_ent_cmp_mode(void) enum cmp_mode cmp_mode, cmp_mode_read; uint8_t *entity_p = (uint8_t *)&ent; - cmp_mode = 0x12; + cmp_mode = (enum cmp_mode)0x12; error = cmp_ent_set_cmp_mode(&ent, cmp_mode); TEST_ASSERT_FALSE(error); @@ -499,7 +499,7 @@ void test_ent_cmp_mode(void) TEST_ASSERT_EQUAL_HEX(0x12, entity_p[24]); /* error cases */ - cmp_mode = 0x100; + cmp_mode = (enum cmp_mode)0x100; error = cmp_ent_set_cmp_mode(&ent, cmp_mode); TEST_ASSERT_TRUE(error); error = cmp_ent_set_cmp_mode(NULL, cmp_mode); @@ -1334,7 +1334,11 @@ void test_cmp_ent_get_data_buf(void) /* compression data type not supported test */ error = cmp_ent_set_data_type(&ent, DATA_TYPE_UNKNOWN, 0); TEST_ASSERT_FALSE(error); + adr = cmp_ent_get_data_buf(&ent); + TEST_ASSERT_NULL(adr); + error = cmp_ent_set_data_type(&ent, (enum cmp_data_type)234, 1); + TEST_ASSERT_FALSE(error); adr = cmp_ent_get_data_buf(&ent); TEST_ASSERT_NULL(adr); } @@ -1767,7 +1771,7 @@ void test_cmp_ent_create(void) cmp_size_byte = 100; size = cmp_ent_create(NULL, data_type, raw_mode_flag, cmp_size_byte); TEST_ASSERT_EQUAL_UINT32(0, size); - data_type = 0xFFF; + data_type = (enum cmp_data_type)0xFFF; /* undefined data type */ raw_mode_flag = 1; cmp_size_byte = 100; size = cmp_ent_create(NULL, data_type, raw_mode_flag, cmp_size_byte); @@ -1985,7 +1989,7 @@ void test_cmp_ent_print(void) uint64_t start_time, end_time; uint16_t model_id; uint8_t model_counter; - struct cmp_cfg cfg; + struct cmp_cfg cfg = {0}; int cmp_size_bits; struct cmp_max_used_bits max_used_bits = {0}; @@ -2107,7 +2111,7 @@ void test_cmp_ent_parse(void) free(ent); - cfg.data_type = DATA_TYPE_S_FX; + cfg.data_type = DATA_TYPE_CHUNK; cfg.cmp_mode = CMP_MODE_MODEL_ZERO; version_id = 0x800F0003; size = cmp_ent_build(NULL, version_id, start_time, end_time, model_id, @@ -2120,5 +2124,9 @@ void test_cmp_ent_parse(void) cmp_ent_parse(ent); + /* unknown data product type */ + cmp_ent_set_data_type(ent, DATA_TYPE_UNKNOWN, 0); + cmp_ent_parse(ent); + free(ent); } diff --git a/test/cmp_icu/test_cmp_icu.c b/test/cmp_icu/test_cmp_icu.c index adc12f04c5aa65d66b94274cc2c5b4b734777c5b..49823b5e9e48b9bd2c970079ada05d08849794da 100644 --- a/test/cmp_icu/test_cmp_icu.c +++ b/test/cmp_icu/test_cmp_icu.c @@ -36,6 +36,9 @@ #include "../../lib/icu_compress/cmp_icu.c" /* this is a hack to test static functions */ +#define MAX_CMP_MODE CMP_MODE_DIFF_MULTI + + /** * @brief Seeds the pseudo-random number generator used by rand() */ @@ -52,9 +55,12 @@ void setUp(void) #endif if (!n) { + uint32_t seed_up = seed >> 32; + uint32_t seed_down = seed & 0xFFFFFFFF; + n = 1; cmp_rand_seed(seed); - printf("seed: %"PRIu64"\n", seed); + printf("seed: 0x%08"PRIx32"%08"PRIx32"\n", seed_up, seed_down); } } @@ -105,7 +111,7 @@ void test_cmp_cfg_icu_create(void) memset(&cfg, 0, sizeof(cfg)); /* wrong compression mode tests */ - cmp_mode = CMP_MODE_STUFF + 1; + cmp_mode = (enum cmp_mode)(MAX_CMP_MODE + 1); cfg = cmp_cfg_icu_create(data_type, cmp_mode, model_value, lossy_par); TEST_ASSERT_EQUAL_INT(DATA_TYPE_UNKNOWN, cfg.data_type); memset(&cfg, 0, sizeof(cfg)); @@ -116,10 +122,10 @@ void test_cmp_cfg_icu_create(void) memset(&cfg, 0, sizeof(cfg)); /* this should work */ - cmp_mode = CMP_MODE_STUFF; + cmp_mode = MAX_CMP_MODE; cfg = cmp_cfg_icu_create(data_type, cmp_mode, model_value, lossy_par); TEST_ASSERT_EQUAL_INT(DATA_TYPE_IMAGETTE, cfg.data_type); - TEST_ASSERT_EQUAL_INT(CMP_MODE_STUFF, cfg.cmp_mode); + TEST_ASSERT_EQUAL_INT(MAX_CMP_MODE, cfg.cmp_mode); TEST_ASSERT_EQUAL_INT(0, cfg.model_value); TEST_ASSERT_EQUAL_INT(0, cfg.round); TEST_ASSERT_EQUAL(&MAX_USED_BITS_SAFE, cfg.max_used_bits); @@ -145,11 +151,11 @@ void test_cmp_cfg_icu_create(void) TEST_ASSERT_EQUAL(&MAX_USED_BITS_SAFE, cfg.max_used_bits); /* no checks for model mode -> no model cmp_mode */ - cmp_mode = CMP_MODE_STUFF; + cmp_mode = CMP_MODE_RAW; model_value = MAX_MODEL_VALUE + 1; cfg = cmp_cfg_icu_create(data_type, cmp_mode, model_value, lossy_par); TEST_ASSERT_EQUAL_INT(DATA_TYPE_IMAGETTE, cfg.data_type); - TEST_ASSERT_EQUAL_INT(CMP_MODE_STUFF, cfg.cmp_mode); + TEST_ASSERT_EQUAL_INT(CMP_MODE_RAW, cfg.cmp_mode); TEST_ASSERT_EQUAL_INT(MAX_MODEL_VALUE + 1, cfg.model_value); TEST_ASSERT_EQUAL_INT(0, cfg.round); TEST_ASSERT_EQUAL(&MAX_USED_BITS_SAFE, cfg.max_used_bits); @@ -168,14 +174,14 @@ void test_cmp_cfg_icu_create(void) lossy_par = MAX_ICU_ROUND; cfg = cmp_cfg_icu_create(data_type, cmp_mode, model_value, lossy_par); TEST_ASSERT_EQUAL_INT(DATA_TYPE_IMAGETTE, cfg.data_type); - TEST_ASSERT_EQUAL_INT(CMP_MODE_STUFF, cfg.cmp_mode); + TEST_ASSERT_EQUAL_INT(CMP_MODE_RAW, cfg.cmp_mode); TEST_ASSERT_EQUAL_INT(16, cfg.model_value); TEST_ASSERT_EQUAL_INT(3, cfg.round); TEST_ASSERT_EQUAL(&MAX_USED_BITS_SAFE, cfg.max_used_bits); /* random test */ data_type = cmp_rand_between(DATA_TYPE_IMAGETTE, biggest_data_type); - cmp_mode = cmp_rand_between(CMP_MODE_RAW, CMP_MODE_STUFF); + cmp_mode = cmp_rand_between(CMP_MODE_RAW, MAX_CMP_MODE); model_value = cmp_rand_between(0, MAX_MODEL_VALUE); lossy_par = cmp_rand_between(CMP_LOSSLESS, MAX_ICU_ROUND); cfg = cmp_cfg_icu_create(data_type, cmp_mode, model_value, lossy_par); @@ -528,7 +534,7 @@ void test_cmp_cfg_icu_imagette(void) /* cmp_par to big */ cfg = cmp_cfg_icu_create(DATA_TYPE_IMAGETTE, CMP_MODE_MODEL_MULTI, 16, CMP_LOSSLESS); - cmp_par = MAX_IMA_GOLOMB_PAR + 1; + cmp_par = MAX_NON_IMA_GOLOMB_PAR + 1; spillover_par = MIN_IMA_SPILL; error = cmp_cfg_icu_imagette(&cfg, cmp_par, spillover_par); TEST_ASSERT_TRUE(error); @@ -551,7 +557,7 @@ void test_cmp_cfg_icu_imagette(void) /* spillover_par to big */ cfg = cmp_cfg_icu_create(DATA_TYPE_IMAGETTE, CMP_MODE_MODEL_MULTI, 16, CMP_LOSSLESS); cmp_par = MIN_IMA_GOLOMB_PAR; - spillover_par = cmp_ima_max_spill(cmp_par)+1; + spillover_par = cmp_icu_max_spill(cmp_par)+1; error = cmp_cfg_icu_imagette(&cfg, cmp_par, spillover_par); TEST_ASSERT_TRUE(error); /* ignore in RAW MODE */ @@ -570,38 +576,9 @@ void test_cmp_cfg_icu_imagette(void) error = cmp_cfg_icu_imagette(&cfg, cmp_par, spillover_par); TEST_ASSERT_FALSE(error); - /* CMP_MODE_STUFF tests */ - spillover_par = ~0U; /* is ignored */ - - /* highest values STUFF MODE */ - cfg = cmp_cfg_icu_create(DATA_TYPE_IMAGETTE, CMP_MODE_STUFF, ~0U, CMP_LOSSLESS); - cmp_par = MAX_STUFF_CMP_PAR; - error = cmp_cfg_icu_imagette(&cfg, cmp_par, spillover_par); - TEST_ASSERT_FALSE(error); - TEST_ASSERT_EQUAL_INT(cfg.golomb_par, 32); - - /* lowest values STUFF MODE */ - cfg = cmp_cfg_icu_create(DATA_TYPE_IMAGETTE, CMP_MODE_STUFF, ~0U, CMP_LOSSLESS); - cmp_par = 0; - error = cmp_cfg_icu_imagette(&cfg, cmp_par, spillover_par); - TEST_ASSERT_FALSE(error); - TEST_ASSERT_EQUAL_INT(cfg.golomb_par, 0); - - /* cmp_par to big */ - cfg = cmp_cfg_icu_create(DATA_TYPE_SAT_IMAGETTE, CMP_MODE_STUFF, ~0U, CMP_LOSSLESS); - cmp_par = MAX_STUFF_CMP_PAR+1; - error = cmp_cfg_icu_imagette(&cfg, cmp_par, spillover_par); - TEST_ASSERT_TRUE(error); - /* cfg = NULL test*/ error = cmp_cfg_icu_imagette(NULL, cmp_par, spillover_par); TEST_ASSERT_TRUE(error); - - /* invalid compression mode test*/ - cfg = cmp_cfg_icu_create(DATA_TYPE_SAT_IMAGETTE, CMP_MODE_STUFF+1, ~0U, CMP_LOSSLESS); - cmp_par = MAX_STUFF_CMP_PAR+1; - error = cmp_cfg_icu_imagette(&cfg, cmp_par, spillover_par); - TEST_ASSERT_TRUE(error); } @@ -1399,7 +1376,8 @@ static void init_PB32_arrays(uint32_t *z, uint32_t *o) void test_put_n_bits32(void) { uint32_t v, n; - int o, rval; /* return value */ + uint32_t o; + uint32_t rval; /* return value */ uint32_t testarray0[SDP_PB_N]; uint32_t testarray1[SDP_PB_N]; const uint32_t l = sizeof(testarray0) * CHAR_BIT; @@ -1740,17 +1718,20 @@ void test_put_n_bits32(void) /* n too large */ v = 0x0; n = 33; o = 1; rval = put_n_bits32(v, n, o, testarray0, l); - TEST_ASSERT_EQUAL_INT(rval, -1); + TEST_ASSERT_TRUE(cmp_is_error(rval)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_INT_DECODER, cmp_get_error_code(rval)); TEST_ASSERT(testarray0[0] == 0); TEST_ASSERT(testarray0[1] == 0); rval = put_n_bits32(v, n, o, NULL, l); - TEST_ASSERT_EQUAL_INT(rval, -1); + TEST_ASSERT_TRUE(cmp_is_error(rval)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_INT_DECODER, cmp_get_error_code(rval)); /* try to put too much in the bitstream */ v = 0x1; n = 1; o = 96; rval = put_n_bits32(v, n, o, testarray0, l); - TEST_ASSERT_EQUAL_INT(CMP_ERROR_SMALL_BUF, rval); + TEST_ASSERT_TRUE(cmp_is_error(rval)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_SMALL_BUF_, cmp_get_error_code(rval)); TEST_ASSERT(testarray0[0] == 0); TEST_ASSERT(testarray0[1] == 0); TEST_ASSERT(testarray0[2] == 0); @@ -1762,15 +1743,17 @@ void test_put_n_bits32(void) /* offset lager than max_stream_len(l) */ v = 0x0; n = 32; o = INT32_MAX; rval = put_n_bits32(v, n, o, testarray1, l); - TEST_ASSERT_EQUAL_INT(CMP_ERROR_SMALL_BUF, rval); + TEST_ASSERT_TRUE(cmp_is_error(rval)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_SMALL_BUF_, cmp_get_error_code(rval)); TEST_ASSERT(testarray1[0] == 0xffffffff); TEST_ASSERT(testarray1[1] == 0xffffffff); TEST_ASSERT(testarray1[2] == 0xffffffff); rval = put_n_bits32(v, n, o, NULL, l); - TEST_ASSERT(rval < 0); + TEST_ASSERT_FALSE(cmp_is_error(rval)); /* negative offset */ +#if 0 v = 0x0; n = 0; o = -1; rval = put_n_bits32(v, n, o, testarray0, l); TEST_ASSERT_EQUAL_INT(-1, rval); @@ -1788,6 +1771,7 @@ void test_put_n_bits32(void) rval = put_n_bits32(v, n, o, NULL, l); TEST_ASSERT_EQUAL_INT(-1, rval); +#endif } @@ -2011,8 +1995,8 @@ void test_golomb_encoder(void) void test_encode_value_zero(void) { uint32_t data, model; - int stream_len; - struct encoder_setupt setup = {0}; + uint32_t stream_len; + struct encoder_setup setup = {0}; uint32_t bitstream[3] = {0}; /* setup the setup */ @@ -2068,7 +2052,8 @@ void test_encode_value_zero(void) /* small buffer error */ data = 23; model = 26; stream_len = encode_value_zero(data, model, stream_len, &setup); - TEST_ASSERT_EQUAL_INT(CMP_ERROR_SMALL_BUF, stream_len); + TEST_ASSERT_TRUE(cmp_is_error(stream_len)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_SMALL_BUF_, cmp_get_error_code(stream_len)); /* reset bitstream to all bits set */ bitstream[0] = ~0U; @@ -2119,7 +2104,8 @@ void test_encode_value_zero(void) setup.max_stream_len = 32; data = 31; model = 0; stream_len = encode_value_zero(data, model, stream_len, &setup); - TEST_ASSERT_EQUAL_INT(CMP_ERROR_SMALL_BUF, stream_len); + TEST_ASSERT_TRUE(cmp_is_error(stream_len)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_SMALL_BUF_, cmp_get_error_code(stream_len)); TEST_ASSERT_EQUAL_HEX(0, be32_to_cpu(bitstream[0])); TEST_ASSERT_EQUAL_HEX(0, be32_to_cpu(bitstream[1])); TEST_ASSERT_EQUAL_HEX(0, be32_to_cpu(bitstream[2])); @@ -2133,8 +2119,8 @@ void test_encode_value_zero(void) void test_encode_value_multi(void) { uint32_t data, model; - int stream_len; - struct encoder_setupt setup = {0}; + uint32_t stream_len; + struct encoder_setup setup = {0}; uint32_t bitstream[4] = {0}; /* setup the setup */ @@ -2202,7 +2188,7 @@ void test_encode_value_multi(void) /* small buffer error */ data = 0; model = 38; stream_len = encode_value_multi(data, model, stream_len, &setup); - TEST_ASSERT_EQUAL_INT(CMP_ERROR_SMALL_BUF, stream_len); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_SMALL_BUF_, cmp_get_error_code(stream_len)); /* small buffer error when creating the multi escape symbol*/ bitstream[0] = 0; @@ -2212,19 +2198,19 @@ void test_encode_value_multi(void) stream_len = 32; data = 31; model = 0; stream_len = encode_value_multi(data, model, stream_len, &setup); - TEST_ASSERT_EQUAL_INT(CMP_ERROR_SMALL_BUF, stream_len); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_SMALL_BUF_, cmp_get_error_code(stream_len)); TEST_ASSERT_EQUAL_HEX(0, bitstream[0]); TEST_ASSERT_EQUAL_HEX(0, bitstream[1]); } - +#if 0 /** * @test encode_value */ -void test_encode_value(void) +void no_test_encode_value(void) { - struct encoder_setupt setup = {0}; + struct encoder_setup setup = {0}; uint32_t bitstream[4] = {0}; uint32_t data, model; int cmp_size; @@ -2329,6 +2315,7 @@ void test_encode_value(void) cmp_size = encode_value(data, model, cmp_size, &setup); TEST_ASSERT_EQUAL_INT(CMP_ERROR_HIGH_VALUE, cmp_size); } +#endif /** @@ -2417,51 +2404,8 @@ void test_compress_imagette_model(void) /* error case: model mode without model data */ cfg.model_buf = NULL; /* this is the error */ cmp_size = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL(-1, cmp_size); -} - - -/** - * @test compress_imagette - */ - -void test_compress_imagette_stuff(void) -{ - uint16_t data[] = {0x0, 0x1, 0x23, 0x42, 0x8000, 0x7FFF, 0xFFFF}; - uint32_t output_buf[4] = {0}; - struct cmp_cfg cfg = {0}; - - int cmp_size, error; - uint8_t output_buf_exp[] = { - 0x00, 0x00, 0x00, 0x01, - 0x00, 0x23, 0x00, 0x42, - 0x80, 0x00, 0x7F, 0xFF, - 0xFF, 0xFF, 0x00, 0x00}; - uint32_t *output_buf_exp_32; - - uint32_t samples = 7; - uint32_t buffer_length = 8; - uint32_t cmp_par = 16; /* how many used bits has the maximum data value */ - uint32_t output_buf_size; - - - cfg = cmp_cfg_icu_create(DATA_TYPE_IMAGETTE, CMP_MODE_STUFF, - CMP_PAR_UNUSED, CMP_LOSSLESS); - TEST_ASSERT(cfg.data_type != DATA_TYPE_UNKNOWN); - output_buf_size = cmp_cfg_icu_buffers(&cfg, data, samples, NULL, NULL, - output_buf, buffer_length); - TEST_ASSERT_EQUAL_INT(buffer_length*sizeof(uint16_t), output_buf_size); - error = cmp_cfg_icu_imagette(&cfg, cmp_par, CMP_PAR_UNUSED); - TEST_ASSERT_FALSE(error); - - cmp_size = icu_compress_data(&cfg); - - output_buf_exp_32 = (uint32_t *)output_buf_exp; - TEST_ASSERT_EQUAL_INT(7*16, cmp_size); - TEST_ASSERT_EQUAL_HEX16(output_buf_exp_32[0], output_buf[0]); - TEST_ASSERT_EQUAL_HEX16(output_buf_exp_32[1], output_buf[1]); - TEST_ASSERT_EQUAL_HEX16(output_buf_exp_32[2], output_buf[2]); - TEST_ASSERT_EQUAL_HEX16(output_buf_exp_32[3], output_buf[3]); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_size)); + TEST_ASSERT_EQUAL(CMP_ERROR_PAR_BUFFERS, cmp_get_error_code((uint32_t)cmp_size)); } @@ -2520,7 +2464,8 @@ void test_compress_imagette_raw(void) cfg.max_used_bits = &MAX_USED_BITS_SAFE; cmp_size = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_size); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_size)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_BUFFERS, cmp_get_error_code((uint32_t)cmp_size)); /* error case: compressed data buffer to small */ @@ -2533,7 +2478,8 @@ void test_compress_imagette_raw(void) cfg.max_used_bits = &MAX_USED_BITS_SAFE; cmp_size = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(CMP_ERROR_SMALL_BUF, cmp_size); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_size)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_SMALL_BUF_, cmp_get_error_code((uint32_t)cmp_size)); free(output_buf); } @@ -2625,7 +2571,8 @@ void test_compress_imagette_error_cases(void) cfg.buffer_length = 4; cmp_size = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_size); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_size)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_size)); /* error my_max_used_bits.saturated_imagette value is to high */ my_max_used_bits = MAX_USED_BITS_SAFE; @@ -2642,7 +2589,8 @@ void test_compress_imagette_error_cases(void) cfg.buffer_length = 4; cmp_size = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_size); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_size)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_size)); /* error my_max_used_bits.fc_imagette value is to high */ my_max_used_bits = MAX_USED_BITS_SAFE; @@ -2659,12 +2607,13 @@ void test_compress_imagette_error_cases(void) cfg.buffer_length = 4; cmp_size = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_size); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_size)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_size)); /* test unknown cmp_mode */ cfg.max_used_bits = &MAX_USED_BITS_SAFE; cfg.data_type = DATA_TYPE_F_CAM_IMAGETTE; - cfg.cmp_mode = CMP_MODE_STUFF+1; + cfg.cmp_mode = (enum cmp_mode)(MAX_CMP_MODE+1); cfg.input_buf = data; cfg.samples = 2; cfg.golomb_par = 1; @@ -2673,7 +2622,8 @@ void test_compress_imagette_error_cases(void) cfg.buffer_length = 4; cmp_size = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_size); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_size)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_GENERIC, cmp_get_error_code((uint32_t)cmp_size)); /* test golomb_par = 0 */ cfg.max_used_bits = &MAX_USED_BITS_SAFE; @@ -2687,7 +2637,8 @@ void test_compress_imagette_error_cases(void) cfg.buffer_length = 4; cmp_size = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_size); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_size)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_SPECIFIC, cmp_get_error_code((uint32_t)cmp_size)); } #if 0 @@ -2831,62 +2782,6 @@ void test_compress_s_fx_raw(void) } -void test_compress_s_fx_staff(void) -{ - struct s_fx data[5]; - struct cmp_cfg cfg = {0}; - int cmp_size, cmp_size_exp; - struct collection_hdr *hdr; - uint32_t *cmp_data; - - /* setup configuration */ - cfg.data_type = DATA_TYPE_S_FX; - cfg.cmp_mode = CMP_MODE_STUFF; - cfg.samples = 5; - cfg.input_buf = malloc(cmp_cal_size_of_data(cfg.samples, cfg.data_type)); - TEST_ASSERT_NOT_NULL(cfg.input_buf); - cfg.buffer_length = 5; - cfg.icu_output_buf = malloc(cmp_cal_size_of_data(cfg.buffer_length, cfg.data_type)); - TEST_ASSERT_NOT_NULL(cfg.icu_output_buf); - cfg.cmp_par_exp_flags = 2; - cfg.cmp_par_fx = 21; - cfg.max_used_bits = &MAX_USED_BITS_V1; - - /* generate input data */ - hdr = cfg.input_buf; - /* use dummy data for the header */ - memset(hdr, 0x42, sizeof(struct collection_hdr)); - data[0].exp_flags = 0x0; - data[0].fx = 0x0; - data[1].exp_flags = 0x1; - data[1].fx = 0x1; - data[2].exp_flags = 0x2; - data[2].fx = 0x23; - data[3].exp_flags = 0x3; - data[3].fx = 0x42; - data[4].exp_flags = 0x0; - data[4].fx = 0x001FFFFF; - memcpy(hdr->entry, data, sizeof(data)); - - cmp_size = icu_compress_data(&cfg); - - cmp_size_exp = 5 * (2 + 21) + COLLECTION_HDR_SIZE * CHAR_BIT; - TEST_ASSERT_EQUAL_INT(cmp_size_exp, cmp_size); - TEST_ASSERT_FALSE(memcmp(cfg.input_buf, cfg.icu_output_buf, COLLECTION_HDR_SIZE)); - hdr = (void *)cfg.icu_output_buf; - cmp_data = calloc(4, sizeof(*cmp_data)); - memcpy(cmp_data, hdr->entry, 4 * sizeof(*cmp_data)); - TEST_ASSERT_EQUAL_HEX(0x00000080, be32_to_cpu(cmp_data[0])); - TEST_ASSERT_EQUAL_HEX(0x00060001, be32_to_cpu(cmp_data[1])); - TEST_ASSERT_EQUAL_HEX(0x1E000423, be32_to_cpu(cmp_data[2])); - TEST_ASSERT_EQUAL_HEX(0xFFFFE000, be32_to_cpu(cmp_data[3])); - - free(cmp_data); - free(cfg.input_buf); - free(cfg.icu_output_buf); -} - - void test_compress_s_fx_model_multi(void) { struct s_fx data[6], model[6]; @@ -3043,12 +2938,14 @@ void test_compress_s_fx_error_cases(void) my_max_used_bits.s_exp_flags = 33; /* more than 32 bits are not allowed */ cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); my_max_used_bits.s_exp_flags = 32; my_max_used_bits.s_fx = 33; /* more than 32 bits are not allowed */ cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); } @@ -3111,21 +3008,24 @@ void test_compress_s_fx_efx_error_cases(void) my_max_used_bits.s_exp_flags = 33; cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); /* error case fx */ my_max_used_bits.s_exp_flags = 2; my_max_used_bits.s_fx = 33; cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); /* error case efx */ my_max_used_bits.s_fx = 21; my_max_used_bits.s_efx = 33; cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); } @@ -3195,21 +3095,25 @@ void test_compress_s_fx_ncob_error_cases(void) my_max_used_bits.s_exp_flags = 33; cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); + /* error case fx */ my_max_used_bits.s_exp_flags = 2; my_max_used_bits.s_fx = 33; cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); /* error case efx */ my_max_used_bits.s_fx = 21; my_max_used_bits.s_ncob = 33; cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); } @@ -3300,34 +3204,38 @@ void test_compress_s_fx_efx_ncob_ecob_error_cases(void) my_max_used_bits.s_exp_flags = 33; cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); /* error case fx */ my_max_used_bits.s_exp_flags = 32; my_max_used_bits.s_fx = 33; cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); /* error case efx */ my_max_used_bits.s_fx = 32; my_max_used_bits.s_ncob = 33; cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); my_max_used_bits.s_ncob = 32; my_max_used_bits.s_efx = 33; cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); my_max_used_bits.s_efx = 32; my_max_used_bits.s_ecob = 33; cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); - my_max_used_bits.s_ecob = 32; + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); } @@ -3369,7 +3277,8 @@ void test_compress_f_fx_error_cases(void) my_max_used_bits.f_fx = 33; /* more than 32 bits are not allowed */ cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); } @@ -3432,13 +3341,15 @@ void test_compress_f_fx_efx_error_cases(void) my_max_used_bits.f_fx = 33; /* more than 32 bits are not allowed */ cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); my_max_used_bits.f_fx = 32; my_max_used_bits.f_efx = 33; /* more than 32 bits are not allowed */ cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); } @@ -3497,13 +3408,15 @@ void test_compress_f_fx_ncob_error_cases(void) my_max_used_bits.f_fx = 33; /* more than 32 bits are not allowed */ cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); my_max_used_bits.f_fx = 32; my_max_used_bits.f_ncob = 33; /* more than 32 bits are not allowed */ cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); } @@ -3582,25 +3495,29 @@ void test_compress_f_fx_efx_ncob_ecob(void) my_max_used_bits.f_fx = 33; /* more than 32 bits are not allowed */ cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); my_max_used_bits.f_fx = 32; my_max_used_bits.f_ncob = 33; /* more than 32 bits are not allowed */ cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); my_max_used_bits.f_ncob = 32; my_max_used_bits.f_efx = 33; /* more than 32 bits are not allowed */ cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); my_max_used_bits.f_efx = 32; my_max_used_bits.f_ecob = 33; /* more than 32 bits are not allowed */ cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); } @@ -3663,19 +3580,22 @@ void test_compress_l_fx_error_cases(void) my_max_used_bits.l_exp_flags = 33; /* more than 32 bits are not allowed */ cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); my_max_used_bits.l_exp_flags = 32; my_max_used_bits.l_fx = 33; /* more than 32 bits are not allowed */ cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); my_max_used_bits.l_fx = 32; my_max_used_bits.l_fx_variance = 33; /* more than 32 bits are not allowed */ cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); } @@ -3745,25 +3665,29 @@ void test_compress_l_fx_efx_error_cases(void) my_max_used_bits.l_exp_flags = 33; /* more than 32 bits are not allowed */ cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); my_max_used_bits.l_exp_flags = 32; my_max_used_bits.l_fx = 33; /* more than 32 bits are not allowed */ cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); my_max_used_bits.l_fx = 32; my_max_used_bits.l_efx = 33; /* more than 32 bits are not allowed */ cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); my_max_used_bits.l_efx = 32; my_max_used_bits.l_fx_variance = 33; /* more than 32 bits are not allowed */ cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); } @@ -3849,31 +3773,36 @@ void test_compress_l_fx_ncob_error_cases(void) my_max_used_bits.l_exp_flags = 33; /* more than 32 bits are not allowed */ cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); my_max_used_bits.l_exp_flags = 32; my_max_used_bits.l_fx = 33; /* more than 32 bits are not allowed */ cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); my_max_used_bits.l_fx = 32; my_max_used_bits.l_ncob = 33; /* more than 32 bits are not allowed */ cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); my_max_used_bits.l_ncob = 32; my_max_used_bits.l_fx_variance = 33; /* more than 32 bits are not allowed */ cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); my_max_used_bits.l_fx_variance = 32; my_max_used_bits.l_cob_variance = 33; /* more than 32 bits are not allowed */ cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); } @@ -3980,43 +3909,50 @@ void test_compress_l_fx_efx_ncob_ecob_error_cases(void) my_max_used_bits.l_exp_flags = 33; /* more than 32 bits are not allowed */ cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); my_max_used_bits.l_exp_flags = 32; my_max_used_bits.l_fx = 33; /* more than 32 bits are not allowed */ cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); my_max_used_bits.l_fx = 32; my_max_used_bits.l_ncob = 33; /* more than 32 bits are not allowed */ cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); my_max_used_bits.l_ncob = 32; my_max_used_bits.l_efx = 33; /* more than 32 bits are not allowed */ cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); my_max_used_bits.l_efx = 32; my_max_used_bits.l_ecob = 33; /* more than 32 bits are not allowed */ cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); my_max_used_bits.l_ecob = 32; my_max_used_bits.l_fx_variance = 33; /* more than 32 bits are not allowed */ cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); my_max_used_bits.l_fx_variance = 32; my_max_used_bits.l_cob_variance = 33; /* more than 32 bits are not allowed */ cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); } @@ -4069,26 +4005,30 @@ void test_compress_offset_error_cases(void) my_max_used_bits.nc_offset_mean = 33; /* more than 32 bits are not allowed */ cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); my_max_used_bits.nc_offset_mean = 32; my_max_used_bits.nc_offset_variance = 33; /* more than 32 bits are not allowed */ cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); cfg.data_type = DATA_TYPE_F_CAM_OFFSET; my_max_used_bits.fc_offset_mean = 33; /* more than 32 bits are not allowed */ cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); my_max_used_bits.fc_offset_mean = 32; my_max_used_bits.fc_offset_variance = 33; /* more than 32 bits are not allowed */ cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); } @@ -4149,38 +4089,44 @@ void test_compress_background_error_cases(void) my_max_used_bits.nc_background_mean = 33; /* more than 32 bits are not allowed */ cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); my_max_used_bits.nc_background_mean = 32; my_max_used_bits.nc_background_variance = 33; /* more than 32 bits are not allowed */ cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); my_max_used_bits.nc_background_variance = 32; my_max_used_bits.nc_background_outlier_pixels = 33; /* more than 32 bits are not allowed */ cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); cfg.data_type = DATA_TYPE_F_CAM_BACKGROUND; my_max_used_bits.fc_background_mean = 33; /* more than 32 bits are not allowed */ cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); my_max_used_bits.fc_background_mean = 32; my_max_used_bits.fc_background_variance = 33; /* more than 32 bits are not allowed */ cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); my_max_used_bits.fc_background_variance = 32; my_max_used_bits.fc_background_outlier_pixels = 33; /* more than 32 bits are not allowed */ cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); } @@ -4241,19 +4187,22 @@ void test_compress_smearing_error_cases(void) my_max_used_bits.smearing_mean = 33; /* more than 32 bits are not allowed */ cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); my_max_used_bits.smearing_mean = 32; my_max_used_bits.smearing_variance_mean = 33; /* more than 32 bits are not allowed */ cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); my_max_used_bits.smearing_variance_mean = 32; my_max_used_bits.smearing_outlier_pixels = 33; /* more than 32 bits are not allowed */ cmp_cfg_icu_max_used_bits(&cfg, &my_max_used_bits); cmp_bits = icu_compress_data(&cfg); - TEST_ASSERT_EQUAL_INT(-1, cmp_bits); + TEST_ASSERT_TRUE(cmp_is_error((uint32_t)cmp_bits)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_PAR_MAX_USED_BITS, cmp_get_error_code((uint32_t)cmp_bits)); } @@ -4264,8 +4213,8 @@ void test_compress_smearing_error_cases(void) void test_pad_bitstream(void) { struct cmp_cfg cfg = {0}; - int cmp_size; - int cmp_size_return; + uint32_t cmp_size; + uint32_t cmp_size_return; uint32_t cmp_data[3]; const int MAX_BIT_LEN = 96; @@ -4275,12 +4224,12 @@ void test_pad_bitstream(void) cfg.buffer_length = sizeof(cmp_data); /* 6 * 16 bit samples -> 3 * 32 bit */ /* test negative cmp_size */ - cmp_size = -1; + cmp_size = -1U; cmp_size_return = pad_bitstream(&cfg, cmp_size); - TEST_ASSERT_EQUAL_INT(-1, cmp_size_return); - cmp_size = -3; + TEST_ASSERT_EQUAL_UINT32(-1U, cmp_size_return); + cmp_size = -3U; cmp_size_return = pad_bitstream(&cfg, cmp_size); - TEST_ASSERT_EQUAL_INT(-3, cmp_size_return); + TEST_ASSERT_EQUAL_UINT32(-3U, cmp_size_return); /* test RAW_MODE */ cfg.cmp_mode = CMP_MODE_RAW; @@ -4320,13 +4269,13 @@ void test_pad_bitstream(void) TEST_ASSERT_EQUAL_INT(cmp_data[1], 0); TEST_ASSERT_EQUAL_INT(cmp_data[2], 0xFFFFFFFF); - /* error case the rest of the compressed data are to small dor a 32 bit + /* error case the rest of the compressed data are to small for a 32 bit * access */ cfg.buffer_length -= 1; cmp_size = 64; cmp_size = put_n_bits32(0, 1, cmp_size, cfg.icu_output_buf, MAX_BIT_LEN); cmp_size_return = pad_bitstream(&cfg, cmp_size); - TEST_ASSERT_EQUAL_INT(CMP_ERROR_SMALL_BUF, cmp_size_return); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_SMALL_BUF_, cmp_get_error_code(cmp_size_return)); } @@ -4344,8 +4293,8 @@ void test_compress_chunk_raw_singel_col(void) struct s_fx *data = (struct s_fx *)col->entry; struct cmp_par cmp_par = {0}; uint32_t *dst; - int cmp_size; - size_t dst_capacity = 43; /* random non zero value */ + uint32_t cmp_size; + uint32_t dst_capacity = 43; /* random non zero value */ /* create a chunk with a single collection */ memset(col, 0, COLLECTION_HDR_SIZE); @@ -4364,7 +4313,7 @@ void test_compress_chunk_raw_singel_col(void) cmp_size = compress_chunk(chunk, CHUNK_SIZE, NULL, NULL, dst, dst_capacity, &cmp_par); TEST_ASSERT_EQUAL_INT(GENERIC_HEADER_SIZE + CHUNK_SIZE, cmp_size); - dst_capacity = (size_t)cmp_size; + dst_capacity = cmp_size; dst = malloc(dst_capacity); TEST_ASSERT_NOT_NULL(dst); cmp_size = compress_chunk(chunk, CHUNK_SIZE, NULL, NULL, dst, dst_capacity, &cmp_par); @@ -4395,7 +4344,7 @@ void test_compress_chunk_raw_singel_col(void) dst = malloc(dst_capacity); TEST_ASSERT_NOT_NULL(dst); cmp_size = compress_chunk(chunk, CHUNK_SIZE, NULL, NULL, dst, dst_capacity, &cmp_par); - TEST_ASSERT_EQUAL_INT(CMP_ERROR_SMALL_BUF, cmp_size); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_SMALL_BUF_, cmp_get_error_code(cmp_size)); free(dst); } @@ -4413,8 +4362,8 @@ void test_compress_chunk_raw_two_col(void) struct s_fx_efx_ncob_ecob *data2; struct cmp_par cmp_par = {0}; uint32_t *dst; - int cmp_size; - size_t dst_capacity = 0; + uint32_t cmp_size; + uint32_t dst_capacity = 0; /* create a chunk with two collection */ memset(col1, 0, COLLECTION_HDR_SIZE); @@ -4458,7 +4407,7 @@ void test_compress_chunk_raw_two_col(void) cmp_size = compress_chunk(chunk, CHUNK_SIZE, NULL, NULL, dst, dst_capacity, &cmp_par); TEST_ASSERT_EQUAL_INT(GENERIC_HEADER_SIZE + CHUNK_SIZE, cmp_size); - dst_capacity = (size_t)cmp_size; + dst_capacity = cmp_size; dst = malloc(dst_capacity); TEST_ASSERT_NOT_NULL(dst); cmp_size = compress_chunk(chunk, CHUNK_SIZE, NULL, NULL, dst, dst_capacity, &cmp_par); @@ -4511,10 +4460,12 @@ void test_compress_chunk_raw_two_col(void) dst = malloc(dst_capacity); TEST_ASSERT_NOT_NULL(dst); cmp_size = compress_chunk(chunk, CHUNK_SIZE, NULL, NULL, dst, dst_capacity, &cmp_par); - TEST_ASSERT_EQUAL_INT(CMP_ERROR_SMALL_BUF, cmp_size); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_SMALL_BUF_, cmp_get_error_code(cmp_size)); free(dst); } + +#if 0 void NOOO_test_compress_chunk_model(void) { enum { DATA_SIZE_1 = 1*sizeof(struct background), @@ -4530,8 +4481,9 @@ void NOOO_test_compress_chunk_model(void) struct offset *data2; struct cmp_par cmp_par = {0}; uint32_t *dst; - int cmp_size; - size_t dst_capacity = 0; + uint32_t cmp_size; + uint32_t dst_capacity = 0; + uint32_t chunk_size; /* create a chunk with two collection */ memset(col1, 0, COLLECTION_HDR_SIZE); @@ -4578,14 +4530,12 @@ void NOOO_test_compress_chunk_model(void) cmp_par.nc_background_outlier_pixels = 5; dst = NULL; - uint32_t chunk_size = COLLECTION_HDR_SIZE + DATA_SIZE_1; - /* chunk_size = CHUNK_SIZE; */ - /* int */ + chunk_size = COLLECTION_HDR_SIZE + DATA_SIZE_1; cmp_size = compress_chunk(chunk, chunk_size, chunk_model, chunk_up_model, dst, dst_capacity, &cmp_par); TEST_ASSERT_EQUAL_INT(NON_IMAGETTE_HEADER_SIZE + COLLECTION_HDR_SIZE + 4, cmp_size); - dst_capacity = (size_t)cmp_size; + dst_capacity = cmp_size; dst = malloc(dst_capacity); TEST_ASSERT_NOT_NULL(dst); cmp_size = compress_chunk(chunk, CHUNK_SIZE, NULL, NULL, dst, dst_capacity, &cmp_par); @@ -4598,7 +4548,6 @@ void NOOO_test_compress_chunk_model(void) struct s_fx_efx_ncob_ecob *raw_cmp_data2 = (struct s_fx_efx_ncob_ecob *)( (uint8_t *)cmp_ent_get_data_buf(ent) + 2*COLLECTION_HDR_SIZE + DATA_SIZE_1); - int i; TEST_ASSERT_EQUAL_UINT(CHUNK_SIZE, cmp_ent_get_cmp_data_size(ent)); TEST_ASSERT_EQUAL_UINT(CHUNK_SIZE, cmp_ent_get_original_size(ent)); TEST_ASSERT_EQUAL_UINT(cmp_par.cmp_mode, cmp_ent_get_cmp_mode(ent)); @@ -4607,31 +4556,30 @@ void NOOO_test_compress_chunk_model(void) TEST_ASSERT_EQUAL_HEX8_ARRAY(col1, cmp_ent_get_data_buf(ent), COLLECTION_HDR_SIZE); -#if 0 - for (i = 0; i < 2; i++) { - TEST_ASSERT_EQUAL_HEX(data1[i].exp_flags, raw_cmp_data1[i].exp_flags); - TEST_ASSERT_EQUAL_HEX(data1[i].fx, be32_to_cpu(raw_cmp_data1[i].fx)); - } - - TEST_ASSERT_EQUAL_HEX8_ARRAY(col1, cmp_ent_get_data_buf(ent), COLLECTION_HDR_SIZE); - - for (i = 0; i < 2; i++) { - TEST_ASSERT_EQUAL_HEX(data1[i].exp_flags, raw_cmp_data1[i].exp_flags); - TEST_ASSERT_EQUAL_HEX(data1[i].fx, be32_to_cpu(raw_cmp_data1[i].fx)); - } - - TEST_ASSERT_EQUAL_HEX8_ARRAY(col2, (uint8_t *)cmp_ent_get_data_buf(ent)+cmp_col_get_size(col1), COLLECTION_HDR_SIZE); - - for (i = 0; i < 2; i++) { - TEST_ASSERT_EQUAL_HEX(data2[i].exp_flags, raw_cmp_data2[i].exp_flags); - TEST_ASSERT_EQUAL_HEX(data2[i].fx, be32_to_cpu(raw_cmp_data2[i].fx)); - TEST_ASSERT_EQUAL_HEX(data2[i].efx, be32_to_cpu(raw_cmp_data2[i].efx)); - TEST_ASSERT_EQUAL_HEX(data2[i].ncob_x, be32_to_cpu(raw_cmp_data2[i].ncob_x)); - TEST_ASSERT_EQUAL_HEX(data2[i].ncob_y, be32_to_cpu(raw_cmp_data2[i].ncob_y)); - TEST_ASSERT_EQUAL_HEX(data2[i].ecob_x, be32_to_cpu(raw_cmp_data2[i].ecob_x)); - TEST_ASSERT_EQUAL_HEX(data2[i].ecob_y, be32_to_cpu(raw_cmp_data2[i].ecob_y)); - } -#endif + /* int i; */ + /* for (i = 0; i < 2; i++) { */ + /* TEST_ASSERT_EQUAL_HEX(data1[i].exp_flags, raw_cmp_data1[i].exp_flags); */ + /* TEST_ASSERT_EQUAL_HEX(data1[i].fx, be32_to_cpu(raw_cmp_data1[i].fx)); */ + /* } */ + + /* TEST_ASSERT_EQUAL_HEX8_ARRAY(col1, cmp_ent_get_data_buf(ent), COLLECTION_HDR_SIZE); */ + + /* for (i = 0; i < 2; i++) { */ + /* TEST_ASSERT_EQUAL_HEX(data1[i].exp_flags, raw_cmp_data1[i].exp_flags); */ + /* TEST_ASSERT_EQUAL_HEX(data1[i].fx, be32_to_cpu(raw_cmp_data1[i].fx)); */ + /* } */ + + /* TEST_ASSERT_EQUAL_HEX8_ARRAY(col2, (uint8_t *)cmp_ent_get_data_buf(ent)+cmp_col_get_size(col1), COLLECTION_HDR_SIZE); */ + + /* for (i = 0; i < 2; i++) { */ + /* TEST_ASSERT_EQUAL_HEX(data2[i].exp_flags, raw_cmp_data2[i].exp_flags); */ + /* TEST_ASSERT_EQUAL_HEX(data2[i].fx, be32_to_cpu(raw_cmp_data2[i].fx)); */ + /* TEST_ASSERT_EQUAL_HEX(data2[i].efx, be32_to_cpu(raw_cmp_data2[i].efx)); */ + /* TEST_ASSERT_EQUAL_HEX(data2[i].ncob_x, be32_to_cpu(raw_cmp_data2[i].ncob_x)); */ + /* TEST_ASSERT_EQUAL_HEX(data2[i].ncob_y, be32_to_cpu(raw_cmp_data2[i].ncob_y)); */ + /* TEST_ASSERT_EQUAL_HEX(data2[i].ecob_x, be32_to_cpu(raw_cmp_data2[i].ecob_x)); */ + /* TEST_ASSERT_EQUAL_HEX(data2[i].ecob_y, be32_to_cpu(raw_cmp_data2[i].ecob_y)); */ + /* } */ } free(dst); @@ -4640,75 +4588,125 @@ void NOOO_test_compress_chunk_model(void) dst = malloc(dst_capacity); TEST_ASSERT_NOT_NULL(dst); cmp_size = compress_chunk(chunk, CHUNK_SIZE, NULL, NULL, dst, dst_capacity, &cmp_par); - TEST_ASSERT_EQUAL_INT(CMP_ERROR_SMALL_BUF, cmp_size); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_SMALL_BUF_, cmp_get_error_code(cmp_size)); free(dst); } /* TODO: chunk tests * collection with 0 length; * collection with wrong mix collections; */ +#endif + /** - * @test cmp_data_to_big_endian + * @test compress_chunk + */ + +void test_collection_zero_data_length(void) +{ + enum { DATA_SIZE = 0, + CHUNK_SIZE = COLLECTION_HDR_SIZE + DATA_SIZE + }; + uint8_t chunk[CHUNK_SIZE]; + struct collection_hdr *col = (struct collection_hdr *)chunk; + struct cmp_par cmp_par = {0}; + uint32_t *dst; + uint32_t cmp_size; + uint32_t dst_capacity = 43; /* random non zero value */ + + /* create a chunk with a single collection */ + memset(col, 0, COLLECTION_HDR_SIZE); + TEST_ASSERT_FALSE(cmp_col_set_subservice(col, SST_NCxx_S_SCIENCE_IMAGETTE)); + + /* compress the data */ + cmp_par.cmp_mode = CMP_MODE_DIFF_MULTI; + dst = NULL; + + cmp_size = compress_chunk(chunk, CHUNK_SIZE, NULL, NULL, dst, + dst_capacity, &cmp_par); + TEST_ASSERT_EQUAL_INT(NON_IMAGETTE_HEADER_SIZE + CHUNK_SIZE + CMP_COLLECTION_FILD_SIZE, cmp_size); + dst_capacity = cmp_size; + dst = malloc(dst_capacity); TEST_ASSERT_NOT_NULL(dst); + cmp_size = compress_chunk(chunk, CHUNK_SIZE, NULL, NULL, dst, + dst_capacity, &cmp_par); + TEST_ASSERT_EQUAL_INT(NON_IMAGETTE_HEADER_SIZE + CHUNK_SIZE + CMP_COLLECTION_FILD_SIZE, cmp_size); + + /* test results */ + { struct cmp_entity *ent = (struct cmp_entity *)dst; + + TEST_ASSERT_EQUAL_UINT(CHUNK_SIZE+CMP_COLLECTION_FILD_SIZE, cmp_ent_get_cmp_data_size(ent)); + TEST_ASSERT_EQUAL_UINT(CHUNK_SIZE, cmp_ent_get_original_size(ent)); + TEST_ASSERT_EQUAL_UINT(cmp_par.cmp_mode, cmp_ent_get_cmp_mode(ent)); + TEST_ASSERT_FALSE(cmp_ent_get_data_type_raw_bit(ent)); + TEST_ASSERT_EQUAL_INT(DATA_TYPE_CHUNK, cmp_ent_get_data_type(ent)); + + TEST_ASSERT_EQUAL_HEX8_ARRAY(col, (uint8_t *)cmp_ent_get_data_buf(ent)+CMP_COLLECTION_FILD_SIZE, COLLECTION_HDR_SIZE); + } + + /* error case: dst buffer to small */ + dst_capacity -= 1; + cmp_size = compress_chunk(chunk, CHUNK_SIZE, NULL, NULL, dst, + dst_capacity, &cmp_par); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_SMALL_BUF_, cmp_get_error_code(cmp_size)); + free(dst); +} + + +/** + * @test compress_chunk */ #if 0 -void notest_cmp_data_to_big_endian_error_cases(void) +void nootest_collection_zero_data_length_2(void) { - struct cmp_cfg cfg = {0}; + enum { DATA_SIZE = 4, + CHUNK_SIZE = COLLECTION_HDR_SIZE + DATA_SIZE + COLLECTION_HDR_SIZE + }; + uint8_t chunk[CHUNK_SIZE]; + struct collection_hdr *col = (struct collection_hdr *)chunk; + uint16_t *data = (struct s_fx *)col->entry; + struct cmp_par cmp_par = {0}; + uint32_t *dst; int cmp_size; - int cmp_size_return; - uint16_t cmp_data[3] = {0x0123, 0x4567, 0x89AB}; - uint32_t output_buf[2] = {0}; - uint8_t *p; + uint32_t dst_capacity = 43; /* random non zero value */ - memcpy(output_buf, cmp_data, sizeof(cmp_data)); - cfg.icu_output_buf = output_buf; + /* create a chunk with a single collection */ + memset(col, 0, COLLECTION_HDR_SIZE); + TEST_ASSERT_FALSE(cmp_col_set_subservice(col, SST_NCxx_S_SCIENCE_IMAGETTE)); - /* this should work */ - cfg.data_type = DATA_TYPE_IMAGETTE; - cfg.cmp_mode = CMP_MODE_RAW; - cmp_size = 48; - cmp_size_return = cmp_data_to_big_endian(&cfg, cmp_size); - TEST_ASSERT_EQUAL_INT(cmp_size_return, 48); - p = (uint8_t *)cfg.icu_output_buf; - TEST_ASSERT_EQUAL(p[0], 0x01); - TEST_ASSERT_EQUAL(p[1], 0x23); - TEST_ASSERT_EQUAL(p[2], 0x45); - TEST_ASSERT_EQUAL(p[3], 0x67); - TEST_ASSERT_EQUAL(p[4], 0x89); - TEST_ASSERT_EQUAL(p[5], 0xAB); + /* compress the data */ + cmp_par.cmp_mode = CMP_MODE_DIFF_MULTI; + dst = NULL; - /* error cases */ - cmp_data[0] = 0x0123; - cmp_data[1] = 0x4567; - cmp_data[2] = 0x89AB; - cfg.data_type = DATA_TYPE_IMAGETTE; - cfg.cmp_mode = CMP_MODE_RAW; - cmp_size = 47; /* wrong size */ - cmp_size_return = cmp_data_to_big_endian(&cfg, cmp_size); - TEST_ASSERT_EQUAL_INT(cmp_size_return, -1); + cmp_size = compress_chunk(chunk, CHUNK_SIZE, NULL, NULL, dst, + dst_capacity, &cmp_par); + TEST_ASSERT_EQUAL_INT(NON_IMAGETTE_HEADER_SIZE + CHUNK_SIZE + CMP_COLLECTION_FILD_SIZE, cmp_size); + dst_capacity = (uint32_t)cmp_size; + dst = malloc(dst_capacity); TEST_ASSERT_NOT_NULL(dst); + cmp_size = compress_chunk(chunk, CHUNK_SIZE, NULL, NULL, dst, + dst_capacity, &cmp_par); + TEST_ASSERT_EQUAL_INT(NON_IMAGETTE_HEADER_SIZE + CHUNK_SIZE + CMP_COLLECTION_FILD_SIZE, cmp_size); - cmp_data[0] = 0x0123; - cmp_data[1] = 0x4567; - cmp_data[2] = 0x89AB; - cfg.data_type = DATA_TYPE_IMAGETTE; - cfg.cmp_mode = CMP_MODE_RAW; - cmp_size = 49; /* wrong size */ - cmp_size_return = cmp_data_to_big_endian(&cfg, cmp_size); - TEST_ASSERT_EQUAL_INT(cmp_size_return, -1); - - cmp_data[0] = 0x0123; - cmp_data[1] = 0x4567; - cmp_data[2] = 0x89AB; - cfg.data_type = DATA_TYPE_UNKNOWN; /* wrong data_type */ - cfg.cmp_mode = CMP_MODE_RAW; - cmp_size = 48; - cmp_size_return = cmp_data_to_big_endian(&cfg, cmp_size); - TEST_ASSERT_EQUAL_INT(cmp_size_return, -1); + /* test results */ + { struct cmp_entity *ent = (struct cmp_entity *)dst; + + TEST_ASSERT_EQUAL_UINT(CHUNK_SIZE+CMP_COLLECTION_FILD_SIZE, cmp_ent_get_cmp_data_size(ent)); + TEST_ASSERT_EQUAL_UINT(CHUNK_SIZE, cmp_ent_get_original_size(ent)); + TEST_ASSERT_EQUAL_UINT(cmp_par.cmp_mode, cmp_ent_get_cmp_mode(ent)); + TEST_ASSERT_FALSE(cmp_ent_get_data_type_raw_bit(ent)); + TEST_ASSERT_EQUAL_INT(DATA_TYPE_CHUNK, cmp_ent_get_data_type(ent)); + + TEST_ASSERT_EQUAL_HEX8_ARRAY(col, cmp_ent_get_data_buf(ent)+CMP_COLLECTION_FILD_SIZE, COLLECTION_HDR_SIZE); + } + + /* error case: dst buffer to small */ + dst_capacity -= 1; + cmp_size = compress_chunk(chunk, CHUNK_SIZE, NULL, NULL, dst, + dst_capacity, &cmp_par); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_SMALL_BUF, cmp_size); + free(dst); } #endif - /** * @test icu_compress_data */ @@ -4737,7 +4735,7 @@ void test_zero_escape_mech_is_used(void) { enum cmp_mode cmp_mode; - for (cmp_mode = 0; cmp_mode <= CMP_MODE_STUFF; cmp_mode++) { + for (cmp_mode = 0; cmp_mode <= MAX_CMP_MODE; cmp_mode++) { int res = zero_escape_mech_is_used(cmp_mode); if (cmp_mode == CMP_MODE_DIFF_ZERO || @@ -4749,6 +4747,211 @@ void test_zero_escape_mech_is_used(void) } +/** + * @test ROUND_UP_TO_4 + * @test COMPRESS_CHUNK_BOUND + */ + +void test_COMPRESS_CHUNK_BOUND(void) +{ + uint32_t chunk_size; + unsigned int num_col; + uint32_t bound, bound_exp; + + TEST_ASSERT_EQUAL(0, ROUND_UP_TO_4(0)); + TEST_ASSERT_EQUAL(4, ROUND_UP_TO_4(1)); + TEST_ASSERT_EQUAL(4, ROUND_UP_TO_4(3)); + TEST_ASSERT_EQUAL(4, ROUND_UP_TO_4(4)); + TEST_ASSERT_EQUAL(8, ROUND_UP_TO_4(5)); + TEST_ASSERT_EQUAL(0xFFFFFFFC, ROUND_UP_TO_4(0xFFFFFFFB)); + TEST_ASSERT_EQUAL(0xFFFFFFFC, ROUND_UP_TO_4(0xFFFFFFFC)); + TEST_ASSERT_EQUAL(0, ROUND_UP_TO_4(0xFFFFFFFD)); + TEST_ASSERT_EQUAL(0, ROUND_UP_TO_4(0xFFFFFFFF)); + + chunk_size = 0; + num_col = 0; + bound = COMPRESS_CHUNK_BOUND(chunk_size, num_col); + TEST_ASSERT_EQUAL(0, bound); + + chunk_size = 0; + num_col = 1; + bound = COMPRESS_CHUNK_BOUND(chunk_size, num_col); + TEST_ASSERT_EQUAL(0, bound); + + chunk_size = COLLECTION_HDR_SIZE - 1; + num_col = 1; + bound = COMPRESS_CHUNK_BOUND(chunk_size, num_col); + TEST_ASSERT_EQUAL(0, bound); + + chunk_size = 2*COLLECTION_HDR_SIZE - 1; + num_col = 2; + bound = COMPRESS_CHUNK_BOUND(chunk_size, num_col); + TEST_ASSERT_EQUAL(0, bound); + + chunk_size = COLLECTION_HDR_SIZE; + num_col = 0; + bound = COMPRESS_CHUNK_BOUND(chunk_size, num_col); + TEST_ASSERT_EQUAL(0, bound); + + chunk_size = CMP_ENTITY_MAX_SIZE; + num_col = 1; + bound = COMPRESS_CHUNK_BOUND(chunk_size, num_col); + TEST_ASSERT_EQUAL(0, bound); + + chunk_size = UINT32_MAX; + num_col = 1; + bound = COMPRESS_CHUNK_BOUND(chunk_size, num_col); + TEST_ASSERT_EQUAL(0, bound); + + num_col = (CMP_ENTITY_MAX_SIZE-NON_IMAGETTE_HEADER_SIZE)/COLLECTION_HDR_SIZE + 1; + chunk_size = num_col*COLLECTION_HDR_SIZE; + bound = COMPRESS_CHUNK_BOUND(chunk_size, num_col); + TEST_ASSERT_EQUAL(0, bound); + + + chunk_size = COLLECTION_HDR_SIZE; + num_col = 1; + bound = COMPRESS_CHUNK_BOUND(chunk_size, num_col); + bound_exp = ROUND_UP_TO_4(NON_IMAGETTE_HEADER_SIZE + CMP_COLLECTION_FILD_SIZE + + COLLECTION_HDR_SIZE); + TEST_ASSERT_EQUAL(bound_exp, bound); + + chunk_size = COLLECTION_HDR_SIZE + 7; + num_col = 1; + bound = COMPRESS_CHUNK_BOUND(chunk_size, num_col); + bound_exp = ROUND_UP_TO_4(NON_IMAGETTE_HEADER_SIZE + CMP_COLLECTION_FILD_SIZE + + chunk_size); + TEST_ASSERT_EQUAL(bound_exp, bound); + + chunk_size = 42*COLLECTION_HDR_SIZE ; + num_col = 42; + bound = COMPRESS_CHUNK_BOUND(chunk_size, num_col); + bound_exp = ROUND_UP_TO_4(NON_IMAGETTE_HEADER_SIZE + 42*CMP_COLLECTION_FILD_SIZE + + chunk_size); + TEST_ASSERT_EQUAL(bound_exp, bound); + + chunk_size = 42*COLLECTION_HDR_SIZE + 7; + num_col = 42; + bound = COMPRESS_CHUNK_BOUND(chunk_size, num_col); + bound_exp = ROUND_UP_TO_4(NON_IMAGETTE_HEADER_SIZE + 42*CMP_COLLECTION_FILD_SIZE + + chunk_size); + TEST_ASSERT_EQUAL(bound_exp, bound); + + chunk_size = (CMP_ENTITY_MAX_SIZE & ~3U) - NON_IMAGETTE_HEADER_SIZE - CMP_COLLECTION_FILD_SIZE; + num_col = 1; + bound = COMPRESS_CHUNK_BOUND(chunk_size, num_col); + bound_exp = ROUND_UP_TO_4(NON_IMAGETTE_HEADER_SIZE + CMP_COLLECTION_FILD_SIZE + + chunk_size); + TEST_ASSERT_EQUAL(bound_exp, bound); + + chunk_size++; + bound = COMPRESS_CHUNK_BOUND(chunk_size, num_col); + TEST_ASSERT_EQUAL(0, bound); + + num_col = (CMP_ENTITY_MAX_SIZE-NON_IMAGETTE_HEADER_SIZE)/(COLLECTION_HDR_SIZE+CMP_COLLECTION_FILD_SIZE); + chunk_size = num_col*COLLECTION_HDR_SIZE + 10; + bound = COMPRESS_CHUNK_BOUND(chunk_size, num_col); + bound_exp = ROUND_UP_TO_4(NON_IMAGETTE_HEADER_SIZE + num_col*CMP_COLLECTION_FILD_SIZE + + chunk_size); + TEST_ASSERT_EQUAL_HEX(bound_exp, bound); + + chunk_size++; + bound = COMPRESS_CHUNK_BOUND(chunk_size, num_col); + TEST_ASSERT_EQUAL_HEX(0, bound); +} + + +/** + * @test compress_chunk_cmp_size_bound + */ + +void test_compress_chunk_cmp_size_bound(void) +{ + uint8_t chunk[2*COLLECTION_HDR_SIZE + 42 + 3] = {0}; + uint32_t chunk_size; + uint32_t bound, bound_exp; + + TEST_ASSERT_FALSE(cmp_col_set_data_length((struct collection_hdr *)chunk, 0)); + + chunk_size = 0; + bound = compress_chunk_cmp_size_bound(chunk, chunk_size); + TEST_ASSERT_TRUE(cmp_is_error(bound)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_CHUNK_SIZE_INCONSISTENT, cmp_get_error_code(bound)); + + chunk_size = COLLECTION_HDR_SIZE-1; + bound = compress_chunk_cmp_size_bound(chunk, chunk_size); + TEST_ASSERT_TRUE(cmp_is_error(bound)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_CHUNK_SIZE_INCONSISTENT, cmp_get_error_code(bound)); + + chunk_size = UINT32_MAX; + bound = compress_chunk_cmp_size_bound(chunk, chunk_size); + TEST_ASSERT_TRUE(cmp_is_error(bound)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_CHUNK_TOO_LARGE, cmp_get_error_code(bound)); + + chunk_size = COLLECTION_HDR_SIZE; + bound = compress_chunk_cmp_size_bound(chunk, chunk_size); + bound_exp = ROUND_UP_TO_4(NON_IMAGETTE_HEADER_SIZE + COLLECTION_HDR_SIZE + CMP_COLLECTION_FILD_SIZE); + TEST_ASSERT_EQUAL(bound_exp, bound); + + chunk_size = COLLECTION_HDR_SIZE + 42; + TEST_ASSERT_FALSE(cmp_col_set_data_length((struct collection_hdr *)chunk, 42)); + bound = compress_chunk_cmp_size_bound(chunk, chunk_size); + bound_exp = ROUND_UP_TO_4(NON_IMAGETTE_HEADER_SIZE + CMP_COLLECTION_FILD_SIZE + + chunk_size); + TEST_ASSERT_EQUAL(bound_exp, bound); + + /* chunk is NULL */ + bound = compress_chunk_cmp_size_bound(NULL, chunk_size); + TEST_ASSERT_TRUE(cmp_is_error(bound)); + TEST_ASSERT_EQUAL_INT(CMP_ERROR_CHUNK_NULL, cmp_get_error_code(bound)); + + TEST_ASSERT_FALSE(cmp_col_set_data_length((struct collection_hdr *)(chunk+chunk_size), 3)); + chunk_size = sizeof(chunk); + bound = compress_chunk_cmp_size_bound(chunk, chunk_size); + bound_exp = ROUND_UP_TO_4(NON_IMAGETTE_HEADER_SIZE + 2*CMP_COLLECTION_FILD_SIZE + + chunk_size); + TEST_ASSERT_EQUAL(bound_exp, bound); +} + + +void test_compress_chunk_set_model_id_and_counter(void) +{ + uint32_t ret; + struct cmp_entity dst; + uint32_t dst_size = sizeof(dst); + uint16_t model_id; + uint8_t model_counter; + + memset(&dst, 0x42, sizeof(dst)); + + model_id = 0; + model_counter = 0; + ret = compress_chunk_set_model_id_and_counter(&dst, dst_size, model_id, model_counter); + TEST_ASSERT_FALSE(cmp_is_error(ret)); + TEST_ASSERT_EQUAL(dst_size, ret); + TEST_ASSERT_EQUAL(model_id, cmp_ent_get_model_id(&dst)); + TEST_ASSERT_EQUAL(model_counter, cmp_ent_get_model_counter(&dst)); + + model_id = UINT16_MAX; + model_counter = UINT8_MAX; + ret = compress_chunk_set_model_id_and_counter(&dst, dst_size, model_id, model_counter); + TEST_ASSERT_FALSE(cmp_is_error(ret)); + TEST_ASSERT_EQUAL(dst_size, ret); + TEST_ASSERT_EQUAL(model_id, cmp_ent_get_model_id(&dst)); + TEST_ASSERT_EQUAL(model_counter, cmp_ent_get_model_counter(&dst)); + + /* error cases */ + ret = compress_chunk_set_model_id_and_counter(&dst, GENERIC_HEADER_SIZE-1, model_id, model_counter); + TEST_ASSERT_TRUE(cmp_is_error(ret)); + TEST_ASSERT_EQUAL(CMP_ERROR_ENTITY_TOO_SMALL, cmp_get_error_code(ret)); + + ret = compress_chunk_set_model_id_and_counter(NULL, dst_size, model_id, model_counter); + TEST_ASSERT_TRUE(cmp_is_error(ret)); + TEST_ASSERT_EQUAL(CMP_ERROR_ENTITY_NULL, cmp_get_error_code(ret)); +} + + + void test_support_function_call_NULL(void) { struct cmp_cfg cfg = cmp_cfg_icu_create(DATA_TYPE_IMAGETTE, CMP_MODE_DIFF_ZERO, 16, CMP_LOSSLESS); @@ -4759,7 +4962,10 @@ void test_support_function_call_NULL(void) TEST_ASSERT_TRUE(cmp_cfg_imagette_is_invalid(NULL, RDCU_CHECK)); TEST_ASSERT_TRUE(cmp_cfg_fx_cob_is_invalid(NULL)); TEST_ASSERT_TRUE(cmp_cfg_aux_is_invalid(NULL)); + TEST_ASSERT_TRUE(cmp_cfg_aux_is_invalid(&cfg)); TEST_ASSERT_TRUE(cmp_cfg_icu_is_invalid(NULL)); + cfg.data_type = DATA_TYPE_UNKNOWN; + TEST_ASSERT_TRUE(cmp_cfg_icu_is_invalid(&cfg)); TEST_ASSERT_TRUE(cmp_cfg_fx_cob_get_need_pars(DATA_TYPE_S_FX, NULL)); } diff --git a/test/cmp_max_used_bits/test_cmp_max_used_bits_list.c b/test/cmp_max_used_bits/test_cmp_max_used_bits_list.c index 2557d827a1505219c5d7c7d7f71bab7e5766af51..21e6c08e71e17dd324fe4c11a48fb2f377ec4a81 100644 --- a/test/cmp_max_used_bits/test_cmp_max_used_bits_list.c +++ b/test/cmp_max_used_bits/test_cmp_max_used_bits_list.c @@ -17,22 +17,28 @@ */ +#if !defined(__sparc__) && !defined(_WIN32) && !defined(_WIN64) +# define MAKE_MALLOC_FAIL_TEST +# define _GNU_SOURCE +# include <dlfcn.h> +# include <stdlib.h> +#endif + #include <string.h> #include <unity.h> #include <cmp_max_used_bits_list.h> -#ifndef __sparc__ +#ifdef MAKE_MALLOC_FAIL_TEST /* if set the mock malloc will fail (return NULL) */ static int malloc_fail; /* * mock of the malloc function; can controlled with the global malloc_fail variable - * see:https://jayconrod.com/posts/23/tutorial--function-interposition-in-linux + * see: https://jayconrod.com/posts/23/tutorial--function-interposition-in-linux */ -#include <dlfcn.h> void* malloc(size_t size) { @@ -47,7 +53,6 @@ void* malloc(size_t size) TEST_ASSERT_NOT_NULL(real_malloc); } - fprintf(stderr, "malloc(%zu)\n", size); return real_malloc(size); } #endif @@ -181,7 +186,7 @@ void test_cmp_max_used_bits_list(void) cmp_max_used_bits_list_empty(); /* error case */ -#ifndef __sparc__ +#ifdef MAKE_MALLOC_FAIL_TEST malloc_fail = 1; return_val = cmp_max_used_bits_list_add(&i_36); TEST_ASSERT_EQUAL_INT(return_val, -1); diff --git a/test/cmp_rdcu_cfg/test_cmp_rdcu_cfg.c b/test/cmp_rdcu_cfg/test_cmp_rdcu_cfg.c index 36645f357b929ab8e22e4fb5fb0c0f48a6842d1f..89ab07d35dba5536586b756c2bc94fc600a100ba 100644 --- a/test/cmp_rdcu_cfg/test_cmp_rdcu_cfg.c +++ b/test/cmp_rdcu_cfg/test_cmp_rdcu_cfg.c @@ -61,16 +61,16 @@ void test_rdcu_cfg_create(void) /* wrong compression mode tests */ - cmp_mode = CMP_MODE_STUFF; /* not a RDCU compression mode */ + cmp_mode = (enum cmp_mode)(CMP_MODE_DIFF_MULTI+1); /* not a RDCU compression mode */ cfg = rdcu_cfg_create(data_type, cmp_mode, model_value, lossy_par); TEST_ASSERT_EQUAL(DATA_TYPE_UNKNOWN, cfg.data_type); - cmp_mode = -1U; + cmp_mode = (enum cmp_mode)-1U; cfg = rdcu_cfg_create(data_type, cmp_mode, model_value, lossy_par); TEST_ASSERT_EQUAL(DATA_TYPE_UNKNOWN, cfg.data_type); /* this should work */ - cmp_mode = 4; + cmp_mode = (enum cmp_mode)4; cfg = rdcu_cfg_create(data_type, cmp_mode, model_value, lossy_par); TEST_ASSERT_EQUAL(data_type, cfg.data_type); TEST_ASSERT_EQUAL(cmp_mode, cfg.cmp_mode); diff --git a/test/cmp_tool/meson.build b/test/cmp_tool/meson.build index 065cc4557853043de6dbd6a861fd620f603da24a..17b6ef1af62a64cf288809b7b3492dbc91dc7e2e 100644 --- a/test/cmp_tool/meson.build +++ b/test/cmp_tool/meson.build @@ -6,6 +6,7 @@ if pytest.found() pytest, args : ['--color=yes', '-vvv', int_test_file], depends : cmp_tool_exe, + timeout : 100, workdir : meson.project_build_root()) else message('Pytest framework not found! Skipping integration tests. Run pip install pytest.')