Coverage Report

Created: 2025-06-15 00:57

/src/cmp_tool/lib/decompress/decmp.c
Line
Count
Source (jump to first uncovered line)
1
/**
2
 * @file   decmp.c
3
 * @author Dominik Loidolt (dominik.loidolt@univie.ac.at)
4
 * @date   2020
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 software decompression library
17
 * @see Data Compression User Manual PLATO-UVIE-PL-UM-0001
18
 *
19
 * To decompress a compression entity (consisting of a compression entity header
20
 * and the compressed data) use the decompress_cmp_entiy() function.
21
 *
22
 * @warning not intended for use with the flight software
23
 */
24
25
26
#include <stdint.h>
27
#include <limits.h>
28
#include <string.h>
29
#include <assert.h>
30
31
#include "../common/byteorder.h"
32
#include "../common/compiler.h"
33
34
#include "read_bitstream.h"
35
#include "../common/cmp_data_types.h"
36
#include "../decmp.h"
37
#include "../common/cmp_debug.h"
38
#include "../common/cmp_support.h"
39
#include "../common/cmp_entity.h"
40
#include "../common/cmp_cal_up_model.h"
41
#include "../common/cmp_max_used_bits.h"
42
43
44
0
#define CORRUPTION_DETECTED (-1)
45
46
47
MAYBE_UNUSED static const char *please_check_str =
48
  "Please check that the compression parameters match those used to compress the data and that the compressed data are not corrupted.";
49
50
51
/**
52
 * @brief function pointer to a code word decoder function
53
 */
54
55
typedef uint32_t(*decoder_ptr)(struct bit_decoder *, uint32_t, uint32_t);
56
57
58
/**
59
 * @brief structure to hold all parameters to decode a value
60
 */
61
62
struct decoder_setup {
63
  int (*decode_method_f)(const struct decoder_setup *setup,
64
             uint32_t *decoded_value); /* pointer to the decoding function with escape mechanism */
65
  decoder_ptr decode_cw_f; /* pointer to the code word decoder function (Golomb/Rice/unary) */
66
  struct bit_decoder *dec; /* pointer to a bit_decoder context */
67
  uint32_t encoder_par1;   /* encoding parameter 1 */
68
  uint32_t encoder_par2;   /* encoding parameter 2 */
69
  uint32_t outlier_par;    /* outlier parameter */
70
  uint32_t lossy_par;      /* lossy compression parameter */
71
  uint32_t max_data_bits;  /* bit length of the decoded value */
72
};
73
74
75
enum decmp_type {ICU_DECOMRESSION, RDCU_DECOMPRESSION};
76
77
78
/**
79
 * @brief decode the next unary code word in the bitstream
80
 *
81
 * @param dec   a pointer to a bit_decoder context
82
 * @param m   this parameter is not used
83
 * @param log2_m  this parameter is not used
84
 * @note: Can be used to decode a code word with compression parameter m = 1 (log2_m = 0)
85
 *
86
 * @returns the decoded value
87
 */
88
89
static __inline uint32_t unary_decoder(struct bit_decoder *dec, uint32_t m UNUSED,
90
               uint32_t log2_m UNUSED)
91
0
{
92
0
  uint32_t const decoded_cw = bit_peek_leading_ones(dec); /* decode unary coding */
93
0
  uint32_t const cw_len = decoded_cw + 1; /* Number of 1's + following 0 */
94
95
0
  bit_consume_bits(dec, cw_len);
96
97
0
  return decoded_cw;
98
0
}
99
100
101
/**
102
 * @brief decode the next Rice code word in the bitstream
103
 *
104
 * @param dec   a pointer to a bit_decoder context
105
 * @param m   Golomb parameter, must be the same used for encoding
106
 * @param log2_m  Rice parameter, is ilog_2(m), must be larger than 0
107
 * @note the Golomb parameter (m) must be a power of 2
108
 * @warning the Rice parameter (log2_m) must be greater than 0! If you want to
109
 *  use a Rice parameter equal to 0, use the unary_decoder instead.
110
 *
111
 * @returns the decoded value
112
 */
113
114
static uint32_t rice_decoder(struct bit_decoder *dec, uint32_t m, uint32_t log2_m)
115
0
{
116
0
  uint32_t q;  /* quotient */
117
0
  uint32_t r;  /* remainder */
118
119
0
  assert(log2_m > 0 && log2_m < 32);
120
121
0
  q = unary_decoder(dec, m, log2_m); /* decode quotient unary code part */
122
0
  r = bit_read_bits32(dec, log2_m); /* get remainder */
123
124
0
  return (q << log2_m) + r; /* calculate decoded value (q*m+r) */
125
0
}
126
127
128
/**
129
 * @brief decode the next Golomb code word in the bitstream
130
 *
131
 * @param dec   a pointer to a bit_decoder context
132
 * @param m   Golomb parameter (has to be bigger than 0)
133
 * @param log2_m  is ilog_2(m) calculate outside function for better
134
 *      performance
135
 *
136
 * @returns the decoded value
137
 */
138
139
static uint32_t golomb_decoder(struct bit_decoder *dec, uint32_t m, uint32_t log2_m)
140
0
{
141
0
  uint32_t q;  /* quotient */
142
0
  uint32_t r1; /* remainder case 1 */
143
0
  uint32_t r2; /* remainder case 2 */
144
0
  uint32_t r;  /* remainder */
145
0
  uint32_t cutoff; /* cutoff between group 1 and 2 */
146
147
0
  assert(m > 0);
148
0
  assert(log2_m == ilog_2(m));
149
150
  /* decode quotient unary code part */
151
0
  q = unary_decoder(dec, m, log2_m);
152
153
  /* get the remainder code for both cases */
154
0
  r2 = (uint32_t)bit_peek_bits(dec, log2_m+1);
155
0
  r1 = r2 >> 1;
156
157
  /* calculate cutoff between case 1 and 2 */
158
0
  cutoff = (0x2U << log2_m) - m; /* = 2^(log2_m+1)-m */
159
160
0
  if (r1 < cutoff) { /* remainder case 1: remainder length=log2_m */
161
0
    bit_consume_bits(dec, log2_m);
162
0
    r = r1;
163
0
  } else { /* remainder case 2: remainder length = log2_m+1 */
164
0
    bit_consume_bits(dec, log2_m+1);
165
0
    r = r2 - cutoff;
166
0
  }
167
168
0
  return q*m + r;
169
0
}
170
171
172
/**
173
 * @brief select the decoder based on the used Golomb parameter
174
 *
175
 * @param golomb_par  Golomb parameter, has to be bigger than 0
176
 *
177
 * @note if the Golomb parameter is a power of 2 we can use the faster Rice decoder
178
 * @note if the Golomb parameter is 1 we can use the even faster unary decoder
179
 *
180
 * @returns function pointer to the select code word decoder function
181
 */
182
183
static decoder_ptr select_decoder(uint32_t golomb_par)
184
0
{
185
0
  assert(golomb_par > 0);
186
187
0
  if (golomb_par == 1)
188
0
    return &unary_decoder;
189
190
0
  if (is_a_pow_of_2(golomb_par))
191
0
    return &rice_decoder;
192
0
  else
193
0
    return &golomb_decoder;
194
0
}
195
196
197
/**
198
 * @brief decode the next code word with zero escape system mechanism from the bitstream
199
 *
200
 * @param setup   pointer to the decoder setup
201
 * @param decoded_value points to the location where the decoded value is stored
202
 *
203
 * @returns 0 on success; otherwise error
204
 */
205
206
static int decode_zero(const struct decoder_setup *setup, uint32_t *decoded_value)
207
0
{
208
  /* Decode the next value in the bitstream with the Golomb/Rice/unary decoder */
209
0
  *decoded_value = setup->decode_cw_f(setup->dec, setup->encoder_par1, setup->encoder_par2);
210
211
0
  if (*decoded_value != 0) { /* no escape symbol detected */
212
0
    if (*decoded_value >= setup->outlier_par) {
213
0
      debug_print("Error: Data consistency check failed. Non-outlier decoded value greater or equal than the outlier parameter. %s", please_check_str);
214
0
      return CORRUPTION_DETECTED;
215
0
    }
216
0
    *decoded_value -= 1;
217
0
  } else {
218
    /* the zero escape symbol mechanism was used; read unencoded value */
219
0
    bit_refill(setup->dec);
220
0
    *decoded_value = bit_read_bits32_sub_1(setup->dec, setup->max_data_bits);
221
222
0
    if (*decoded_value < setup->outlier_par - 1) { /* -1 because we subtract -1 from the *decoded_value */
223
0
      if (bit_refill(setup->dec) != BIT_OVERFLOW)
224
0
        debug_print("Error: Data consistency check failed. Outlier small than the outlier parameter. %s", please_check_str);
225
0
      return CORRUPTION_DETECTED;
226
0
    }
227
0
  }
228
0
  return bit_refill(setup->dec) == BIT_OVERFLOW;
229
0
}
230
231
232
/**
233
 * @brief decode the next code word with the multi escape mechanism from the bitstream
234
 *
235
 * @param setup   pointer to the decoder setup
236
 * @param decoded_value points to the location where the decoded value is stored
237
 *
238
 * @returns 0 on success; otherwise error
239
 */
240
241
static int decode_multi(const struct decoder_setup *setup, uint32_t *decoded_value)
242
0
{
243
  /* Decode the next value in the bitstream with the Golomb/Rice/unary decoder */
244
0
  *decoded_value = setup->decode_cw_f(setup->dec, setup->encoder_par1, setup->encoder_par2);
245
246
0
  if (*decoded_value >= setup->outlier_par) { /* escape symbol mechanism detected */
247
0
    uint32_t const unencoded_len = (*decoded_value - setup->outlier_par + 1) << 1;
248
249
0
    if (unencoded_len > ((setup->max_data_bits+1) & -2U)) { /* round up max_data_bits to the nearest multiple of 2 */
250
0
      debug_print("Error: Data consistency check failed. Multi escape symbol higher than expected. %s", please_check_str);
251
0
      return CORRUPTION_DETECTED;
252
0
    }
253
254
    /* read unencoded value */
255
0
    bit_refill(setup->dec);
256
0
    *decoded_value = bit_read_bits32(setup->dec, unencoded_len);
257
258
0
    if (*decoded_value >> (unencoded_len-2) == 0) { /* check if at least one bit of the two highest is set. */
259
0
      if (unencoded_len > 2) { /* Exception: if we code outlier_par as outlier, no set bit is expected */
260
0
        if (bit_refill(setup->dec) != BIT_OVERFLOW)
261
0
          debug_print("Error: Data consistency check failed. Unencoded data after multi escape symbol to small. %s", please_check_str);
262
0
        return CORRUPTION_DETECTED;
263
0
      }
264
0
    }
265
266
0
    *decoded_value += setup->outlier_par;
267
268
0
    if ((*decoded_value & BIT_MASK[setup->max_data_bits]) < setup->outlier_par) { /* check for overflow in addition */
269
0
      if (bit_refill(setup->dec) != BIT_OVERFLOW)
270
0
        debug_print("Error: Data consistency check failed. Outlier small than the outlier parameter. %s", please_check_str);
271
0
      return CORRUPTION_DETECTED;
272
0
    }
273
0
  }
274
0
  return bit_refill(setup->dec) == BIT_OVERFLOW;
275
0
}
276
277
278
/**
279
 * @brief remap an unsigned value back to a signed value
280
 * @note this is the reverse function of map_to_pos()
281
 *
282
 * @param value_to_unmap  unsigned value to remap
283
 *
284
 * @returns the signed remapped value
285
 */
286
287
static __inline uint32_t re_map_to_pos(uint32_t value_to_unmap)
288
0
{
289
0
  if (value_to_unmap & 0x1) { /* if uneven */
290
    /* uint64_t to prevent overflow if value_to_unmap == 0xFFFFFFFF */
291
0
    uint64_t const tmp64 = value_to_unmap;
292
293
0
    return (uint32_t)(-((tmp64 + 1) / 2));
294
0
  } else {
295
0
    return value_to_unmap / 2;
296
0
  }
297
0
}
298
299
300
/**
301
 * @brief decompress the next code word in the bitstream and decorrelate it with
302
 *  the model
303
 *
304
 * @param setup   pointer to the decoder setup
305
 * @param decoded_value points to the location where the decoded value is stored
306
 * @param model   model of the decoded_value (0 if not used)
307
 *
308
 * @returns 0 on success; otherwise error
309
 */
