Coverage Report

Created: 2025-06-15 00:57

/src/cmp_tool/lib/common/cmp_support.c
Line
Count
Source (jump to first uncovered line)
1
/**
2
 * @file   cmp_support.c
3
 * @author Dominik Loidolt (dominik.loidolt@univie.ac.at)
4
 * @date   2019
5
 *
6
 * @copyright GPLv2
7
 * This program is free software; you can redistribute it and/or modify it
8
 * under the terms and conditions of the GNU General Public License,
9
 * version 2, as published by the Free Software Foundation.
10
 *
11
 * This program is distributed in the hope it will be useful, but WITHOUT
12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14
 * more details.
15
 *
16
 * @brief compressor support library
17
 * @see Data Compression User Manual PLATO-UVIE-PL-UM-0001
18
 */
19
20
#include <stdint.h>
21
22
#include "compiler.h"
23
24
#include "cmp_support.h"
25
#include "cmp_debug.h"
26
#include "leon_inttypes.h"
27
#include "cmp_cal_up_model.h"
28
29
30
/**
31
 * @brief implementation of the logarithm base of floor(log2(x)) for integers
32
 * @note ilog_2(0) = -1 defined
33
 *
34
 * @param x input parameter
35
 *
36
 * @returns the result of floor(log2(x))
37
 */
38
39
unsigned int ilog_2(uint32_t x)
40
151k
{
41
151k
  if (!x)
42
739
    return -1U;
43
44
150k
  return 31 - (unsigned int)__builtin_clz(x);
45
151k
}
46
47
48
/**
49
 * @brief determining if an integer is a power of 2
50
 * @note 0 is incorrectly considered a power of 2 here
51
 *
52
 * @param v we want to see if v is a power of 2
53
 *
54
 * @returns 1 if v is a power of 2, otherwise 0
55
 *
56
 * @note see: https://graphics.stanford.edu/~seander/bithacks.html#DetermineIfPowerOf2
57
 */
58
59
int is_a_pow_of_2(unsigned int v)
60
42.5k
{
61
42.5k
  return (((v) & ((v) - 1)) == 0);
62
42.5k
}
63
64
65
/**
66
 * @brief check if the compression entity data product type is supported
67
 *
68
 * @param data_type compression entity data product type to check
69
 *
70
 * @returns non-zero if data_type is invalid; zero if data_type is valid
71
 */
72
73
int cmp_data_type_is_invalid(enum cmp_data_type data_type)
74
20.6k
{
75
20.6k
  if (data_type <= DATA_TYPE_UNKNOWN || data_type > DATA_TYPE_CHUNK)
76
0
    return 1;
77
78
20.6k
  return 0;
79
20.6k
}
80
81
82
/**
83
 * @brief check if a model mode is selected
84
 *
85
 * @param cmp_mode  compression mode
86
 *
87
 * @returns 1 when the model mode is used, otherwise 0
88
 */
89
90
int model_mode_is_used(enum cmp_mode cmp_mode)
91
93.4k
{
92
93.4k
  if (cmp_mode == CMP_MODE_MODEL_ZERO ||
93
93.4k
      cmp_mode == CMP_MODE_MODEL_MULTI)
94
40.9k
    return 1;
95
96
52.4k
  return 0;
97
93.4k
}
98
99
100
/**
101
 * @brief check if the raw mode is selected
102
 *
103
 * @param cmp_mode  compression mode
104
 *
105
 * @returns 1 when the raw mode is used, otherwise 0
106
 */
107
108
int raw_mode_is_used(enum cmp_mode cmp_mode)
109
31.8k
{
110
31.8k
  if (cmp_mode == CMP_MODE_RAW)
111
15.7k
    return 1;
112
113
16.1k
  return 0;
114
31.8k
}
115
116
117
/**
118
 * @brief check if the data product data type is supported by the RDCU compressor
119
 *
120
 * @param data_type compression data product type
121
 *
122
 * @returns 1 when the data type is supported by the RDCU, otherwise 0
123
 */
