From 4fd8c3394ba016e4a6f331c1d02985bb08c4c594 Mon Sep 17 00:00:00 2001 From: Dominik Loidolt <dominik.loidolt@univie.ac.at> Date: Thu, 1 Sep 2022 14:05:43 +0200 Subject: [PATCH] fix a bug if setting the non_ima_spill2 non_ima_cmp_par2 in the cmp_ent_write_cmp_pars() functions add max_used_bits registry version to the compression entity header catch overflows in the cmp_cal_size_of_data() function --- include/cmp_data_types.h | 5 ++- include/cmp_entity.h | 4 ++- lib/cmp_data_types.c | 29 ++++++++++++--- lib/cmp_entity.c | 77 +++++++++++++++++++++++++++++++++------- test/meson.build | 1 + 5 files changed, 94 insertions(+), 22 deletions(-) diff --git a/include/cmp_data_types.h b/include/cmp_data_types.h index 9c8a470..8878557 100644 --- a/include/cmp_data_types.h +++ b/include/cmp_data_types.h @@ -84,7 +84,7 @@ /* struct holding the maximum length of the different data products types in bits */ struct cmp_max_used_bits { - unsigned int version; + uint8_t version; unsigned int s_exp_flags; unsigned int s_fx; unsigned int s_efx; @@ -127,8 +127,7 @@ struct cmp_max_used_bits { void cmp_set_max_used_bits(const struct cmp_max_used_bits *set_max_used_bits); struct cmp_max_used_bits cmp_get_max_used_bits(void); -/* for internal use only! */ -extern struct cmp_max_used_bits max_used_bits; +uint8_t cmp_get_max_used_bits_version(void); /* Source data header structure for multi entry packet */ diff --git a/include/cmp_entity.h b/include/cmp_entity.h index 0c9a606..c56cef5 100644 --- a/include/cmp_entity.h +++ b/include/cmp_entity.h @@ -116,7 +116,7 @@ struct cmp_entity { uint8_t model_value_used; /* used Model Updating Weighing Value */ uint16_t model_id; /* Model ID */ uint8_t model_counter; /* Model Counter */ - uint8_t spare; + uint8_t max_used_bits_version; uint16_t lossy_cmp_par_used; /* used Lossy Compression Parameters */ union { /* specific Compression Entity Header for the different Data Product Types */ struct imagette_header ima; @@ -174,6 +174,7 @@ int cmp_ent_set_cmp_mode(struct cmp_entity *ent, uint32_t cmp_mode_used); int cmp_ent_set_model_value(struct cmp_entity *ent, uint32_t model_value_used); int cmp_ent_set_model_id(struct cmp_entity *ent, uint32_t model_id); int cmp_ent_set_model_counter(struct cmp_entity *ent, uint32_t model_counter); +int cmp_ent_set_max_used_bits_version(struct cmp_entity *ent, uint8_t max_used_bits_version); int cmp_ent_set_lossy_cmp_par(struct cmp_entity *ent, uint32_t lossy_cmp_par_used); @@ -235,6 +236,7 @@ uint8_t cmp_ent_get_model_value_used(struct cmp_entity *ent); uint16_t cmp_ent_get_model_id(struct cmp_entity *ent); uint8_t cmp_ent_get_model_counter(struct cmp_entity *ent); +uint8_t cmp_ent_get_max_used_bits_version(struct cmp_entity *ent); uint16_t cmp_ent_get_lossy_cmp_par(struct cmp_entity *ent); diff --git a/lib/cmp_data_types.c b/lib/cmp_data_types.c index 8dd5792..5a01f8b 100644 --- a/lib/cmp_data_types.c +++ b/lib/cmp_data_types.c @@ -20,6 +20,8 @@ #include <cmp_data_types.h> #include <cmp_debug.h> #include <byteorder.h> +#include <stdint.h> +#include <stdio.h> /* the maximum length of the different data products types in bits */ @@ -88,6 +90,17 @@ struct cmp_max_used_bits cmp_get_max_used_bits(void) } +/** + * @brief get the version record form the max used bits registry + * + * @returns version of the max used bits registry + */ + +uint8_t cmp_get_max_used_bits_version(void) { + return max_used_bits.version; +} + + /** * @brief calculate the size of a sample for the different compression data type * @@ -106,6 +119,8 @@ size_t size_of_a_sample(enum cmp_data_type data_type) case DATA_TYPE_IMAGETTE_ADAPTIVE: case DATA_TYPE_SAT_IMAGETTE: case DATA_TYPE_SAT_IMAGETTE_ADAPTIVE: + case DATA_TYPE_F_CAM_IMAGETTE: + case DATA_TYPE_F_CAM_IMAGETTE_ADAPTIVE: sample_size = sizeof(uint16_t); break; case DATA_TYPE_OFFSET: @@ -155,7 +170,7 @@ size_t size_of_a_sample(enum cmp_data_type data_type) break; case DATA_TYPE_F_CAM_OFFSET: case DATA_TYPE_F_CAM_BACKGROUND: - case DATA_TYPE_UNKOWN: + case DATA_TYPE_UNKNOWN: default: debug_print("Error: Compression data type is not supported.\n"); break; @@ -178,16 +193,20 @@ size_t size_of_a_sample(enum cmp_data_type data_type) unsigned int cmp_cal_size_of_data(unsigned int samples, enum cmp_data_type data_type) { unsigned int s = size_of_a_sample(data_type); + uint64_t x; /* use 64 bit to catch overflow */ if (!s) return 0; - s *= samples; + x = (uint64_t)s*samples; if (!rdcu_supported_data_type_is_used(data_type)) - s += MULTI_ENTRY_HDR_SIZE; + x += MULTI_ENTRY_HDR_SIZE; + + if (x > UINT32_MAX) /* catch overflow */ + return 0; - return s; + return (unsigned int)x; } @@ -510,7 +529,7 @@ int cmp_input_big_to_cpu_endianness(void *data, uint32_t data_size_byte, /* TODO: implement F_CAM conversion */ case DATA_TYPE_F_CAM_OFFSET: case DATA_TYPE_F_CAM_BACKGROUND: - case DATA_TYPE_UNKOWN: + case DATA_TYPE_UNKNOWN: default: debug_print("Error: Can not swap endianness for this compression data type.\n"); return -1; diff --git a/lib/cmp_entity.c b/lib/cmp_entity.c index 0296894..6a5b040 100644 --- a/lib/cmp_entity.c +++ b/lib/cmp_entity.c @@ -97,7 +97,7 @@ uint32_t cmp_ent_cal_hdr_size(enum cmp_data_type data_type, int raw_mode_flag) case DATA_TYPE_F_CAM_BACKGROUND: size = NON_IMAGETTE_HEADER_SIZE; break; - case DATA_TYPE_UNKOWN: + case DATA_TYPE_UNKNOWN: size = 0; break; } @@ -442,6 +442,27 @@ int cmp_ent_set_model_counter(struct cmp_entity *ent, uint32_t model_counter) } +/** + * @brief set version identifier for the max. used bits registry in the + * compression entity header + * + * @param ent pointer to a compression entity + * @param max_used_bits_version the identifier for the max. used bits registry + * + * @returns 0 on success, otherwise error + */ + +int cmp_ent_set_max_used_bits_version(struct cmp_entity *ent, uint8_t max_used_bits_version) +{ + if (!ent) + return -1; + + ent->max_used_bits_version = max_used_bits_version; + + return 0; +} + + /** * @brief set the used lossy compression parameter in the compression entity * header @@ -1108,7 +1129,7 @@ uint16_t cmp_ent_get_fine_end_time(struct cmp_entity *ent) * @param ent pointer to a compression entity * * @returns the data_type NOT including the uncompressed data bit on success, - * DATA_TYPE_UNKOWN on error + * DATA_TYPE_UNKNOWN on error */ enum cmp_data_type cmp_ent_get_data_type(struct cmp_entity *ent) @@ -1116,13 +1137,13 @@ enum cmp_data_type cmp_ent_get_data_type(struct cmp_entity *ent) enum cmp_data_type data_type; if (!ent) - return DATA_TYPE_UNKOWN; + return DATA_TYPE_UNKNOWN; data_type = be16_to_cpu(ent->data_type); data_type &= (1U << RAW_BIT_DATA_TYPE_POS)-1; /* remove uncompressed data flag */ if (!cmp_data_type_valid(data_type)) - data_type = DATA_TYPE_UNKOWN; + data_type = DATA_TYPE_UNKNOWN; return data_type; } @@ -1214,6 +1235,25 @@ uint8_t cmp_ent_get_model_counter(struct cmp_entity *ent) } +/** + * @brief get the version identifier for the max. used bits registry from the + * compression entity header + * + * @param ent pointer to a compression entity + * + * @returns the version identifier for the max. used bits registry on success, + * 0 on error + */ + +uint8_t cmp_ent_get_max_use_bits_version(struct cmp_entity *ent) +{ + if (!ent) + return 0; + + return ent->max_used_bits_version; +} + + /** * @brief get the used lossy compression parameter from the compression entity header * @@ -1598,10 +1638,15 @@ void *cmp_ent_get_data_buf(struct cmp_entity *ent) if (!ent) return NULL; + data_type = cmp_ent_get_data_type(ent); + if (!cmp_data_type_valid(data_type)) { + debug_print("Error: Compression data type not supported.\n"); + return NULL; + } + if (cmp_ent_get_data_type_raw_bit(ent)) return (uint8_t *)ent + GENERIC_HEADER_SIZE; - data_type = cmp_ent_get_data_type(ent); switch (data_type) { case DATA_TYPE_IMAGETTE: @@ -1630,7 +1675,8 @@ void *cmp_ent_get_data_buf(struct cmp_entity *ent) case DATA_TYPE_F_CAM_OFFSET: case DATA_TYPE_F_CAM_BACKGROUND: return ent->non_ima.cmp_data; - case DATA_TYPE_UNKOWN: + case DATA_TYPE_UNKNOWN: + default: return NULL; } @@ -1777,6 +1823,8 @@ int cmp_ent_write_cmp_pars(struct cmp_entity *ent, const struct cmp_cfg *cfg, return -1; if (cmp_ent_set_model_value(ent, cfg->model_value)) return -1; + if (cmp_ent_set_max_used_bits_version(ent, cmp_get_max_used_bits_version())) + return -1; if (cmp_ent_set_lossy_cmp_par(ent, cfg->round)) return -1; @@ -1819,9 +1867,9 @@ int cmp_ent_write_cmp_pars(struct cmp_entity *ent, const struct cmp_cfg *cfg, if (cmp_ent_set_non_ima_spill1(ent, cfg->spill_mean)) return -1; - if (cmp_ent_set_non_ima_spill2(ent, cfg->cmp_par_variance)) + if (cmp_ent_set_non_ima_cmp_par2(ent, cfg->cmp_par_variance)) return -1; - if (cmp_ent_set_non_ima_cmp_par2(ent, cfg->spill_variance)) + if (cmp_ent_set_non_ima_spill2(ent, cfg->spill_variance)) return -1; if (cmp_ent_set_non_ima_cmp_par3(ent, cfg->cmp_par_pixels_error)) @@ -1892,7 +1940,7 @@ int cmp_ent_write_cmp_pars(struct cmp_entity *ent, const struct cmp_cfg *cfg, /* TODO: fix this*/ return -1; break; - case DATA_TYPE_UNKOWN: + case DATA_TYPE_UNKNOWN: default: return -1; } @@ -2187,7 +2235,7 @@ int cmp_ent_read_header(struct cmp_entity *ent, struct cmp_cfg *cfg) /* TODO: fix this*/ return -1; break; - case DATA_TYPE_UNKOWN: /* fall through */ + case DATA_TYPE_UNKNOWN: /* fall through */ default: return -1; } @@ -2341,8 +2389,8 @@ void cmp_ent_print(struct cmp_entity *ent) static void cmp_ent_parse_generic_header(struct cmp_entity *ent) { uint32_t version_id, cmp_ent_size, original_size, cmp_mode_used, - model_value_used, model_id, model_counter, lossy_cmp_par_used, - start_coarse_time, end_coarse_time; + model_value_used, model_id, model_counter, max_used_bits_version, + lossy_cmp_par_used, start_coarse_time, end_coarse_time; uint16_t start_fine_time, end_fine_time; enum cmp_data_type data_type; int raw_bit; @@ -2386,7 +2434,7 @@ static void cmp_ent_parse_generic_header(struct cmp_entity *ent) + ((end_fine_time - start_fine_time)/256./256.)); data_type = cmp_ent_get_data_type(ent); - if (data_type != DATA_TYPE_UNKOWN) + if (data_type != DATA_TYPE_UNKNOWN) printf("Data Product Type: %d\n", data_type); else printf("Data Product Type: unknown!"); @@ -2406,6 +2454,9 @@ static void cmp_ent_parse_generic_header(struct cmp_entity *ent) model_counter = cmp_ent_get_model_counter(ent); printf("Model Counter: %u\n", model_counter); + max_used_bits_version = cmp_ent_get_max_use_bits_version(ent); + printf("Maximum Used Bits Registry Version: %u\n", max_used_bits_version); + lossy_cmp_par_used = cmp_ent_get_lossy_cmp_par(ent); printf("Used Lossy Compression Parameters: %u\n", lossy_cmp_par_used); } diff --git a/test/meson.build b/test/meson.build index 4743653..145cdb8 100644 --- a/test/meson.build +++ b/test/meson.build @@ -37,3 +37,4 @@ subdir('cmp_tool') unity_dep = dependency('unity', fallback : ['unity', 'unity_dep']) subdir('cmp_icu') +subdir('cmp_data_types') -- GitLab