310
311
static int decode_value(const struct decoder_setup *setup, uint32_t *decoded_value,
312
      uint32_t model)
313
0
{
314
  /* decode the next value from the bitstream */
315
0
  int const err = setup->decode_method_f(setup, decoded_value);
316
317
  /* map the unsigned decode value back to a signed value */
318
0
  *decoded_value = re_map_to_pos(*decoded_value);
319
320
  /* decorrelate data the data with the model */
321
0
  *decoded_value += round_fwd(model, setup->lossy_par);
322
323
  /* we mask only the used bits in case there is an overflow when adding the model */
324
0
  *decoded_value &= BIT_MASK[setup->max_data_bits];
325
326
  /* inverse step of the lossy compression */
327
0
  *decoded_value = round_inv(*decoded_value, setup->lossy_par);
328
329
0
  return err;
330
0
}
331
332
333
/**
334
 * @brief configure a decoder setup structure to have a setup to decode a value
335
 *
336
 * @param setup   pointer to the decoder setup
337
 * @param dec   pointer to a bit_decoder context
338
 * @param cmp_mode  compression mode
339
 * @param cmp_par compression parameter
340
 * @param spillover spillover_par parameter
341
 * @param lossy_par lossy compression parameter
342
 * @param max_data_bits how many bits are needed to represent the highest possible value
343
 */
344
345
static void configure_decoder_setup(struct decoder_setup *setup, struct bit_decoder *dec,
346
            enum cmp_mode cmp_mode, uint32_t cmp_par,
347
            uint32_t spillover, uint32_t lossy_par,
348
            uint32_t max_data_bits)
349
0
{
350
0
  assert(setup != NULL);
351
0
  assert(dec != NULL);
352
0
  assert(cmp_par != 0);
353
0
  assert(max_data_bits > 0 && max_data_bits <= 32);
354
355
0
  if (multi_escape_mech_is_used(cmp_mode))
356
0
    setup->decode_method_f = &decode_multi;
357
0
  else if (zero_escape_mech_is_used(cmp_mode))
358
0
    setup->decode_method_f = &decode_zero;
359
0
  else {
360
0
    debug_print("Error: Compression mode not supported.");
361
0
    assert(0);
362
0
  }
363
0
  setup->decode_cw_f = select_decoder(cmp_par);
364
0
  setup->dec = dec;
365
0
  setup->encoder_par1 = cmp_par; /* encoding parameter 1 */
366
0
  setup->encoder_par2 = ilog_2(cmp_par); /* encoding parameter 2 */
367
0
  setup->outlier_par = spillover; /* outlier parameter */
368
0
  setup->lossy_par = lossy_par; /* lossy compression parameter */
369
0
  setup->max_data_bits = max_data_bits; /* how many bits are needed to represent the highest possible value */
370
0
}
371
372
373
/**
374
 * @brief return a pointer of the data of a collection
375
 *
376
 * @param col pointer to a collection header (can be NULL)
377
 *
378
 * @returns pointer to the collection data; NULL if col is NULL
379
 */
380
381
static void *get_collection_data(void *col)
382
0
{
383
0
  if (col)
384
0
    col = (uint8_t *)col + COLLECTION_HDR_SIZE;
385
0
  return col;
386
0
}
387
388
389
/**
390
 * @brief return a pointer of the data of a collection
391
 *
392
 * @param col pointer to a collection header (can be NULL)
393
 *
394
 * @returns pointer to the collection data; NULL if col is NULL
395
 */
396
397
static const void *get_collection_data_const(const void *col)
398
0
{
399
0
  if (col)
400
0
    col = (const uint8_t *)col + COLLECTION_HDR_SIZE;
401
0
  return col;
402
0
}
403
404
405
/**
406
 * @brief decompress imagette data
407
 *
408
 * @param cfg pointer to the compression configuration structure
409
 * @param dec a pointer to a bit_decoder context
410
 *
411
 * @returns 0 on success; otherwise error
412
 */
413
414
static int decompress_imagette(const struct cmp_cfg *cfg, struct bit_decoder *dec, enum decmp_type decmp_type)
415
0
{
416
0
  size_t i;
417
0
  int err;
418
0
  uint32_t decoded_value;
419
0
  uint32_t max_data_bits;
420
0
  struct decoder_setup setup;
421
0
  uint16_t *data_buf;
422
0
  const uint16_t *model_buf;
423
0
  uint16_t *up_model_buf;
424
0
  const uint16_t *next_model_p;
425
0
  uint16_t model;
426
427
0
  switch (decmp_type) {
428
0
  case RDCU_DECOMPRESSION: /* RDCU compresses the header like data */
429
0
    data_buf = cfg->dst;
430
0
    model_buf = cfg->model_buf;
431
0
    up_model_buf = cfg->updated_model_buf;
432
0
    break;
433
0
  case ICU_DECOMRESSION:
434
0
    data_buf = get_collection_data(cfg->dst);
435
0
    model_buf = get_collection_data_const(cfg->model_buf);
436
0
    up_model_buf = get_collection_data(cfg->updated_model_buf);
437
0
    break;
438
0
  }
439
440
0
  if (model_mode_is_used(cfg->cmp_mode)) {
441
0
    model =  get_unaligned(&model_buf[0]);
442
0
    next_model_p = &model_buf[1];
443
0
  } else {
444
0
    up_model_buf = NULL;
445
0
    memset(&model, 0, sizeof(model));
446
0
    next_model_p = data_buf;
447
0
  }
448
449
0
  switch (cfg->data_type) {
450
0
  case DATA_TYPE_IMAGETTE:
451
0
  case DATA_TYPE_IMAGETTE_ADAPTIVE:
452
0
    max_data_bits = MAX_USED_BITS.nc_imagette;
453
0
    break;
454
0
  case DATA_TYPE_SAT_IMAGETTE:
455
0
  case DATA_TYPE_SAT_IMAGETTE_ADAPTIVE:
456
0
    max_data_bits = MAX_USED_BITS.saturated_imagette;
457
0
    break;
458
0
  default:
459
0
  case DATA_TYPE_F_CAM_IMAGETTE:
460
0
  case DATA_TYPE_F_CAM_IMAGETTE_ADAPTIVE:
461
0
    max_data_bits = MAX_USED_BITS.fc_imagette;
462
0
    break;
463
0
  }
464
465
0
  configure_decoder_setup(&setup, dec, cfg->cmp_mode, cfg->cmp_par_imagette,
466
0
        cfg->spill_imagette, cfg->round, max_data_bits);
467
468
0
  for (i = 0; ; i++) {
469
0
    err = decode_value(&setup, &decoded_value, model);
470
0
    if (err)
471
0
      break;
472
473
0
    put_unaligned((uint16_t)decoded_value, &data_buf[i]);
474
475
0
    if (up_model_buf) {
476
0
      uint16_t up_model = cmp_up_model((uint16_t)decoded_value, model, cfg->model_value,
477
0
                   setup.lossy_par);
478
0
      put_unaligned(up_model, &up_model_buf[i]);
479
0
    }
480
481
0
    if (i >= cfg->samples-1)
482
0
      break;
483
484
0
    model = get_unaligned(&next_model_p[i]);
485
0
  }
486
0
  return err;
487
0
}
488
489
490
/**
491
 * @brief decompress short normal light flux (S_FX) data
492
 *
493
 * @param cfg pointer to the compression configuration structure
494
 * @param dec a pointer to a bit_decoder context
495
 *
496
 * @returns 0 on success; otherwise error
497
 */
498
499
static int decompress_s_fx(const struct cmp_cfg *cfg, struct bit_decoder *dec)
500
0
{
501
0
  size_t i;
502
0
  int err;
503
0
  uint32_t decoded_value;
504
0
  struct decoder_setup setup_exp_flags, setup_fx;
505
0
  struct s_fx *data_buf = get_collection_data(cfg->dst);
506
0
  const struct s_fx *model_buf = get_collection_data_const(cfg->model_buf);
507
0
  struct s_fx *up_model_buf;
508
0
  const struct s_fx *next_model_p;
509
0
  struct s_fx model;
510
511
0
  if (model_mode_is_used(cfg->cmp_mode)) {
512
0
    model = model_buf[0];
513
0
    next_model_p = &model_buf[1];
514
0
    up_model_buf = get_collection_data(cfg->updated_model_buf);
515
0
  } else {
516
0
    memset(&model, 0, sizeof(model));
517
0
    next_model_p = data_buf;
518
0
    up_model_buf = NULL;
519
0
  }
520
521
0
  configure_decoder_setup(&setup_exp_flags, dec, cfg->cmp_mode, cfg->cmp_par_exp_flags,
522
0
        cfg->spill_exp_flags, cfg->round, MAX_USED_BITS.s_exp_flags);
523
0
  configure_decoder_setup(&setup_fx, dec, cfg->cmp_mode, cfg->cmp_par_fx,
524
0
        cfg->spill_fx, cfg->round, MAX_USED_BITS.s_fx);
525
526
0
  for (i = 0; ; i++) {
527
0
    err = decode_value(&setup_exp_flags, &decoded_value, model.exp_flags);
528
0
    if (err)
529
0
      break;
530
0
    data_buf[i].exp_flags = (__typeof__(data_buf[i].exp_flags))decoded_value;
531
532
0
    err = decode_value(&setup_fx, &decoded_value, model.fx);
533
0
    if (err)
534
0
      break;
535
0
    data_buf[i].fx = decoded_value;
536
537
0
    if (up_model_buf) {
538
0
      up_model_buf[i].exp_flags = cmp_up_model(data_buf[i].exp_flags, model.exp_flags,
539
0
                 cfg->model_value, setup_exp_flags.lossy_par);
540
0
      up_model_buf[i].fx = cmp_up_model(data_buf[i].fx, model.fx,
541
0
                cfg->model_value, setup_fx.lossy_par);
542
0
    }
543
544
0
    if (i >= cfg->samples-1)
545
0
      break;
546
547
0
    model = next_model_p[i];
548
0
  }
549
0
  return err;
550
0
}
551
552
553
/**
554
 * @brief decompress S_FX_EFX data
555
 *
556
 * @param cfg pointer to the compression configuration structure
557
 * @param dec a pointer to a bit_decoder context
558
 *
559
 * @returns 0 on success; otherwise error
560
 */
561
562
static int decompress_s_fx_efx(const struct cmp_cfg *cfg, struct bit_decoder *dec)
563
0
{
564
0
  size_t i;
565
0
  int err;
566
0
  uint32_t decoded_value;
567
0
  struct decoder_setup setup_exp_flags, setup_fx, setup_efx;
568
0
  struct s_fx_efx *data_buf = get_collection_data(cfg->dst);
569
0
  const struct s_fx_efx *model_buf = get_collection_data_const(cfg->model_buf);
570
0
  struct s_fx_efx *up_model_buf;
571
0
  const struct s_fx_efx *next_model_p;
572
0
  struct s_fx_efx model;
573
574
0
  if (model_mode_is_used(cfg->cmp_mode)) {
575
0
    up_model_buf = get_collection_data(cfg->updated_model_buf);
576
0
    model = model_buf[0];
577
0
    next_model_p = &model_buf[1];
578
0
  } else {
579
0
    up_model_buf = NULL;
580
0
    memset(&model, 0, sizeof(model));
581
0
    next_model_p = data_buf;
582
0
  }
583
584
0
  configure_decoder_setup(&setup_exp_flags, dec, cfg->cmp_mode, cfg->cmp_par_exp_flags,
585
0
        cfg->spill_exp_flags, cfg->round, MAX_USED_BITS.s_exp_flags);
586
0
  configure_decoder_setup(&setup_fx, dec, cfg->cmp_mode, cfg->cmp_par_fx,
587
0
        cfg->spill_fx, cfg->round, MAX_USED_BITS.s_fx);
588
0
  configure_decoder_setup(&setup_efx, dec, cfg->cmp_mode, cfg->cmp_par_efx,
589
0
        cfg->spill_efx, cfg->round, MAX_USED_BITS.s_efx);
590
591
0
  for (i = 0; ; i++) {
592
0
    err = decode_value(&setup_exp_flags, &decoded_value, model.exp_flags);
593
0
    if (err)
594
0
      break;
595
0
    data_buf[i].exp_flags = (__typeof__(data_buf[i].exp_flags)) decoded_value;
596
597
0
    err = decode_value(&setup_fx, &decoded_value, model.fx);
598
0
    if (err)
599
0
      break;
600
0
    data_buf[i].fx = decoded_value;
601
602
0
    err = decode_value(&setup_efx, &decoded_value, model.efx);
603
0
    if (err)
604
0
      break;
605
0
    data_buf[i].efx = decoded_value;
606
607
0
    if (up_model_buf) {
608
0
      up_model_buf[i].exp_flags = cmp_up_model(data_buf[i].exp_flags, model.exp_flags,
609
0
                 cfg->model_value, setup_exp_flags.lossy_par);
610
0
      up_model_buf[i].fx = cmp_up_model(data_buf[i].fx, model.fx,
611
0
                cfg->model_value, setup_fx.lossy_par);
612
0
      up_model_buf[i].efx = cmp_up_model(data_buf[i].efx, model.efx,
613
0
                 cfg->model_value, setup_efx.lossy_par);
614
0
    }
615
616
0
    if (i >= cfg->samples-1)
617
0
      break;
618
619
0
    model = next_model_p[i];
620
0
  }
621
0
  return err;
622
0
}
623
624
625
/**
626
 * @brief decompress short S_FX_NCOB data
627
 *
628
 * @param cfg pointer to the compression configuration structure
629
 * @param dec a pointer to a bit_decoder context
630
 *
631
 * @returns 0 on success; otherwise error
632
 */