124
125
int rdcu_supported_data_type_is_used(enum cmp_data_type data_type)
126
26.3k
{
127
26.3k
  switch (data_type) {
128
1.60k
  case DATA_TYPE_IMAGETTE:
129
1.60k
  case DATA_TYPE_IMAGETTE_ADAPTIVE:
130
10.7k
  case DATA_TYPE_SAT_IMAGETTE:
131
10.7k
  case DATA_TYPE_SAT_IMAGETTE_ADAPTIVE:
132
11.3k
  case DATA_TYPE_F_CAM_IMAGETTE:
133
11.3k
  case DATA_TYPE_F_CAM_IMAGETTE_ADAPTIVE:
134
11.3k
    return 1;
135
14.9k
  default:
136
14.9k
    return 0;
137
26.3k
  }
138
26.3k
}
139
140
141
/**
142
 * @brief check if the compression mode is supported for an ICU compression
143
 *
144
 * @param cmp_mode  compression mode
145
 *
146
 * @returns 1 when the compression mode is supported, otherwise 0
147
 */
148
149
int cmp_mode_is_supported(enum cmp_mode cmp_mode)
150
20.6k
{
151
20.6k
  switch (cmp_mode) {
152
2.63k
  case CMP_MODE_RAW:
153
6.37k
  case CMP_MODE_MODEL_ZERO:
154
11.8k
  case CMP_MODE_DIFF_ZERO:
155
16.7k
  case CMP_MODE_MODEL_MULTI:
156
20.6k
  case CMP_MODE_DIFF_MULTI:
157
20.6k
    return 1;
158
1
  default:
159
1
    return 0;
160
20.6k
  }
161
20.6k
}
162
163
164
/**
165
 * @brief check if zero escape symbol mechanism mode is used
166
 *
167
 * @param cmp_mode  compression mode
168
 *
169
 * @returns 1 when zero escape symbol mechanism is set, otherwise 0
170
 */
171
172
int zero_escape_mech_is_used(enum cmp_mode cmp_mode)
173
8.11k
{
174
8.11k
  if (cmp_mode == CMP_MODE_MODEL_ZERO ||
175
8.11k
      cmp_mode == CMP_MODE_DIFF_ZERO)
176
4.66k
    return 1;
177
178
3.44k
  return 0;
179
8.11k
}
180
181
182
/**
183
 * @brief check if multi escape symbol mechanism mode is used
184
 *
185
 * @param cmp_mode  compression mode
186
 *
187
 * @returns 1 when multi escape symbol mechanism is set, otherwise 0
188
 */
189
190
int multi_escape_mech_is_used(enum cmp_mode cmp_mode)
191
0
{
192
0
  if (cmp_mode == CMP_MODE_MODEL_MULTI ||
193
0
      cmp_mode == CMP_MODE_DIFF_MULTI)
194
0
    return 1;
195
196
0
  return 0;
197
0
}
198
199
200
/**
201
 * @brief check if an imagette compression data type is used
202
 * @note adaptive imagette compression data types included
203
 *
204
 * @param data_type compression data type
205
 *
206
 * @returns 1 when data_type is an imagette data type, otherwise 0
207
 */
208
209
int cmp_imagette_data_type_is_used(enum cmp_data_type data_type)
210
26.3k
{
211
26.3k
  return rdcu_supported_data_type_is_used(data_type);
212
26.3k
}
213
214
215
/**
216
 * @brief check if an adaptive imagette compression data type is used
217
 *
218
 * @param data_type compression data type
219
 *
220
 * @returns 1 when data_type is an adaptive imagette data type, otherwise 0
221
 */
222
223
int cmp_ap_imagette_data_type_is_used(enum cmp_data_type data_type)
224
0
{
225
0
  switch (data_type) {
226
0
  case DATA_TYPE_IMAGETTE_ADAPTIVE:
227
0
  case DATA_TYPE_SAT_IMAGETTE_ADAPTIVE:
228
0
  case DATA_TYPE_F_CAM_IMAGETTE_ADAPTIVE:
229
0
    return 1;
230
0
  default:
231
0
    return 0;
232
0
  }
233
0
}
234
235
236
/**
237
 * @brief check if a flux/center of brightness compression data type is used
238
 *
239
 * @param data_type compression data type
240
 *
241
 * @returns 1 when data_type is a flux/center of brightness data type, otherwise 0
242
 */
243
244
int cmp_fx_cob_data_type_is_used(enum cmp_data_type data_type)
245
23.0k
{
246
23.0k
  switch (data_type) {
247
1.93k
  case DATA_TYPE_S_FX:
248
5.35k
  case DATA_TYPE_S_FX_EFX:
249
9.67k
  case DATA_TYPE_S_FX_NCOB:
250
11.5k
  case DATA_TYPE_S_FX_EFX_NCOB_ECOB:
251
12.8k
  case DATA_TYPE_L_FX:
252
13.9k
  case DATA_TYPE_L_FX_EFX:
253
14.9k
  case DATA_TYPE_L_FX_NCOB:
254
16.2k
  case DATA_TYPE_L_FX_EFX_NCOB_ECOB:
255
16.2k
  case DATA_TYPE_F_FX:
256
16.2k
  case DATA_TYPE_F_FX_EFX:
257
16.2k
  case DATA_TYPE_F_FX_NCOB:
258
16.2k
  case DATA_TYPE_F_FX_EFX_NCOB_ECOB:
259
16.2k
    return 1;
260
6.86k
  default:
261
6.86k
    return 0;
262
23.0k
  }
263
23.0k
}
264
265
266
/**
267
 * @brief check if an auxiliary science compression data type is used
268
 *
269
 * @param data_type compression data type
270
 *
271
 * @returns 1 when data_type is an auxiliary science data type, otherwise 0
272
 */
273
274
int cmp_aux_data_type_is_used(enum cmp_data_type data_type)
275
0
{
276
0
  switch (data_type) {
277
0
  case DATA_TYPE_OFFSET:
278
0
  case DATA_TYPE_BACKGROUND:
279
0
  case DATA_TYPE_SMEARING:
280
0
  case DATA_TYPE_F_CAM_OFFSET:
281
0
  case DATA_TYPE_F_CAM_BACKGROUND:
282
0
    return 1;
283
0
  default:
284
0
    return 0;
285
0
  }
286
0
}
287
288
289
/**
290
 * @brief get the maximum valid spill threshold value for a imagette
291
 *  compression in diff or model mode
292
 *
293
 * @param golomb_par  Golomb parameter
294
 *
295
 * @returns the highest still valid spill threshold value for a diff of model
296
 *   mode compression; 0 if golomb_par is invalid
297
 */
298
299
uint32_t cmp_ima_max_spill(unsigned int golomb_par)
300
0
{
301
  /* the RDCU can only generate 16 bit long code words -> lower max spill needed */
302
0
  const uint32_t LUT_MAX_RDCU[MAX_IMA_GOLOMB_PAR+1] = { 0, 8, 22, 35, 48,
303
0
    60, 72, 84, 96, 107, 118, 129, 140, 151, 162, 173, 184, 194,
304
0
    204, 214, 224, 234, 244, 254, 264, 274, 284, 294, 304, 314, 324,
305
0
    334, 344, 353, 362, 371, 380, 389, 398, 407, 416, 425, 434, 443,
306
0
    452, 461, 470, 479, 488, 497, 506, 515, 524, 533, 542, 551, 560,
307
0
    569, 578, 587, 596, 605, 614, 623 };
308
309
0
  if (golomb_par >= ARRAY_SIZE(LUT_MAX_RDCU))
310
0
    return 0;
311
312
0
  return LUT_MAX_RDCU[golomb_par];
313
0
}
314
315
316
/**
317
 * @brief get the maximum valid spill threshold value for a non-imagette compression
318
 *  in diff or model mode
319
 *
320
 * @param cmp_par compression parameter
321
 *
322
 * @returns the highest still valid spill threshold value for diff or model
323
 *  mode compression; 0 if the cmp_par is not valid
324
 */
325
326
uint32_t cmp_icu_max_spill(unsigned int cmp_par)
327
54.0k
{
328
  /* the ICU compressor can generate code words with a length of maximal 32 bits. */
329
54.0k
  unsigned int const max_cw_bits = 32;
330
54.0k
  unsigned int const cutoff = (0x2U << (ilog_2(cmp_par) & 0x1FU)) - cmp_par;
331
54.0k
  unsigned int const max_n_sym_offset = (max_cw_bits/2) - 1;
332
333
54.0k
  if (!cmp_par || cmp_par > MAX_NON_IMA_GOLOMB_PAR)
334
2.69k
    return 0;
335
336
51.3k
  return ((max_cw_bits-1-ilog_2(cmp_par))*cmp_par) + cutoff
337
51.3k
    - max_n_sym_offset - 1;
338
54.0k
}
339
340
341
/**
342
 * @brief calculate the need bytes to hold a bitstream
343
 *
344
 * @param cmp_size_bit  compressed data size, measured in bits
345
 *
346
 * @returns the size in bytes to store the hole bitstream
347
 */