633
634
static int decompress_s_fx_ncob(const struct cmp_cfg *cfg, struct bit_decoder *dec)
635
0
{
636
0
  size_t i;
637
0
  int err;
638
0
  uint32_t decoded_value;
639
0
  struct decoder_setup setup_exp_flags, setup_fx, setup_ncob;
640
0
  struct s_fx_ncob *data_buf = get_collection_data(cfg->dst);
641
0
  const struct s_fx_ncob *model_buf = get_collection_data_const(cfg->model_buf);
642
0
  struct s_fx_ncob *up_model_buf;
643
0
  const struct s_fx_ncob *next_model_p;
644
0
  struct s_fx_ncob model;
645
646
0
  if (model_mode_is_used(cfg->cmp_mode)) {
647
0
    up_model_buf = get_collection_data(cfg->updated_model_buf);
648
0
    model = model_buf[0];
649
0
    next_model_p = &model_buf[1];
650
0
  } else {
651
0
    up_model_buf = NULL;
652
0
    memset(&model, 0, sizeof(model));
653
0
    next_model_p = data_buf;
654
0
  }
655
656
0
  configure_decoder_setup(&setup_exp_flags, dec, cfg->cmp_mode, cfg->cmp_par_exp_flags,
657
0
        cfg->spill_exp_flags, cfg->round, MAX_USED_BITS.s_exp_flags);
658
0
  configure_decoder_setup(&setup_fx, dec, cfg->cmp_mode, cfg->cmp_par_fx,
659
0
        cfg->spill_fx, cfg->round, MAX_USED_BITS.s_fx);
660
0
  configure_decoder_setup(&setup_ncob, dec, cfg->cmp_mode, cfg->cmp_par_ncob,
661
0
        cfg->spill_ncob, cfg->round, MAX_USED_BITS.s_ncob);
662
663
0
  for (i = 0; ; i++) {
664
0
    err = decode_value(&setup_exp_flags, &decoded_value, model.exp_flags);
665
0
    if (err)
666
0
      break;
667
0
    data_buf[i].exp_flags = (__typeof__(data_buf[i].exp_flags)) decoded_value;
668
669
0
    err = decode_value(&setup_fx, &decoded_value, model.fx);
670
0
    if (err)
671
0
      break;
672
0
    data_buf[i].fx = decoded_value;
673
674
0
    err = decode_value(&setup_ncob, &decoded_value, model.ncob_x);
675
0
    if (err)
676
0
      break;
677
0
    data_buf[i].ncob_x = decoded_value;
678
679
0
    err = decode_value(&setup_ncob, &decoded_value, model.ncob_y);
680
0
    if (err)
681
0
      break;
682
0
    data_buf[i].ncob_y = decoded_value;
683
684
0
    if (up_model_buf) {
685
0
      up_model_buf[i].exp_flags = cmp_up_model(data_buf[i].exp_flags, model.exp_flags,
686
0
                 cfg->model_value, setup_exp_flags.lossy_par);
687
0
      up_model_buf[i].fx = cmp_up_model(data_buf[i].fx, model.fx,
688
0
                cfg->model_value, setup_fx.lossy_par);
689
0
      up_model_buf[i].ncob_x = cmp_up_model(data_buf[i].ncob_x, model.ncob_x,
690
0
                    cfg->model_value, setup_ncob.lossy_par);
691
0
      up_model_buf[i].ncob_y = cmp_up_model(data_buf[i].ncob_y, model.ncob_y,
692
0
                    cfg->model_value, setup_ncob.lossy_par);
693
0
    }
694
695
0
    if (i >= cfg->samples-1)
696
0
      break;
697
698
0
    model = next_model_p[i];
699
0
  }
700
0
  return err;
701
0
}
702
703
704
/**
705
 * @brief decompress short S_FX_NCOB_ECOB data
706
 *
707
 * @param cfg pointer to the compression configuration structure
708
 * @param dec a pointer to a bit_decoder context
709
 *
710
 * @returns 0 on success; otherwise error
711
 */
712
713
static int decompress_s_fx_efx_ncob_ecob(const struct cmp_cfg *cfg, struct bit_decoder *dec)
714
0
{
715
0
  size_t i;
716
0
  int err;
717
0
  uint32_t decoded_value;
718
0
  struct decoder_setup setup_exp_flags, setup_fx, setup_ncob, setup_efx, setup_ecob;
719
0
  struct s_fx_efx_ncob_ecob *data_buf = get_collection_data(cfg->dst);
720
0
  const struct s_fx_efx_ncob_ecob *model_buf = get_collection_data_const(cfg->model_buf);
721
0
  struct s_fx_efx_ncob_ecob *up_model_buf;
722
0
  const struct s_fx_efx_ncob_ecob *next_model_p;
723
0
  struct s_fx_efx_ncob_ecob model;
724
725
0
  if (model_mode_is_used(cfg->cmp_mode)) {
726
0
    up_model_buf = get_collection_data(cfg->updated_model_buf);
727
0
    model = model_buf[0];
728
0
    next_model_p = &model_buf[1];
729
0
  } else {
730
0
    up_model_buf = NULL;
731
0
    memset(&model, 0, sizeof(model));
732
0
    next_model_p = data_buf;
733
0
  }
734
735
0
  configure_decoder_setup(&setup_exp_flags, dec, cfg->cmp_mode, cfg->cmp_par_exp_flags,
736
0
        cfg->spill_exp_flags, cfg->round, MAX_USED_BITS.s_exp_flags);
737
0
  configure_decoder_setup(&setup_fx, dec, cfg->cmp_mode, cfg->cmp_par_fx, cfg->spill_fx,
738
0
        cfg->round, MAX_USED_BITS.s_fx);
739
0
  configure_decoder_setup(&setup_ncob, dec, cfg->cmp_mode, cfg->cmp_par_ncob, cfg->spill_ncob,
740
0
        cfg->round, MAX_USED_BITS.s_ncob);
741
0
  configure_decoder_setup(&setup_efx, dec, cfg->cmp_mode, cfg->cmp_par_efx, cfg->spill_efx,
742
0
        cfg->round, MAX_USED_BITS.s_efx);
743
0
  configure_decoder_setup(&setup_ecob, dec, cfg->cmp_mode, cfg->cmp_par_ecob, cfg->spill_ecob,
744
0
        cfg->round, MAX_USED_BITS.s_ecob);
745
746
0
  for (i = 0; ; i++) {
747
0
    err = decode_value(&setup_exp_flags, &decoded_value, model.exp_flags);
748
0
    if (err)
749
0
      break;
750
0
    data_buf[i].exp_flags = (__typeof__(data_buf[i].exp_flags)) decoded_value;
751
752
0
    err = decode_value(&setup_fx, &decoded_value, model.fx);
753
0
    if (err)
754
0
      break;
755
0
    data_buf[i].fx = decoded_value;
756
757
0
    err = decode_value(&setup_ncob, &decoded_value, model.ncob_x);
758
0
    if (err)
759
0
      break;
760
0
    data_buf[i].ncob_x = decoded_value;
761
762
0
    err = decode_value(&setup_ncob, &decoded_value, model.ncob_y);
763
0
    if (err)
764
0
      break;
765
0
    data_buf[i].ncob_y = decoded_value;
766
767
0
    err = decode_value(&setup_efx, &decoded_value, model.efx);
768
0
    if (err)
769
0
      break;
770
0
    data_buf[i].efx = decoded_value;
771
772
0
    err = decode_value(&setup_ecob, &decoded_value, model.ecob_x);
773
0
    if (err)
774
0
      break;
775
0
    data_buf[i].ecob_x = decoded_value;
776
777
0
    err = decode_value(&setup_ecob, &decoded_value, model.ecob_y);
778
0
    if (err)
779
0
      break;
780
0
    data_buf[i].ecob_y = decoded_value;
781
782
0
    if (up_model_buf) {
783
0
      up_model_buf[i].exp_flags = cmp_up_model(data_buf[i].exp_flags, model.exp_flags,
784
0
                 cfg->model_value, setup_exp_flags.lossy_par);
785
0
      up_model_buf[i].fx = cmp_up_model(data_buf[i].fx, model.fx,
786
0
                cfg->model_value, setup_fx.lossy_par);
787
0
      up_model_buf[i].ncob_x = cmp_up_model(data_buf[i].ncob_x, model.ncob_x,
788
0
                    cfg->model_value, setup_ncob.lossy_par);
789
0
      up_model_buf[i].ncob_y = cmp_up_model(data_buf[i].ncob_y, model.ncob_y,
790
0
                    cfg->model_value, setup_ncob.lossy_par);
791
0
      up_model_buf[i].efx = cmp_up_model(data_buf[i].efx, model.efx,
792
0
                 cfg->model_value, setup_efx.lossy_par);
793
0
      up_model_buf[i].ecob_x = cmp_up_model(data_buf[i].ecob_x, model.ecob_x,
794
0
                    cfg->model_value, setup_ecob.lossy_par);
795
0
      up_model_buf[i].ecob_y = cmp_up_model(data_buf[i].ecob_y, model.ecob_y,
796
0
                    cfg->model_value, setup_ecob.lossy_par);
797
0
    }
798
799
0
    if (i >= cfg->samples-1)
800
0
      break;
801
802
0
    model = next_model_p[i];
803
0
  }
804
0
  return err;
805
0
}
806
807
808
/**
809
 * @brief decompress long normal light flux (L_FX) data
810
 *
811
 * @param cfg pointer to the compression configuration structure
812
 * @param dec a pointer to a bit_decoder context
813
 *
814
 * @returns 0 on success; otherwise error
815
 */