348
349
unsigned int cmp_bit_to_byte(unsigned int cmp_size_bit)
350
20.5k
{
351
20.5k
  return (cmp_size_bit + 7) / 8;
352
20.5k
}
353
354
355
/**
356
 * @brief check if the compression data type, compression mode, model value and
357
 *  the lossy rounding parameters are invalid for a RDCU or ICU compression
358
 *
359
 * @param cfg pointer to a compression configuration containing the compression
360
 *  data product type, compression mode, model value and the rounding parameters
361
 *
362
 * @returns 0 if the compression data type, compression mode, model value and
363
 *  the lossy rounding parameters are valid for an RDCU or ICU compression,
364
 *  non-zero if parameters are invalid
365
 */
366
367
int cmp_cfg_gen_par_is_invalid(const struct cmp_cfg *cfg)
368
20.6k
{
369
20.6k
  int cfg_invalid = 0;
370
371
20.6k
  if (!cfg)
372
0
    return 1;
373
374
20.6k
  if (cmp_data_type_is_invalid(cfg->data_type)) {
375
0
    debug_print("Error: selected compression data type is not supported.");
376
0
    cfg_invalid++;
377
0
  }
378
379
20.6k
  if (!cmp_mode_is_supported(cfg->cmp_mode)) {
380
1
    debug_print("Error: selected cmp_mode: %i is not supported.", cfg->cmp_mode);
381
1
    cfg_invalid++;
382
1
  }
383
384
20.6k
  if (model_mode_is_used(cfg->cmp_mode)) {
385
8.56k
    if (cfg->model_value > MAX_MODEL_VALUE) {
386
3
      debug_print("Error: selected model_value: %" PRIu32 " is invalid. The largest supported value is: %u.",
387
3
            cfg->model_value, MAX_MODEL_VALUE);
388
3
      cfg_invalid++;
389
3
    }
390
8.56k
  }
391
392
20.6k
  if (cfg->round > MAX_ICU_ROUND) {
393
0
    debug_print("Error: selected lossy parameter: %" PRIu32 " is not supported. The largest supported value is: %" PRIu32 ".",
394
0
          cfg->round, MAX_ICU_ROUND);
395
0
    cfg_invalid++;
396
0
  }
397
398
#ifdef SKIP_CMP_PAR_CHECK
399
  return 0;
400
#endif
401
20.6k
  return cfg_invalid;
402
20.6k
}
403
404
405
/**
406
 * @brief check if the combination of the different compression parameters is invalid
407
 *
408
 * @param cmp_par compression parameter
409
 * @param spill   spillover threshold parameter
410
 * @param cmp_mode  compression mode
411
 * @param par_name  string describing the use of the compression par. for
412
 *      debug messages (can be NULL)
413
 *
414
 * @returns 0 if the parameter combination is valid, otherwise the combination is invalid
415
 */
416
417
static int cmp_pars_are_invalid(uint32_t cmp_par, uint32_t spill, enum cmp_mode cmp_mode,
418
        const char *par_name MAYBE_UNUSED)
419
52.2k
{
420
52.2k
  int cfg_invalid = 0;
421
422
52.2k
  switch (cmp_mode) {
423
6.32k
  case CMP_MODE_RAW:
424
    /* no checks needed */
425
6.32k
    break;
426
16.2k
  case CMP_MODE_DIFF_ZERO:
427
27.3k
  case CMP_MODE_DIFF_MULTI:
428
37.9k
  case CMP_MODE_MODEL_ZERO:
429
45.8k
  case CMP_MODE_MODEL_MULTI:
430
45.8k
    if (cmp_par < MIN_NON_IMA_GOLOMB_PAR || cmp_par > MAX_NON_IMA_GOLOMB_PAR) {
431
85
      debug_print("Error: The selected %s compression parameter: %" PRIu32 " is not supported in the selected compression mode. The compression parameter has to be between [%" PRIu32 ", %" PRIu32 "] in this mode.",
432
85
            par_name, cmp_par, MIN_NON_IMA_GOLOMB_PAR, MAX_NON_IMA_GOLOMB_PAR);
433
85
      cfg_invalid++;
434
85
    }
435
45.8k
    if (spill < MIN_NON_IMA_SPILL) {
436
85
      debug_print("Error: The selected %s spillover threshold value: %" PRIu32 " is too small. The smallest possible spillover value is: %" PRIu32 ".",
437
85
            par_name, spill, MIN_NON_IMA_SPILL);
438
85
      cfg_invalid++;
439
85
    }
440
45.8k
    if (spill > cmp_icu_max_spill(cmp_par)) {
441
0
      debug_print("Error: The selected %s spillover threshold value: %" PRIu32 " is too large for the selected %s compression parameter: %" PRIu32 ". The largest possible spillover value in the selected compression mode is: %" PRIu32 ".",
442
0
            par_name, spill, par_name, cmp_par, cmp_icu_max_spill(cmp_par));
443
0
      cfg_invalid++;
444
0
    }
445
446
45.8k
    break;
447
0
  default:
448
0
    debug_print("Error: selected cmp_mode: %i is not supported.", cmp_mode);
449
0
    cfg_invalid++;
450
0
    break;
451
52.2k
  }
452
453
#ifdef SKIP_CMP_PAR_CHECK
454
  return 0;
455
#endif
456
52.2k
  return cfg_invalid;
457
52.2k
}
458
459
460
/**
461
 * @brief check if the imagette specific compression parameters are invalid
462
 *
463
 * @param cfg   pointer to a compressor configuration
464
 *
465
 * @returns 0 if the imagette specific parameters are valid, otherwise invalid
466
 */
467
468
int cmp_cfg_imagette_is_invalid(const struct cmp_cfg *cfg)
469
5.69k
{
470
5.69k
  int cfg_invalid = 0;
471
472
5.69k
  if (!cfg)
473
0
    return 1;
474
475
5.69k
  if (!cmp_imagette_data_type_is_used(cfg->data_type)) {
476
0
    debug_print("Error: The compression data type is not an imagette compression data type.");
477
0
    cfg_invalid++;
478
0
  }
479
480
5.69k
  cfg_invalid += cmp_pars_are_invalid(cfg->cmp_par_imagette, cfg->spill_imagette,
481
5.69k
              cfg->cmp_mode, "imagette");
482
5.69k
  return cfg_invalid;
483
5.69k
}
484
485
486
/**
487
 * @brief get needed compression parameter pairs for a flux/center of brightness
488
 *  data type
489
 *
490
 * @param data_type a flux/center of brightness data type
491
 * @param par   pointer to a structure containing flux/COB compression
492
 *      parameters pairs
493
 *
494
 * @returns 0 on success and sets the needed compression parameter pairs in the
495
 *  par struct, otherwise error
496
 */