816
817
static int decompress_l_fx(const struct cmp_cfg *cfg, struct bit_decoder *dec)
818
0
{
819
0
  size_t i;
820
0
  int err;
821
0
  uint32_t decoded_value;
822
0
  struct decoder_setup setup_exp_flags, setup_fx, setup_fx_var;
823
0
  struct l_fx *data_buf = get_collection_data(cfg->dst);
824
0
  const struct l_fx *model_buf = get_collection_data_const(cfg->model_buf);
825
0
  struct l_fx *up_model_buf;
826
0
  const struct l_fx *next_model_p;
827
0
  struct l_fx model;
828
829
0
  if (model_mode_is_used(cfg->cmp_mode)) {
830
0
    up_model_buf = get_collection_data(cfg->updated_model_buf);
831
0
    model = model_buf[0];
832
0
    next_model_p = &model_buf[1];
833
0
  } else {
834
0
    up_model_buf = NULL;
835
0
    memset(&model, 0, sizeof(model));
836
0
    next_model_p = data_buf;
837
0
  }
838
839
0
  configure_decoder_setup(&setup_exp_flags, dec, cfg->cmp_mode, cfg->cmp_par_exp_flags, cfg->spill_exp_flags,
840
0
        cfg->round, MAX_USED_BITS.l_exp_flags);
841
0
  configure_decoder_setup(&setup_fx, dec, cfg->cmp_mode, cfg->cmp_par_fx, cfg->spill_fx,
842
0
        cfg->round, MAX_USED_BITS.l_fx);
843
0
  configure_decoder_setup(&setup_fx_var, dec, cfg->cmp_mode, cfg->cmp_par_fx_cob_variance, cfg->spill_fx_cob_variance,
844
0
        cfg->round, MAX_USED_BITS.l_fx_cob_variance);
845
846
0
  for (i = 0; ; i++) {
847
0
    err = decode_value(&setup_exp_flags, &decoded_value, model.exp_flags);
848
0
    if (err)
849
0
      break;
850
0
    data_buf[i].exp_flags = decoded_value;
851
852
0
    err = decode_value(&setup_fx, &decoded_value, model.fx);
853
0
    if (err)
854
0
      break;
855
0
    data_buf[i].fx = decoded_value;
856
857
0
    err = decode_value(&setup_fx_var, &decoded_value, model.fx_variance);
858
0
    if (err)
859
0
      break;
860
0
    data_buf[i].fx_variance = decoded_value;
861
862
0
    if (up_model_buf) {
863
0
      up_model_buf[i].exp_flags = cmp_up_model32(data_buf[i].exp_flags, model.exp_flags,
864
0
                   cfg->model_value, setup_exp_flags.lossy_par);
865
0
      up_model_buf[i].fx = cmp_up_model(data_buf[i].fx, model.fx,
866
0
                cfg->model_value, setup_fx.lossy_par);
867
0
      up_model_buf[i].fx_variance = cmp_up_model(data_buf[i].fx_variance, model.fx_variance,
868
0
                   cfg->model_value, setup_fx_var.lossy_par);
869
0
    }
870
871
0
    if (i >= cfg->samples-1)
872
0
      break;
873
874
0
    model = next_model_p[i];
875
0
  }
876
0
  return err;
877
0
}
878
879
880
/**
881
 * @brief decompress L_FX_EFX data
882
 *
883
 * @param cfg pointer to the compression configuration structure
884
 * @param dec a pointer to a bit_decoder context
885
 *
886
 * @returns 0 on success; otherwise error
887
 */
888
889
static int decompress_l_fx_efx(const struct cmp_cfg *cfg, struct bit_decoder *dec)
890
0
{
891
0
  size_t i;
892
0
  int err;
893
0
  uint32_t decoded_value;
894
0
  struct decoder_setup setup_exp_flags, setup_fx, setup_efx, setup_fx_var;
895
0
  struct l_fx_efx *data_buf = get_collection_data(cfg->dst);
896
0
  const struct l_fx_efx *model_buf = get_collection_data_const(cfg->model_buf);
897
0
  struct l_fx_efx *up_model_buf;
898
0
  const struct l_fx_efx *next_model_p;
899
0
  struct l_fx_efx model;
900
901
0
  if (model_mode_is_used(cfg->cmp_mode)) {
902
0
    up_model_buf = get_collection_data(cfg->updated_model_buf);
903
0
    model = model_buf[0];
904
0
    next_model_p = &model_buf[1];
905
0
  } else {
906
0
    up_model_buf = NULL;
907
0
    memset(&model, 0, sizeof(model));
908
0
    next_model_p = data_buf;
909
0
  }
910
911
0
  configure_decoder_setup(&setup_exp_flags, dec, cfg->cmp_mode, cfg->cmp_par_exp_flags, cfg->spill_exp_flags,
912
0
        cfg->round, MAX_USED_BITS.l_exp_flags);
913
0
  configure_decoder_setup(&setup_fx, dec, cfg->cmp_mode, cfg->cmp_par_fx, cfg->spill_fx,
914
0
        cfg->round, MAX_USED_BITS.l_fx);
915
0
  configure_decoder_setup(&setup_efx, dec, cfg->cmp_mode, cfg->cmp_par_efx, cfg->spill_efx,
916
0
        cfg->round, MAX_USED_BITS.l_efx);
917
0
  configure_decoder_setup(&setup_fx_var, dec, cfg->cmp_mode, cfg->cmp_par_fx_cob_variance, cfg->spill_fx_cob_variance,
918
0
        cfg->round, MAX_USED_BITS.l_fx_cob_variance);
919
920
0
  for (i = 0; ; i++) {
921
0
    err = decode_value(&setup_exp_flags, &decoded_value, model.exp_flags);
922
0
    if (err)
923
0
      break;
924
0
    data_buf[i].exp_flags = decoded_value;
925
926
0
    err = decode_value(&setup_fx, &decoded_value, model.fx);
927
0
    if (err)
928
0
      break;
929
0
    data_buf[i].fx = decoded_value;
930
931
0
    err = decode_value(&setup_efx, &decoded_value, model.efx);
932
0
    if (err)
933
0
      break;
934
0
    data_buf[i].efx = decoded_value;
935
936
0
    err = decode_value(&setup_fx_var, &decoded_value, model.fx_variance);
937
0
    if (err)
938
0
      break;
939
0
    data_buf[i].fx_variance = decoded_value;
940
941
0
    if (up_model_buf) {
942
0
      up_model_buf[i].exp_flags = cmp_up_model32(data_buf[i].exp_flags, model.exp_flags,
943
0
                   cfg->model_value, setup_exp_flags.lossy_par);
944
0
      up_model_buf[i].fx = cmp_up_model(data_buf[i].fx, model.fx,
945
0
                cfg->model_value, setup_fx.lossy_par);
946
0
      up_model_buf[i].efx = cmp_up_model(data_buf[i].efx, model.efx,
947
0
                 cfg->model_value, setup_efx.lossy_par);
948
0
      up_model_buf[i].fx_variance = cmp_up_model(data_buf[i].fx_variance, model.fx_variance,
949
0
                   cfg->model_value, setup_fx_var.lossy_par);
950
0
    }
951
952
0
    if (i >= cfg->samples-1)
953
0
      break;
954
955
0
    model = next_model_p[i];
956
0
  }
957
0
  return err;
958
0
}
959
960
961
/**
962
 * @brief decompress L_FX_NCOB data
963
 *
964
 * @param cfg pointer to the compression configuration structure
965
 * @param dec a pointer to a bit_decoder context
966
 *
967
 * @returns 0 on success; otherwise error
968
 */
969
970
static int decompress_l_fx_ncob(const struct cmp_cfg *cfg, struct bit_decoder *dec)
971
0
{
972
0
  size_t i;
973
0
  int err;
974
0
  uint32_t decoded_value;
975
0
  struct decoder_setup setup_exp_flags, setup_fx, setup_ncob,
976
0
           setup_fx_var, setup_cob_var;
977
0
  struct l_fx_ncob *data_buf = get_collection_data(cfg->dst);
978
0
  const struct l_fx_ncob *model_buf = get_collection_data_const(cfg->model_buf);
979
0
  struct l_fx_ncob *up_model_buf;
980
0
  const struct l_fx_ncob *next_model_p;
981
0
  struct l_fx_ncob model;
982
983
0
  if (model_mode_is_used(cfg->cmp_mode)) {
984
0
    up_model_buf = get_collection_data(cfg->updated_model_buf);
985
0
    model = model_buf[0];
986
0
    next_model_p = &model_buf[1];
987
0
  } else {
988
0
    up_model_buf = NULL;
989
0
    memset(&model, 0, sizeof(model));
990
0
    next_model_p = data_buf;
991
0
  }
992
993
0
  configure_decoder_setup(&setup_exp_flags, dec, cfg->cmp_mode, cfg->cmp_par_exp_flags, cfg->spill_exp_flags,
994
0
        cfg->round, MAX_USED_BITS.l_exp_flags);
995
0
  configure_decoder_setup(&setup_fx, dec, cfg->cmp_mode, cfg->cmp_par_fx, cfg->spill_fx,
996
0
        cfg->round, MAX_USED_BITS.l_fx);
997
0
  configure_decoder_setup(&setup_ncob, dec, cfg->cmp_mode, cfg->cmp_par_ncob, cfg->spill_ncob,
998
0
        cfg->round, MAX_USED_BITS.l_ncob);
999
0
  configure_decoder_setup(&setup_fx_var, dec, cfg->cmp_mode, cfg->cmp_par_fx_cob_variance, cfg->spill_fx_cob_variance,
1000
0
        cfg->round, MAX_USED_BITS.l_fx_cob_variance);
1001
0
  configure_decoder_setup(&setup_cob_var, dec, cfg->cmp_mode, cfg->cmp_par_fx_cob_variance, cfg->spill_fx_cob_variance,
1002
0
        cfg->round, MAX_USED_BITS.l_fx_cob_variance);
1003
1004
0
  for (i = 0; ; i++) {
1005
0
    err = decode_value(&setup_exp_flags, &decoded_value, model.exp_flags);
1006
0
    if (err)
1007
0
      break;
1008
0
    data_buf[i].exp_flags = decoded_value;
1009
1010
0
    err = decode_value(&setup_fx, &decoded_value, model.fx);
1011
0
    if (err)
1012
0
      break;
1013
0
    data_buf[i].fx = decoded_value;
1014
1015
0
    err = decode_value(&setup_ncob, &decoded_value, model.ncob_x);
1016
0
    if (err)
1017
0
      break;
1018
0
    data_buf[i].ncob_x = decoded_value;
1019
1020
0
    err = decode_value(&setup_ncob, &decoded_value, model.ncob_y);
1021
0
    if (err)
1022
0
      break;
1023
0
    data_buf[i].ncob_y = decoded_value;
1024
1025
0
    err = decode_value(&setup_fx_var, &decoded_value, model.fx_variance);
1026
0
    if (err)
1027
0
      break;
1028
0
    data_buf[i].fx_variance = decoded_value;
1029
1030
0
    err = decode_value(&setup_cob_var, &decoded_value, model.cob_x_variance);
1031
0
    if (err)
1032
0
      break;
1033
0
    data_buf[i].cob_x_variance = decoded_value;
1034
1035
0
    err = decode_value(&setup_cob_var, &decoded_value, model.cob_y_variance);
1036
0
    if (err)
1037
0
      break;
1038
0
    data_buf[i].cob_y_variance = decoded_value;
1039
1040
0
    if (up_model_buf) {
1041
0
      up_model_buf[i].exp_flags = cmp_up_model32(data_buf[i].exp_flags, model.exp_flags,
1042
0
        cfg->model_value, setup_exp_flags.lossy_par);
1043
0
      up_model_buf[i].fx = cmp_up_model(data_buf[i].fx, model.fx,
1044
0
        cfg->model_value, setup_fx.lossy_par);
1045
0
      up_model_buf[i].ncob_x = cmp_up_model(data_buf[i].ncob_x, model.ncob_x,
1046
0
        cfg->model_value, setup_ncob.lossy_par);
1047
0
      up_model_buf[i].ncob_y = cmp_up_model(data_buf[i].ncob_y, model.ncob_y,
1048
0
        cfg->model_value, setup_ncob.lossy_par);
1049
0
      up_model_buf[i].fx_variance = cmp_up_model(data_buf[i].fx_variance, model.fx_variance,
1050
0
        cfg->model_value, setup_fx_var.lossy_par);
1051
0
      up_model_buf[i].cob_x_variance = cmp_up_model(data_buf[i].cob_x_variance, model.cob_x_variance,
1052
0
        cfg->model_value, setup_cob_var.lossy_par);
1053
0
      up_model_buf[i].cob_y_variance = cmp_up_model(data_buf[i].cob_y_variance, model.cob_y_variance,
1054
0
        cfg->model_value, setup_cob_var.lossy_par);
1055
0
    }
1056
1057
0
    if (i >= cfg->samples-1)
1058
0
      break;
1059
1060
0
    model = next_model_p[i];
1061
0
  }
1062
0
  return err;
1063
0
}
1064
1065
1066
/**
1067
 * @brief decompress L_FX_EFX_NCOB_ECOB data
1068
 *
1069
 * @param cfg pointer to the compression configuration structure
1070
 * @param dec a pointer to a bit_decoder context
1071
 *
1072
 * @returns 0 on success; otherwise error
1073
 */