497
498
int cmp_cfg_fx_cob_get_need_pars(enum cmp_data_type data_type, struct fx_cob_par *par)
499
8.10k
{
500
8.10k
  if (!par)
501
0
    return -1;
502
503
8.10k
  par->exp_flags = 0;
504
8.10k
  par->fx = 0;
505
8.10k
  par->ncob = 0;
506
8.10k
  par->efx = 0;
507
8.10k
  par->ecob = 0;
508
8.10k
  par->fx_cob_variance = 0;
509
510
  /* flux parameter is needed for every fx_cob data_type */
511
8.10k
  par->fx = 1;
512
513
8.10k
  switch (data_type) {
514
969
  case DATA_TYPE_S_FX:
515
969
    par->exp_flags = 1;
516
969
    break;
517
1.70k
  case DATA_TYPE_S_FX_EFX:
518
1.70k
    par->exp_flags = 1;
519
1.70k
    par->efx = 1;
520
1.70k
    break;
521
2.15k
  case DATA_TYPE_S_FX_NCOB:
522
2.15k
    par->exp_flags = 1;
523
2.15k
    par->ncob = 1;
524
2.15k
    break;
525
931
  case DATA_TYPE_S_FX_EFX_NCOB_ECOB:
526
931
    par->exp_flags = 1;
527
931
    par->ncob = 1;
528
931
    par->efx = 1;
529
931
    par->ecob = 1;
530
931
    break;
531
676
  case DATA_TYPE_L_FX:
532
676
    par->exp_flags = 1;
533
676
    par->fx_cob_variance = 1;
534
676
    break;
535
534
  case DATA_TYPE_L_FX_EFX:
536
534
    par->exp_flags = 1;
537
534
    par->efx = 1;
538
534
    par->fx_cob_variance = 1;
539
534
    break;
540
496
  case DATA_TYPE_L_FX_NCOB:
541
496
    par->exp_flags = 1;
542
496
    par->ncob = 1;
543
496
    par->fx_cob_variance = 1;
544
496
    break;
545
633
  case DATA_TYPE_L_FX_EFX_NCOB_ECOB:
546
633
    par->exp_flags = 1;
547
633
    par->ncob = 1;
548
633
    par->efx = 1;
549
633
    par->ecob = 1;
550
633
    par->fx_cob_variance = 1;
551
633
    break;
552
0
  case DATA_TYPE_F_FX:
553
0
    break;
554
0
  case DATA_TYPE_F_FX_EFX:
555
0
    par->efx = 1;
556
0
    break;
557
0
  case DATA_TYPE_F_FX_NCOB:
558
0
    par->ncob = 1;
559
0
    break;
560
0
  case DATA_TYPE_F_FX_EFX_NCOB_ECOB:
561
0
    par->ncob = 1;
562
0
    par->efx = 1;
563
0
    par->ecob = 1;
564
0
    break;
565
0
  default:
566
0
    return -1;
567
8.10k
  }
568
8.10k
  return 0;
569
8.10k
}
570
571
572
/**
573
 * @brief check if the flux/center of brightness specific compression parameters
574
 *  are invalid
575
 *
576
 * @param cfg pointer to the compressor configuration
577
 *
578
 * @returns 0 if the flux/center of brightness specific parameters are valid, otherwise invalid
579
 */
580
581
int cmp_cfg_fx_cob_is_invalid(const struct cmp_cfg *cfg)
582
8.10k
{
583
8.10k
  int cfg_invalid = 0;
584
8.10k
  struct fx_cob_par needed_pars;
585
586
8.10k
  if (!cfg)
587
0
    return 1;
588
589
8.10k
  if (!cmp_fx_cob_data_type_is_used(cfg->data_type)) {
590
0
    debug_print("Error: The compression data type is not a flux/center of brightness compression data type.");
591
0
    cfg_invalid++;
592
0
  }
593
594
8.10k
  cmp_cfg_fx_cob_get_need_pars(cfg->data_type, &needed_pars);
595
596
8.10k
  if (needed_pars.fx) /* this is always true because every flux/center of brightness data type contains a flux parameter */
597
8.10k
    cfg_invalid += cmp_pars_are_invalid(cfg->cmp_par_fx, cfg->spill_fx,
598
8.10k
                cfg->cmp_mode, "flux");
599
8.10k
  if (needed_pars.exp_flags)
600
8.10k
    cfg_invalid += cmp_pars_are_invalid(cfg->cmp_par_exp_flags, cfg->spill_exp_flags,
601
8.10k
      cfg->cmp_mode, "exposure flags");
602
8.10k
  if (needed_pars.ncob)
603
4.21k
    cfg_invalid += cmp_pars_are_invalid(cfg->cmp_par_ncob, cfg->spill_ncob,
604
4.21k
      cfg->cmp_mode, "center of brightness");
605
8.10k
  if (needed_pars.efx)
606
3.80k
    cfg_invalid += cmp_pars_are_invalid(cfg->cmp_par_efx, cfg->spill_efx,
607
3.80k
      cfg->cmp_mode, "extended flux");
608
8.10k
  if (needed_pars.ecob)
609
1.56k
    cfg_invalid += cmp_pars_are_invalid(cfg->cmp_par_ecob, cfg->spill_ecob,
610
1.56k
      cfg->cmp_mode, "extended center of brightness");
611
8.10k
  if (needed_pars.fx_cob_variance)
612
2.33k
    cfg_invalid += cmp_pars_are_invalid(cfg->cmp_par_fx_cob_variance,
613
2.33k
      cfg->spill_fx_cob_variance, cfg->cmp_mode, "flux/COB variance");
614
615
8.10k
  return cfg_invalid;
616
8.10k
}
617
618
619
/**
620
 * @brief check if the auxiliary science specific compression parameters are invalid
621
 *
622
 * @param cfg pointer to the compressor configuration
623
 *
624
 * @returns 0 if the auxiliary science specific parameters are valid, otherwise
625
 *  invalid
626
 */
627
628
int cmp_cfg_aux_is_invalid(const struct cmp_cfg *cfg)
629
6.86k
{
630
6.86k
  int cfg_invalid = 0;
631
632
6.86k
  if (!cfg)
633
0
    return 1;
634
635
6.86k
  switch (cfg->data_type) {
636
1.99k
  case DATA_TYPE_OFFSET:
637
2.19k
  case DATA_TYPE_F_CAM_OFFSET:
638
2.19k
    cfg_invalid += cmp_pars_are_invalid(cfg->cmp_par_offset_mean, cfg->spill_offset_mean,
639
2.19k
        cfg->cmp_mode, "offset mean");
640
2.19k
    cfg_invalid += cmp_pars_are_invalid(cfg->cmp_par_offset_variance, cfg->spill_offset_variance,
641
2.19k
        cfg->cmp_mode, "offset variance");
642
2.19k
    break;
643
1.32k
  case DATA_TYPE_BACKGROUND:
644
2.23k
  case DATA_TYPE_F_CAM_BACKGROUND:
645
2.23k
    cfg_invalid += cmp_pars_are_invalid(cfg->cmp_par_background_mean, cfg->spill_background_mean,
646
2.23k
        cfg->cmp_mode, "background mean");
647
2.23k
    cfg_invalid += cmp_pars_are_invalid(cfg->cmp_par_background_variance, cfg->spill_background_variance,
648
2.23k
        cfg->cmp_mode, "background variance");
649
2.23k
    cfg_invalid += cmp_pars_are_invalid(cfg->cmp_par_background_pixels_error, cfg->spill_background_pixels_error,
650
2.23k
        cfg->cmp_mode, "background outlier pixls num");
651
2.23k
    break;
652
2.42k
  case DATA_TYPE_SMEARING:
653
2.42k
    cfg_invalid += cmp_pars_are_invalid(cfg->cmp_par_smearing_mean, cfg->spill_smearing_mean,
654
2.42k
        cfg->cmp_mode, "smearing mean");
655
2.42k
    cfg_invalid += cmp_pars_are_invalid(cfg->cmp_par_smearing_variance, cfg->spill_smearing_variance,
656
2.42k
        cfg->cmp_mode, "smearing variance");
657
2.42k
    cfg_invalid += cmp_pars_are_invalid(cfg->cmp_par_smearing_pixels_error, cfg->spill_smearing_pixels_error,
658
2.42k
        cfg->cmp_mode, "smearing outlier pixls num");
659
2.42k
    break;
660
0
  default:
661
0
    debug_print("Error: The compression data type is not an auxiliary science compression data type.");
662
0
    cfg_invalid++;
663
6.86k
  }
664
6.86k
  return cfg_invalid;
665
6.86k
}
666
667
668
/**
669
 * @brief print the cmp_info structure
670
 *
671
 * @param info  pointer to a compressor information contains information of an
672
 *    executed RDCU compression
673
 */
674
675
void print_cmp_info(const struct cmp_info *info)
676
0
{
677
0
  if (!info) {
678
0
    debug_print("Pointer to the compressor information is NULL.");
679
0
    return;
680
0
  }
681
682
0
  debug_print("cmp_mode_used: %" PRIu32 "", info->cmp_mode_used);
683
0
  debug_print("spill_used: %" PRIu32 "", info->spill_used);
684
0
  debug_print("golomb_par_used: %" PRIu32 "", info->golomb_par_used);
685
0
  debug_print("samples_used: %" PRIu32 "", info->samples_used);
686
0
  debug_print("cmp_size: %" PRIu32 "", info->cmp_size);
687
0
  debug_print("ap1_cmp_size: %" PRIu32 "", info->ap1_cmp_size);
688
0
  debug_print("ap2_cmp_size: %" PRIu32 "", info->ap2_cmp_size);
689
0
  debug_print("rdcu_new_model_adr_used: 0x%06"PRIX32"", info->rdcu_new_model_adr_used);
690
0
  debug_print("rdcu_cmp_adr_used: 0x%06"PRIX32"", info->rdcu_cmp_adr_used);
691
0
  debug_print("model_value_used: %u", info->model_value_used);
692
0
  debug_print("round_used: %u", info->round_used);
693
0
  debug_print("cmp_err: %#X", info->cmp_err);
694
0
}