1074
1075
static int decompress_l_fx_efx_ncob_ecob(const struct cmp_cfg *cfg, struct bit_decoder *dec)
1076
0
{
1077
0
  size_t i;
1078
0
  int err;
1079
0
  uint32_t decoded_value;
1080
0
  struct decoder_setup setup_exp_flags, setup_fx, setup_ncob, setup_efx,
1081
0
           setup_ecob, setup_fx_var, setup_cob_var;
1082
0
  struct l_fx_efx_ncob_ecob *data_buf = get_collection_data(cfg->dst);
1083
0
  const struct l_fx_efx_ncob_ecob *model_buf = get_collection_data_const(cfg->model_buf);
1084
0
  struct l_fx_efx_ncob_ecob *up_model_buf;
1085
0
  const struct l_fx_efx_ncob_ecob *next_model_p;
1086
0
  struct l_fx_efx_ncob_ecob model;
1087
1088
0
  if (model_mode_is_used(cfg->cmp_mode)) {
1089
0
    up_model_buf = get_collection_data(cfg->updated_model_buf);
1090
0
    model = model_buf[0];
1091
0
    next_model_p = &model_buf[1];
1092
0
  } else {
1093
0
    up_model_buf = NULL;
1094
0
    memset(&model, 0, sizeof(model));
1095
0
    next_model_p = data_buf;
1096
0
  }
1097
1098
0
  configure_decoder_setup(&setup_exp_flags, dec, cfg->cmp_mode, cfg->cmp_par_exp_flags, cfg->spill_exp_flags,
1099
0
        cfg->round, MAX_USED_BITS.l_exp_flags);
1100
0
  configure_decoder_setup(&setup_fx, dec, cfg->cmp_mode, cfg->cmp_par_fx, cfg->spill_fx,
1101
0
        cfg->round, MAX_USED_BITS.l_fx);
1102
0
  configure_decoder_setup(&setup_ncob, dec, cfg->cmp_mode, cfg->cmp_par_ncob, cfg->spill_ncob,
1103
0
        cfg->round, MAX_USED_BITS.l_ncob);
1104
0
  configure_decoder_setup(&setup_efx, dec, cfg->cmp_mode, cfg->cmp_par_efx, cfg->spill_efx,
1105
0
        cfg->round, MAX_USED_BITS.l_efx);
1106
0
  configure_decoder_setup(&setup_ecob, dec, cfg->cmp_mode, cfg->cmp_par_ecob, cfg->spill_ecob,
1107
0
        cfg->round, MAX_USED_BITS.l_ecob);
1108
0
  configure_decoder_setup(&setup_fx_var, dec, cfg->cmp_mode, cfg->cmp_par_fx_cob_variance, cfg->spill_fx_cob_variance,
1109
0
        cfg->round, MAX_USED_BITS.l_fx_cob_variance);
1110
0
  configure_decoder_setup(&setup_cob_var, dec, cfg->cmp_mode, cfg->cmp_par_fx_cob_variance, cfg->spill_fx_cob_variance,
1111
0
        cfg->round, MAX_USED_BITS.l_fx_cob_variance);
1112
1113
0
  for (i = 0; ; i++) {
1114
0
    err = decode_value(&setup_exp_flags, &decoded_value, model.exp_flags);
1115
0
    if (err)
1116
0
      break;
1117
0
    data_buf[i].exp_flags = decoded_value;
1118
1119
0
    err = decode_value(&setup_fx, &decoded_value, model.fx);
1120
0
    if (err)
1121
0
      break;
1122
0
    data_buf[i].fx = decoded_value;
1123
1124
0
    err = decode_value(&setup_ncob, &decoded_value, model.ncob_x);
1125
0
    if (err)
1126
0
      break;
1127
0
    data_buf[i].ncob_x = decoded_value;
1128
1129
0
    err = decode_value(&setup_ncob, &decoded_value, model.ncob_y);
1130
0
    if (err)
1131
0
      break;
1132
0
    data_buf[i].ncob_y = decoded_value;
1133
1134
0
    err = decode_value(&setup_efx, &decoded_value, model.efx);
1135
0
    if (err)
1136
0
      break;
1137
0
    data_buf[i].efx = decoded_value;
1138
1139
0
    err = decode_value(&setup_ecob, &decoded_value, model.ecob_x);
1140
0
    if (err)
1141
0
      break;
1142
0
    data_buf[i].ecob_x = decoded_value;
1143
1144
0
    err = decode_value(&setup_ecob, &decoded_value, model.ecob_y);
1145
0
    if (err)
1146
0
      break;
1147
0
    data_buf[i].ecob_y = decoded_value;
1148
1149
0
    err = decode_value(&setup_fx_var, &decoded_value, model.fx_variance);
1150
0
    if (err)
1151
0
      break;
1152
0
    data_buf[i].fx_variance = decoded_value;
1153
1154
0
    err = decode_value(&setup_cob_var, &decoded_value, model.cob_x_variance);
1155
0
    if (err)
1156
0
      break;
1157
0
    data_buf[i].cob_x_variance = decoded_value;
1158
1159
0
    err = decode_value(&setup_cob_var, &decoded_value, model.cob_y_variance);
1160
0
    if (err)
1161
0
      break;
1162
0
    data_buf[i].cob_y_variance = decoded_value;
1163
1164
0
    if (up_model_buf) {
1165
0
      up_model_buf[i].exp_flags = cmp_up_model32(data_buf[i].exp_flags, model.exp_flags,
1166
0
        cfg->model_value, setup_exp_flags.lossy_par);
1167
0
      up_model_buf[i].fx = cmp_up_model(data_buf[i].fx, model.fx,
1168
0
        cfg->model_value, setup_fx.lossy_par);
1169
0
      up_model_buf[i].ncob_x = cmp_up_model(data_buf[i].ncob_x, model.ncob_x,
1170
0
        cfg->model_value, setup_ncob.lossy_par);
1171
0
      up_model_buf[i].ncob_y = cmp_up_model(data_buf[i].ncob_y, model.ncob_y,
1172
0
        cfg->model_value, setup_ncob.lossy_par);
1173
0
      up_model_buf[i].efx = cmp_up_model(data_buf[i].efx, model.efx,
1174
0
        cfg->model_value, setup_efx.lossy_par);
1175
0
      up_model_buf[i].ecob_x = cmp_up_model(data_buf[i].ecob_x, model.ecob_x,
1176
0
        cfg->model_value, setup_ecob.lossy_par);
1177
0
      up_model_buf[i].ecob_y = cmp_up_model(data_buf[i].ecob_y, model.ecob_y,
1178
0
        cfg->model_value, setup_ecob.lossy_par);
1179
0
      up_model_buf[i].fx_variance = cmp_up_model(data_buf[i].fx_variance, model.fx_variance,
1180
0
        cfg->model_value, setup_fx_var.lossy_par);
1181
0
      up_model_buf[i].cob_x_variance = cmp_up_model(data_buf[i].cob_x_variance, model.cob_x_variance,
1182
0
        cfg->model_value, setup_cob_var.lossy_par);
1183
0
      up_model_buf[i].cob_y_variance = cmp_up_model(data_buf[i].cob_y_variance, model.cob_y_variance,
1184
0
        cfg->model_value, setup_cob_var.lossy_par);
1185
0
    }
1186
1187
0
    if (i >= cfg->samples-1)
1188
0
      break;
1189
1190
0
    model = next_model_p[i];
1191
0
  }
1192
0
  return err;
1193
0
}
1194
1195
1196
/**
1197
 * @brief decompress N-CAM and F-CAM offset data
1198
 *
1199
 * @param cfg pointer to the compression configuration structure
1200
 * @param dec a pointer to a bit_decoder context
1201
 *
1202
 * @returns 0 on success; otherwise error
1203
 */
1204
1205
static int decompress_offset(const struct cmp_cfg *cfg, struct bit_decoder *dec)
1206
0
{
1207
0
  size_t i;
1208
0
  int err;
1209
0
  uint32_t decoded_value;
1210
0
  struct decoder_setup setup_mean, setup_var;
1211
0
  struct offset *data_buf = get_collection_data(cfg->dst);
1212
0
  const struct offset *model_buf = get_collection_data_const(cfg->model_buf);
1213
0
  struct offset *up_model_buf;
1214
0
  const struct offset *next_model_p;
1215
0
  struct offset model;
1216
1217
0
  if (model_mode_is_used(cfg->cmp_mode)) {
1218
0
    up_model_buf = get_collection_data(cfg->updated_model_buf);
1219
0
    model = model_buf[0];
1220
0
    next_model_p = &model_buf[1];
1221
0
  } else {
1222
0
    up_model_buf = NULL;
1223
0
    memset(&model, 0, sizeof(model));
1224
0
    next_model_p = data_buf;
1225
0
  }
1226
1227
0
  {
1228
0
    unsigned int mean_bits_used, variance_bits_used;
1229
1230
0
    switch (cfg->data_type) {
1231
0
    case DATA_TYPE_F_CAM_OFFSET:
1232
0
      mean_bits_used = MAX_USED_BITS.fc_offset_mean;
1233
0
      variance_bits_used = MAX_USED_BITS.fc_offset_variance;
1234
0
      break;
1235
0
    case DATA_TYPE_OFFSET:
1236
0
    default:
1237
0
      mean_bits_used = MAX_USED_BITS.nc_offset_mean;
1238
0
      variance_bits_used = MAX_USED_BITS.nc_offset_variance;
1239
0
      break;
1240
0
    }
1241
0
    configure_decoder_setup(&setup_mean, dec, cfg->cmp_mode, cfg->cmp_par_offset_mean, cfg->spill_offset_mean,
1242
0
          cfg->round, mean_bits_used);
1243
1244
0
    configure_decoder_setup(&setup_var, dec, cfg->cmp_mode, cfg->cmp_par_offset_variance, cfg->spill_offset_variance,
1245
0
          cfg->round, variance_bits_used);
1246
1247
0
  }
1248
1249
0
  for (i = 0; ; i++) {
1250
0
    err = decode_value(&setup_mean, &decoded_value, model.mean);
1251
0
    if (err)
1252
0
      break;
1253
0
    data_buf[i].mean = decoded_value;
1254
1255
0
    err = decode_value(&setup_var, &decoded_value, model.variance);
1256
0
    if (err)
1257
0
      break;
1258
0
    data_buf[i].variance = decoded_value;
1259
1260
0
    if (up_model_buf) {
1261
0
      up_model_buf[i].mean = cmp_up_model(data_buf[i].mean,
1262
0
        model.mean, cfg->model_value, setup_mean.lossy_par);
1263
0
      up_model_buf[i].variance = cmp_up_model(data_buf[i].variance,
1264
0
        model.variance, cfg->model_value, setup_var.lossy_par);
1265
0
    }
1266
1267
0
    if (i >= cfg->samples-1)
1268
0
      break;
1269
1270
0
    model = next_model_p[i];
1271
0
  }
1272
0
  return err;
1273
0
}
1274
1275
1276
/**
1277
 * @brief decompress N-CAM background data
1278
 *
1279
 * @param cfg pointer to the compression configuration structure
1280
 * @param dec a pointer to a bit_decoder context
1281
 *
1282
 * @returns 0 on success; otherwise error
1283
 */
1284
1285
static int decompress_background(const struct cmp_cfg *cfg, struct bit_decoder *dec)
1286
0
{
1287
0
  size_t i;
1288
0
  int err;
1289
0
  uint32_t decoded_value;
1290
0
  struct decoder_setup setup_mean, setup_var, setup_pix;
1291
0
  struct background *data_buf = get_collection_data(cfg->dst);
1292
0
  const struct background *model_buf = get_collection_data_const(cfg->model_buf);
1293
0
  struct background *up_model_buf;
1294
0
  const struct background *next_model_p;
1295
0
  struct background model;
1296
1297
0
  if (model_mode_is_used(cfg->cmp_mode)) {
1298
0
    up_model_buf = get_collection_data(cfg->updated_model_buf);
1299
0
    model = model_buf[0];
1300
0
    next_model_p = &model_buf[1];
1301
0
  } else {
1302
0
    up_model_buf = NULL;
1303
0
    memset(&model, 0, sizeof(model));
1304
0
    next_model_p = data_buf;
1305
0
  }
1306
0
  {
1307
0
    unsigned int mean_used_bits, variance_used_bits, outlier_pixels_used_bits;
1308
1309
0
    switch (cfg->data_type) {
1310
0
    case DATA_TYPE_F_CAM_BACKGROUND:
1311
0
      mean_used_bits = MAX_USED_BITS.fc_background_mean;
1312
0
      variance_used_bits = MAX_USED_BITS.fc_background_variance;
1313
0
      outlier_pixels_used_bits = MAX_USED_BITS.fc_background_outlier_pixels;
1314
0
      break;
1315
0
    case DATA_TYPE_BACKGROUND:
1316
0
    default:
1317
0
      mean_used_bits = MAX_USED_BITS.nc_background_mean;
1318
0
      variance_used_bits = MAX_USED_BITS.nc_background_variance;
1319
0
      outlier_pixels_used_bits = MAX_USED_BITS.nc_background_outlier_pixels;
1320
0
      break;
1321
0
    }
1322
1323
0
    configure_decoder_setup(&setup_mean, dec, cfg->cmp_mode, cfg->cmp_par_background_mean, cfg->spill_background_mean,
1324
0
          cfg->round, mean_used_bits);
1325
1326
0
    configure_decoder_setup(&setup_var, dec, cfg->cmp_mode, cfg->cmp_par_background_variance, cfg->spill_background_variance,
1327
0
          cfg->round, variance_used_bits);
1328
1329
0
    configure_decoder_setup(&setup_pix, dec, cfg->cmp_mode, cfg->cmp_par_background_pixels_error, cfg->spill_background_pixels_error,
1330
0
          cfg->round, outlier_pixels_used_bits);
1331
1332
0
  }
1333
1334
0
  for (i = 0; ; i++) {
1335
0
    err = decode_value(&setup_mean, &decoded_value, model.mean);
1336
0
    if (err)
1337
0
      break;
1338
0
    data_buf[i].mean = decoded_value;
1339
1340
0
    err = decode_value(&setup_var, &decoded_value, model.variance);
1341
0
    if (err)
1342
0
      break;
1343
0
    data_buf[i].variance = decoded_value;
1344
1345
0
    err = decode_value(&setup_pix, &decoded_value, model.outlier_pixels);
1346
0
    if (err)
1347
0
      break;
1348
0
    data_buf[i].outlier_pixels = (__typeof__(data_buf[i].outlier_pixels))decoded_value;
1349
1350
0
    if (up_model_buf) {
1351
0
      up_model_buf[i].mean = cmp_up_model(data_buf[i].mean,
1352
0
        model.mean, cfg->model_value, setup_mean.lossy_par);
1353
0
      up_model_buf[i].variance = cmp_up_model(data_buf[i].variance,
1354
0
        model.variance, cfg->model_value, setup_var.lossy_par);
1355
0
      up_model_buf[i].outlier_pixels = cmp_up_model(data_buf[i].outlier_pixels,
1356
0
        model.outlier_pixels, cfg->model_value, setup_pix.lossy_par);
1357
0
    }
1358
1359
0
    if (i >= cfg->samples-1)
1360
0
      break;
1361
1362
0
    model = next_model_p[i];
1363
0
  }
1364
0
  return err;
1365
0
}
1366
1367
1368
/**
1369
 * @brief decompress N-CAM smearing data
1370
 *
1371
 * @param cfg pointer to the compression configuration structure
1372
 * @param dec a pointer to a bit_decoder context
1373
 *
1374
 * @returns 0 on success; otherwise error
1375
 */
1376
1377
static int decompress_smearing(const struct cmp_cfg *cfg, struct bit_decoder *dec)
1378
0
{
1379
0
  size_t i;
1380
0
  int err;
1381
0
  uint32_t decoded_value;
1382
0
  struct decoder_setup setup_mean, setup_var, setup_pix;
1383
0
  struct smearing *data_buf = get_collection_data(cfg->dst);
1384
0
  const struct smearing *model_buf = get_collection_data_const(cfg->model_buf);
1385
0
  struct smearing *up_model_buf;
1386
0
  const struct smearing *next_model_p;
1387
0
  struct smearing model;
1388
1389
0
  if (model_mode_is_used(cfg->cmp_mode)) {
1390
0
    up_model_buf = get_collection_data(cfg->updated_model_buf);
1391
0
    model = model_buf[0];
1392
0
    next_model_p = &model_buf[1];
1393
0
  } else {
1394
0
    up_model_buf = NULL;
1395
0
    memset(&model, 0, sizeof(model));
1396
0
    next_model_p = data_buf;
1397
0
  }
1398
1399
0
  configure_decoder_setup(&setup_mean, dec, cfg->cmp_mode, cfg->cmp_par_smearing_mean, cfg->spill_smearing_mean,
1400
0
        cfg->round, MAX_USED_BITS.smearing_mean);
1401
0
  configure_decoder_setup(&setup_var, dec, cfg->cmp_mode, cfg->cmp_par_smearing_variance, cfg->spill_smearing_variance,
1402
0
        cfg->round, MAX_USED_BITS.smearing_variance_mean);
1403
0
  configure_decoder_setup(&setup_pix, dec, cfg->cmp_mode, cfg->cmp_par_smearing_pixels_error, cfg->spill_smearing_pixels_error,
1404
0
        cfg->round, MAX_USED_BITS.smearing_outlier_pixels);
1405
1406
0
  for (i = 0; ; i++) {
1407
0
    err = decode_value(&setup_mean, &decoded_value, model.mean);
1408
0
    if (err)
1409
0
      break;
1410
0
    data_buf[i].mean = decoded_value;
1411
1412
0
    err = decode_value(&setup_var, &decoded_value, model.variance_mean);
1413
0
    if (err)
1414
0
      break;
1415
0
    data_buf[i].variance_mean = (__typeof__(data_buf[i].variance_mean))decoded_value;
1416
1417
0
    err = decode_value(&setup_pix, &decoded_value, model.outlier_pixels);
1418
0
    if (err)
1419
0
      break;
1420
0
    data_buf[i].outlier_pixels = (__typeof__(data_buf[i].outlier_pixels))decoded_value;
1421
1422
0
    if (up_model_buf) {
1423
0
      up_model_buf[i].mean = cmp_up_model(data_buf[i].mean,
1424
0
        model.mean, cfg->model_value, setup_mean.lossy_par);
1425
0
      up_model_buf[i].variance_mean = cmp_up_model(data_buf[i].variance_mean,
1426
0
        model.variance_mean, cfg->model_value, setup_var.lossy_par);
1427
0
      up_model_buf[i].outlier_pixels = cmp_up_model(data_buf[i].outlier_pixels,
1428
0
        model.outlier_pixels, cfg->model_value, setup_pix.lossy_par);
1429
0
    }
1430
1431
0
    if (i >= cfg->samples-1)
1432
0
      break;
1433
1434
0
    model = next_model_p[i];
1435
0
  }
1436
0
  return err;
1437
0
}
1438
1439
1440
/**
1441
 * @brief Decompresses the collection header.
1442
 *
1443
 * @param cfg pointer to the compression configuration structure
1444
 *
1445
 * @note the collection header is not truly compressed; it is simply copied into
1446
 *  the compressed data.
1447
 *
1448
 * @return The size of the decompressed collection header on success,
1449
 *         or -1 if the buffer length is insufficient
1450
 */
1451
1452
static int decompress_collection_hdr(const struct cmp_cfg *cfg)
1453
0
{
1454
0
  if (cfg->stream_size < COLLECTION_HDR_SIZE)
1455
0
    return -1;
1456
1457
0
  if (cfg->src) {
1458
0
    if (cfg->dst)
1459
0
      memcpy(cfg->dst, cfg->src, COLLECTION_HDR_SIZE);
1460
1461
0
    if (model_mode_is_used(cfg->cmp_mode) && cfg->updated_model_buf)
1462
0
      memcpy(cfg->updated_model_buf, cfg->src, COLLECTION_HDR_SIZE);
1463
0
  }
1464
0
  return COLLECTION_HDR_SIZE;
1465
0
}
1466
1467
1468
/**
1469
 * @brief decompress the data based on a compression configuration
1470
 *
1471
 * @param cfg   pointer to a compression configuration
1472
 * @param decmp_type  type of decompression: ICU chunk or RDCU decompression
1473
 *
1474
 * @note cfg->buffer_length is measured in bytes
1475
 *
1476
 * @returns the size of the decompressed data on success; returns negative on failure
1477
 */
1478
1479
static int decompressed_data_internal(const struct cmp_cfg *cfg, enum decmp_type decmp_type)
1480
0
{
1481
0
  int err;
1482
0
  uint32_t data_size;
1483
1484
0
  assert(decmp_type == ICU_DECOMRESSION || decmp_type == RDCU_DECOMPRESSION);
1485
1486
0
  if (!cfg)
1487
0
    return -1;
1488
1489
0
  if (!cfg->src)
1490
0
    return -1;
1491
1492
0
  if (cmp_cfg_gen_par_is_invalid(cfg))
1493
0
    return -1;
1494
1495
0
  if (cmp_imagette_data_type_is_used(cfg->data_type)) {
1496
0
    if (cmp_cfg_imagette_is_invalid(cfg))
1497
0
      return -1;
1498
0
  } else if (cmp_fx_cob_data_type_is_used(cfg->data_type)) {
1499
0
    if (cmp_cfg_fx_cob_is_invalid(cfg))
1500
0
      return -1;
1501
0
  } else if (cmp_aux_data_type_is_used(cfg->data_type)) {
1502
0
    if (cmp_cfg_aux_is_invalid(cfg))
1503
0
      return -1;
1504
0
  } else {
1505
0
    return -1;
1506
0
  }
1507
1508
0
  if (model_mode_is_used(cfg->cmp_mode))
1509
0
    if (!cfg->model_buf) /* we need a model for model compression */
1510
0
      return -1;
1511
1512
0
  data_size = cfg->samples * (uint32_t)size_of_a_sample(cfg->data_type);
1513
0
  if (decmp_type == ICU_DECOMRESSION)
1514
0
    data_size += COLLECTION_HDR_SIZE;
1515
1516
0
  if (cfg->cmp_mode == CMP_MODE_RAW) {
1517
0
    if (cfg->dst) {
1518
0
      memcpy(cfg->dst, cfg->src, data_size);
1519
0
      switch (decmp_type) {
1520
0
      case ICU_DECOMRESSION:
1521
0
        if (be_to_cpu_chunk(cfg->dst, data_size))
1522
0
          return -1;
1523
0
        break;
1524
0
      case RDCU_DECOMPRESSION:
1525
0
        if (be_to_cpu_data_type(cfg->dst, data_size,
1526
0
              cfg->data_type))
1527
0
          return -1;
1528
0
        break;
1529
0
      }
1530
0
    }
1531
0
    err = 0;
1532
1533
0
  } else {
1534
0
    struct bit_decoder dec;
1535
0
    int hdr_size = 0;
1536
1537
0
    if (!cfg->dst)
1538
0
      return (int)data_size;
1539
1540
0
    if (decmp_type == ICU_DECOMRESSION) {
1541
0
      hdr_size = decompress_collection_hdr(cfg);
1542
0
      if (hdr_size < 0)
1543
0
        return -1;
1544
0
    }
1545
1546
0
    bit_init_decoder(&dec, (const uint8_t *)cfg->src+hdr_size,
1547
0
         cfg->stream_size-(uint32_t)hdr_size);
1548
1549
0
    switch (cfg->data_type) {
1550
0
    case DATA_TYPE_IMAGETTE:
1551
0
    case DATA_TYPE_IMAGETTE_ADAPTIVE:
1552
0
    case DATA_TYPE_SAT_IMAGETTE:
1553
0
    case DATA_TYPE_SAT_IMAGETTE_ADAPTIVE:
1554
0
    case DATA_TYPE_F_CAM_IMAGETTE:
1555
0
    case DATA_TYPE_F_CAM_IMAGETTE_ADAPTIVE:
1556
0
      err = decompress_imagette(cfg, &dec, decmp_type);
1557
0
      break;
1558
0
    case DATA_TYPE_S_FX:
1559
0
      err = decompress_s_fx(cfg, &dec);
1560
0
      break;
1561
0
    case DATA_TYPE_S_FX_EFX:
1562
0
      err = decompress_s_fx_efx(cfg, &dec);
1563
0
      break;
1564
0
    case DATA_TYPE_S_FX_NCOB:
1565
0
      err = decompress_s_fx_ncob(cfg, &dec);
1566
0
      break;
1567
0
    case DATA_TYPE_S_FX_EFX_NCOB_ECOB:
1568
0
      err = decompress_s_fx_efx_ncob_ecob(cfg, &dec);
1569
0
      break;
1570
1571
0
    case DATA_TYPE_L_FX:
1572
0
      err = decompress_l_fx(cfg, &dec);
1573
0
      break;
1574
0
    case DATA_TYPE_L_FX_EFX:
1575
0
      err = decompress_l_fx_efx(cfg, &dec);
1576
0
      break;
1577
0
    case DATA_TYPE_L_FX_NCOB:
1578
0
      err = decompress_l_fx_ncob(cfg, &dec);
1579
0
      break;
1580
0
    case DATA_TYPE_L_FX_EFX_NCOB_ECOB:
1581
0
      err = decompress_l_fx_efx_ncob_ecob(cfg, &dec);
1582
0
      break;
1583
1584
0
    case DATA_TYPE_OFFSET:
1585
0
    case DATA_TYPE_F_CAM_OFFSET:
1586
0
      err = decompress_offset(cfg, &dec);
1587
0
      break;
1588
0
    case DATA_TYPE_BACKGROUND:
1589
0
    case DATA_TYPE_F_CAM_BACKGROUND:
1590
0
      err = decompress_background(cfg, &dec);
1591
0
      break;
1592
0
    case DATA_TYPE_SMEARING:
1593
0
      err = decompress_smearing(cfg, &dec);
1594
0
      break;
1595
1596
0
    case DATA_TYPE_F_FX:
1597
0
    case DATA_TYPE_F_FX_EFX:
1598
0
    case DATA_TYPE_F_FX_NCOB:
1599
0
    case DATA_TYPE_F_FX_EFX_NCOB_ECOB:
1600
0
    case DATA_TYPE_CHUNK:
1601
0
    case DATA_TYPE_UNKNOWN:
1602
0
    default:
1603
0
      err = -1;
1604
0
      debug_print("Error: Compressed data type not supported.");
1605
0
      break;
1606
0
    }
1607
1608
0
    switch (bit_refill(&dec)) {
1609
0
    case BIT_OVERFLOW:
1610
0
      if (dec.cursor == dec.limit_ptr)
1611
0
        debug_print("Error: The end of the compressed bit stream has been exceeded. Please check that the compression parameters match those used to compress the data and that the compressed data are not corrupted.");
1612
0
      else
1613
0
        debug_print("Error: Data consistency check failed. %s", please_check_str);
1614
0
      break;
1615
0
    case BIT_END_OF_BUFFER:
1616
      /* check if non consumed bits are zero */
1617
0
      { unsigned int bits_not_read = sizeof(dec.bit_container)*8 - dec.bits_consumed;
1618
1619
0
        if (bits_not_read > 57) /* can not read more than 57 bits */
1620
0
          bits_not_read = 57;
1621
1622
0
        if (bit_read_bits(&dec, bits_not_read ) == 0)
1623
0
          break;
1624
0
      } /* fall through */
1625
0
    case BIT_UNFINISHED:
1626
0
      debug_print("Warning: Not all compressed data are processed.");
1627
0
      break;
1628
0
    }
1629
0
  }
1630
0
  if (err)
1631
0
    return -1;
1632
1633
0
  return (int)data_size;
1634
0
}
1635
1636
1637
/**
1638
 * @brief read in an imagette compression entity header to a
1639
 *  compression configuration
1640
 *
1641
 * @param ent pointer to a compression entity
1642
 * @param cfg pointer to a compression configuration
1643
 *
1644
 * @returns 0 on success; otherwise error
1645
 */
1646
1647
static int cmp_ent_read_header(const struct cmp_entity *ent, struct cmp_cfg *cfg)
1648
16
{
1649
16
  uint32_t org_size;
1650
1651
16
  if (!cfg)
1652
0
    return -1;
1653
1654
16
  cfg->data_type = cmp_ent_get_data_type(ent);
1655
  /* the compression entity data type field only supports imagette or chunk data types */
1656
16
  if (cfg->data_type != DATA_TYPE_CHUNK && !rdcu_supported_data_type_is_used(cfg->data_type)) {
1657
1
    debug_print("Error: Compression entity data type not supported.");
1658
1
    return -1;
1659
1
  }
1660
1661
15
  cfg->cmp_mode = cmp_ent_get_cmp_mode(ent);
1662
15
  if (cmp_ent_get_data_type_raw_bit(ent) != (cfg->cmp_mode == CMP_MODE_RAW)) {
1663
1
    debug_print("Error: The entity's raw data bit does not match up with the compression mode.");
1664
1
    return -1;
1665
1
  }
1666
14
  cfg->model_value = cmp_ent_get_model_value(ent);
1667
14
  cfg->round = cmp_ent_get_lossy_cmp_par(ent);
1668
14
  cfg->stream_size = cmp_ent_get_cmp_data_size(ent);
1669
1670
14
  if (cmp_cfg_gen_par_is_invalid(cfg))
1671
3
    return -1;
1672
1673
11
  org_size = cmp_ent_get_original_size(ent);
1674
11
  if (cfg->data_type == DATA_TYPE_CHUNK) {
1675
2
    cfg->samples = 0;
1676
2
    if ((cfg->stream_size < (COLLECTION_HDR_SIZE + CMP_COLLECTION_FILD_SIZE) && (cfg->cmp_mode != CMP_MODE_RAW)) ||
1677
2
        (cfg->stream_size < COLLECTION_HDR_SIZE && (cfg->cmp_mode == CMP_MODE_RAW))) {
1678
2
      debug_print("Error: The compressed data size in the compression header is smaller than a collection header.");
1679
2
      return -1;
1680
2
    }
1681
0
    if (org_size < COLLECTION_HDR_SIZE) {
1682
0
      debug_print("Error: The original decompressed data size in the compression header is smaller than the minimum size.");
1683
0
      return -1;
1684
0
    }
1685
9
  } else {
1686
9
    if (org_size % sizeof(uint16_t)) {
1687
1
      debug_print("Error: The original size of an imagette product type in the compression header must be a multiple of 2.");
1688
1
      cfg->samples = 0;
1689
1
      return -1;
1690
1
    }
1691
8
    cfg->samples = org_size/sizeof(uint16_t);
1692
8
  }
1693
1694
8
  cfg->src = cmp_ent_get_data_buf_const(ent);
1695
1696
8
  if (cmp_ent_get_reserved(ent))
1697
5
    debug_print("Warning: The reserved field in the compressed header should be zero.");
1698
1699
8
  if (cfg->cmp_mode == CMP_MODE_RAW) {
1700
2
    if (cmp_ent_get_original_size(ent) != cmp_ent_get_cmp_data_size(ent)) {
1701
2
      debug_print("Error: The compressed data size and the decompressed original data size in the compression header should be the same in raw mode.");
1702
2
      return -1;
1703
2
    }
1704
    /* no specific header is used for raw data we are done */
1705
0
    return 0;
1706
2
  }
1707
1708
6
  if (cmp_ent_cal_hdr_size(cfg->data_type, cfg->cmp_mode == CMP_MODE_RAW)
1709
6
      > cmp_ent_get_size(ent)) {
1710
6
    debug_print("Error: The compression entity size is smaller than the minimum allowed size.");
1711
6
    return -1;
1712
6
  }
1713
1714
0
  switch (cfg->data_type) {
1715
0
  case DATA_TYPE_IMAGETTE_ADAPTIVE:
1716
0
  case DATA_TYPE_SAT_IMAGETTE_ADAPTIVE:
1717
0
  case DATA_TYPE_F_CAM_IMAGETTE_ADAPTIVE:
1718
    /* we do not read in adaptive parameters */
1719
0
  case DATA_TYPE_IMAGETTE:
1720
0
  case DATA_TYPE_SAT_IMAGETTE:
1721
0
  case DATA_TYPE_F_CAM_IMAGETTE:
1722
0
    cfg->cmp_par_imagette = cmp_ent_get_ima_golomb_par(ent);
1723
0
    cfg->spill_imagette = cmp_ent_get_ima_spill(ent);
1724
0
    break;
1725
0
  case DATA_TYPE_OFFSET:
1726
0
  case DATA_TYPE_F_CAM_OFFSET:
1727
0
  case DATA_TYPE_BACKGROUND:
1728
0
  case DATA_TYPE_F_CAM_BACKGROUND:
1729
0
  case DATA_TYPE_SMEARING:
1730
0
  case DATA_TYPE_S_FX:
1731
0
  case DATA_TYPE_S_FX_EFX:
1732
0
  case DATA_TYPE_S_FX_NCOB:
1733
0
  case DATA_TYPE_S_FX_EFX_NCOB_ECOB:
1734
0
  case DATA_TYPE_L_FX:
1735
0
  case DATA_TYPE_L_FX_EFX:
1736
0
  case DATA_TYPE_L_FX_NCOB:
1737
0
  case DATA_TYPE_L_FX_EFX_NCOB_ECOB:
1738
0
  case DATA_TYPE_F_FX:
1739
0
  case DATA_TYPE_F_FX_EFX:
1740
0
  case DATA_TYPE_F_FX_NCOB:
1741
0
  case DATA_TYPE_F_FX_EFX_NCOB_ECOB:
1742
0
  case DATA_TYPE_CHUNK:
1743
0
    cfg->cmp_par_exp_flags = cmp_ent_get_non_ima_cmp_par1(ent);
1744
0
    cfg->spill_exp_flags = cmp_ent_get_non_ima_spill1(ent);
1745
0
    cfg->cmp_par_fx = cmp_ent_get_non_ima_cmp_par2(ent);
1746
0
    cfg->spill_fx = cmp_ent_get_non_ima_spill2(ent);
1747
0
    cfg->cmp_par_ncob = cmp_ent_get_non_ima_cmp_par3(ent);
1748
0
    cfg->spill_ncob = cmp_ent_get_non_ima_spill3(ent);
1749
0
    cfg->cmp_par_efx = cmp_ent_get_non_ima_cmp_par4(ent);
1750
0
    cfg->spill_efx = cmp_ent_get_non_ima_spill4(ent);
1751
0
    cfg->cmp_par_ecob = cmp_ent_get_non_ima_cmp_par5(ent);
1752
0
    cfg->spill_ecob = cmp_ent_get_non_ima_spill5(ent);
1753
0
    cfg->cmp_par_fx_cob_variance = cmp_ent_get_non_ima_cmp_par6(ent);
1754
0
    cfg->spill_fx_cob_variance = cmp_ent_get_non_ima_spill6(ent);
1755
0
    break;
1756
  /* LCOV_EXCL_START */
1757
0
  case DATA_TYPE_UNKNOWN:
1758
0
  default:
1759
0
    return -1;
1760
  /* LCOV_EXCL_STOP */
1761
0
  }
1762
1763
0
  return 0;
1764
0
}
1765
1766
1767
/**
1768
 * @brief Get the size of the compressed collection data
1769
 *
1770
 * @param cmp_col pointer to a compressed collection
1771
 *
1772
 * @return The size of the compressed collection data in bytes
1773
 */
1774
1775
static uint16_t get_cmp_collection_data_length(const uint8_t *cmp_col)
1776
0
{
1777
0
  uint16_t cmp_data_size;
1778
  /* If a non-raw mode is used to compress all collections, a
1779
   * 2-byte big endian field with the size of the compressed data
1780
   * is prefixed (without the size of the file itself and without
1781
   * the size of the collection header). This is followed by a
1782
   * collection header, followed by the compressed data.
1783
   * |---------------------| - cmp_col
1784
   * |compressed collection|
1785
   * |      data size      | 2 bytes
1786
   * |---------------------|-
1787
   * |   COLLECTION HDR    |
1788
   * |                     | 12 bytes
1789
   * |---------------------|-
1790
   * |    compressed data  | (variable) data size
1791
   * |         *-*-*       |
1792
   * |         *-*-*       |
1793
   * |---------------------|- next cmp_col
1794
   * Fields not scaled correctly
1795
   */
1796
1797
0
  memcpy(&cmp_data_size, cmp_col, sizeof(cmp_data_size));
1798
0
  be16_to_cpus(&cmp_data_size);
1799
1800
0
  return cmp_data_size;
1801
0
}
1802
1803
1804
/**
1805
 * @brief get the total size of the compressed collection
1806
 * j
1807
 * This function returns the total size of the compressed collection in bytes,
1808
 * including the size of the compressed size field itself, the collection header,
1809
 * and the compressed collection data.
1810
 *
1811
 * @param cmp_col pointer to a compressed collection
1812
 *
1813
 * @return The total size of the compressed collection in bytes
1814
 */
1815
1816
static uint32_t get_cmp_collection_size(const uint8_t *cmp_col)
1817
0
{
1818
0
  return CMP_COLLECTION_FILD_SIZE + COLLECTION_HDR_SIZE
1819
0
    + get_cmp_collection_data_length(cmp_col);
1820
0
}
1821
1822
1823
/**
1824
 * @brief get the number of compressed collections in a compression entity
1825
 *
1826
 * This function returns the number of compressed collections in a compression
1827
 * entity, by iterating over the compressed collection data
1828
 *
1829
 * @param ent  pointer to the compression entity
1830
 *
1831
 * @return the number of compressed collections in the compressed entity, or -1
1832
 *  on error
1833
 */
1834
1835
static int get_num_of_chunks(const struct cmp_entity *ent)
1836
0
{
1837
0
  const uint8_t *cmp_data_p = cmp_ent_get_data_buf_const(ent);
1838
0
  long const cmp_data_size = cmp_ent_get_cmp_data_size(ent);
1839
0
  int n = 0;
1840
0
  const uint8_t *p = cmp_data_p;
1841
  /* highest plausible address of compressed collection */
1842
0
  const uint8_t *limit_ptr = cmp_data_p + cmp_data_size - COLLECTION_HDR_SIZE;
1843
1844
0
  while (p < limit_ptr) {
1845
0
    p += get_cmp_collection_size(p);
1846
0
    n++;
1847
0
  }
1848
1849
0
  if (p-cmp_data_p != cmp_data_size) {
1850
0
    debug_print("Error: The sum of the compressed collection does not match the size of the data in the compression header.");
1851
0
    return -1;
1852
0
  }
1853
0
  return n;
1854
0
}
1855
1856
1857
/**
1858
 * @brief Parse n'th compressed collection and set configuration parameters
1859
 *  for decompression it
1860
 *
1861
 * @param cmp_col   pointer to a compressed collection to parse
1862
 * @param n     the number of the compressed collection to
1863
 *        parse, starting from 1
1864
 * @param cfg     pointer to the configuration structure
1865
 * @param coll_uncompressed pointer to store whether the collection is
1866
 *        uncompressed or not
1867
 * @param decmp_size    size of the original decompressed data
1868
 *
1869
 * @return the byte offset where to put the uncompressed result in the
1870
 *  decompressed data, or -1 on error.
1871
 */
1872
1873
static long parse_cmp_collection(const uint8_t *cmp_col, int n, struct cmp_cfg *cfg,
1874
         int *coll_uncompressed, int decmp_size)
1875
0
{
1876
0
  int i;
1877
0
  long decmp_pos = 0; /* position where to put the uncompressed result */
1878
  /* pointer to the collection header */
1879
0
  const struct collection_hdr *col_hdr =
1880
0
    (const struct collection_hdr *)(cmp_col + CMP_COLLECTION_FILD_SIZE);
1881
0
  uint32_t cmp_data_size; /* size of the compressed data in the collection (not including the header) */
1882
0
  uint16_t original_col_size; /* size of the decompressed collection data (not including the header) */
1883
0
  size_t sample_size;
1884
1885
  /* get to the collection we want to decompress */
1886
0
  for (i = 0; i < n; i++) {
1887
0
    decmp_pos += cmp_col_get_size(col_hdr);
1888
0
    cmp_col += get_cmp_collection_size(cmp_col);
1889
0
    col_hdr = (const struct collection_hdr *)(cmp_col + CMP_COLLECTION_FILD_SIZE);
1890
0
  }
1891
1892
0
  cmp_data_size = get_cmp_collection_data_length(cmp_col);
1893
0
  original_col_size = cmp_col_get_data_length(col_hdr);
1894
1895
0
  if (cmp_data_size > original_col_size) {
1896
0
    debug_print("Error: Collection %i, the size of the compressed collection is larger than that of the uncompressed collection.", i);
1897
0
    return -1;
1898
0
  }
1899
1900
  /* if the compressed data size == original_col_size the collection data
1901
   * was put uncompressed into the bitstream */
1902
0
  if (cmp_data_size == original_col_size)
1903
0
    *coll_uncompressed = 1;
1904
0
  else
1905
0
    *coll_uncompressed = 0;
1906
1907
0
  cfg->src = col_hdr;
1908
0
  cfg->stream_size = cmp_data_size + COLLECTION_HDR_SIZE;
1909
1910
0
  cfg->data_type = convert_subservice_to_cmp_data_type(cmp_col_get_subservice(col_hdr));
1911
0
  sample_size = size_of_a_sample(cfg->data_type);
1912
0
  if (!sample_size)
1913
0
    return -1;
1914
1915
0
  if (original_col_size % sample_size) {
1916
0
    debug_print("Error: The size of the collection is not a multiple of a collection entry.");
1917
0
    return -1;
1918
0
  }
1919
0
  cfg->samples = original_col_size / sample_size;
1920
1921
0
  if (decmp_pos + original_col_size + COLLECTION_HDR_SIZE > decmp_size) {
1922
0
    debug_print("Error: The compressed data and the original size do not match.");
1923
0
    return -1;
1924
0
  }
1925
1926
0
  return decmp_pos;
1927
0
}
1928
1929
1930
/**
1931
 * @brief decompress a compression entity
1932
 *
1933
 * @note this function assumes that the entity size in the ent header is correct
1934
 * @param ent     pointer to the compression entity to be decompressed
1935
 * @param model_of_data   pointer to model data buffer (can be NULL if no
1936
 *        model compression mode is used)
1937
 * @param up_model_buf    pointer to store the updated model for the next model
1938
 *        mode compression (can be the same as the model_of_data
1939
 *        buffer for an in-place update or NULL if the updated model is not needed)
1940
 * @param decompressed_data pointer to the decompressed data buffer (can be NULL)
1941
 *
1942
 * @returns the size of the decompressed data on success; returns negative on failure
1943
 */
1944
1945
int decompress_cmp_entiy(const struct cmp_entity *ent, const void *model_of_data,
1946
       void *up_model_buf, void *decompressed_data)
1947
19
{
1948
19
  struct cmp_cfg cfg;
1949
19
  int decmp_size;
1950
19
  int i, n_chunks;
1951
1952
19
  memset(&cfg, 0, sizeof(struct cmp_cfg));
1953
1954
19
  if (!ent)
1955
0
    return -1;
1956
1957
19
  decmp_size = (int)cmp_ent_get_original_size(ent);
1958
19
  if (decmp_size < 0)
1959
0
    return -1;
1960
19
  if (decmp_size == 0)
1961
3
    return 0;
1962
1963
16
  if (cmp_ent_read_header(ent, &cfg))
1964
16
    return -1;
1965
1966
0
  if (cfg.data_type != DATA_TYPE_CHUNK) { /* perform a non-chunk decompression */
1967
0
    if (cfg.cmp_mode == CMP_MODE_RAW) {
1968
0
      uint32_t data_size = cfg.samples * sizeof(uint16_t);
1969
1970
0
      if (decompressed_data) {
1971
0
        memcpy(decompressed_data, cmp_ent_get_data_buf_const(ent), data_size);
1972
0
        if (cmp_input_big_to_cpu_endianness(decompressed_data, data_size, cfg.data_type))
1973
0
          return -1;
1974
0
      }
1975
0
      return (int)data_size;
1976
0
    }
1977
1978
0
    cfg.model_buf = model_of_data;
1979
0
    cfg.updated_model_buf = up_model_buf;
1980
0
    cfg.dst = decompressed_data;
1981
1982
0
    return decompressed_data_internal(&cfg, RDCU_DECOMPRESSION);
1983
0
  }
1984
1985
  /* perform a chunk decompression */
1986
1987
0
  if (cfg.cmp_mode == CMP_MODE_RAW) {
1988
0
    if (decompressed_data) {
1989
0
      memcpy(decompressed_data, cfg.src, cfg.stream_size);
1990
0
      cpu_to_be_chunk(decompressed_data, cfg.stream_size);
1991
0
    }
1992
0
    return (int)cfg.stream_size;
1993
0
  }
1994
1995
0
  n_chunks = get_num_of_chunks(ent);
1996
0
  if (n_chunks <= 0)
1997
0
    return -1;
1998
1999
0
  for (i = 0; i < n_chunks; i++) {
2000
0
    int decmp_chunk_size;
2001
0
    int col_uncompressed;
2002
0
    struct cmp_cfg cmp_cpy = cfg;
2003
0
    long offset = parse_cmp_collection(cmp_ent_get_data_buf_const(ent), i,
2004
0
               &cmp_cpy, &col_uncompressed, decmp_size);
2005
0
    if (offset < 0)
2006
0
      return -1;
2007
2008
0
    if (decompressed_data)
2009
0
      cmp_cpy.dst = (uint8_t *)decompressed_data + offset;
2010
0
    if (model_of_data)
2011
0
      cmp_cpy.model_buf = (const uint8_t *)model_of_data + offset;
2012
0
    if (up_model_buf)
2013
0
      cmp_cpy.updated_model_buf = (uint8_t *)up_model_buf + offset;
2014
2015
0
    if (col_uncompressed) {
2016
0
      if (cmp_cpy.updated_model_buf && model_mode_is_used(cmp_cpy.cmp_mode)) {
2017
0
        uint32_t s = cmp_cpy.stream_size;
2018
0
        memcpy(cmp_cpy.updated_model_buf, cmp_cpy.src, s);
2019
0
        if (be_to_cpu_chunk(cmp_cpy.updated_model_buf, s))
2020
0
          return -1;
2021
0
      }
2022
0
      cmp_cpy.cmp_mode = CMP_MODE_RAW;
2023
0
    }
2024
2025
0
    decmp_chunk_size = decompressed_data_internal(&cmp_cpy, ICU_DECOMRESSION);
2026
0
    if (decmp_chunk_size < 0)
2027
0
      return decmp_chunk_size;
2028
0
  }
2029
0
  return decmp_size;
2030
0
}
2031
2032
2033
/**
2034
 * @brief decompress RDCU compressed data without a compression entity header
2035
 *
2036
 * @param compressed_data pointer to the RDCU compressed data (without a
2037
 *        compression entity header)
2038
 * @param info      pointer to a decompression information structure
2039
 *        consisting of the metadata of the compression
2040
 * @param model_of_data   pointer to model data buffer (can be NULL if no
2041
 *        model compression mode is used)
2042
 * @param up_model_buf    pointer to store the updated model for the next model
2043
 *        mode compression (can be the same as the model_of_data
2044
 *        buffer for an in-place update or NULL if the
2045
 *        updated model is not needed)
2046
 * @param decompressed_data pointer to the decompressed data buffer (can be NULL)
2047
 *
2048
 * @returns the size of the decompressed data on success; returns negative on failure
2049
 */
2050
2051
int decompress_rdcu_data(const uint32_t *compressed_data, const struct cmp_info *info,
2052
       const uint16_t *model_of_data, uint16_t *up_model_buf,
2053
       uint16_t *decompressed_data)
2054
2055
0
{
2056
0
  struct cmp_cfg cfg;
2057
2058
0
  if (!compressed_data)
2059
0
    return -1;
2060
2061
0
  if (!info)
2062
0
    return -1;
2063
2064
0
  if (info->cmp_err)
2065
0
    return -1;
2066
2067
0
  memset(&cfg, 0, sizeof(struct cmp_cfg));
2068
2069
0
  cfg.data_type = DATA_TYPE_IMAGETTE;
2070
0
  cfg.model_buf = model_of_data;
2071
0
  cfg.updated_model_buf = up_model_buf;
2072
0
  cfg.dst = decompressed_data;
2073
2074
0
  cfg.cmp_mode = info->cmp_mode_used;
2075
0
  cfg.model_value = info->model_value_used;
2076
0
  cfg.round = info->round_used;
2077
0
  cfg.spill_imagette = info->spill_used;
2078
0
  cfg.cmp_par_imagette = info->golomb_par_used;
2079
0
  cfg.samples = info->samples_used;
2080
0
  cfg.src = compressed_data;
2081
0
  cfg.stream_size = (info->cmp_size+7)/8;
2082
2083
0
  return decompressed_data_internal(&cfg, RDCU_DECOMPRESSION);
2084
0
}