Coverage Report

Created: 2025-06-15 00:57

/src/cmp_tool/lib/common/cmp_data_types.c
Line
Count
Source (jump to first uncovered line)
1
/**
2
 * @file    cmp_data_types.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 collection of functions to handle the different compression data types
17
 */
18
19
20
#include <stddef.h>
21
#include <stdint.h>
22
#include <limits.h>
23
24
#include "compiler.h"
25
#include "byteorder.h"
26
#include "cmp_debug.h"
27
#include "cmp_support.h"
28
#include "cmp_data_types.h"
29
30
31
#ifdef __BIG_ENDIAN
32
#  define CMP_IS_BIG_ENDIAN 1
33
#else
34
64.5k
#  define CMP_IS_BIG_ENDIAN 0
35
#endif
36
37
/**
38
 * @brief get the collection timestamp from the collection header
39
 *
40
 * @param col pointer to a collection header
41
 *
42
 * @returns the collection timestamp
43
 */
44
45
uint64_t cmp_col_get_timestamp(const struct collection_hdr *col)
46
0
{
47
0
#ifdef __LITTLE_ENDIAN
48
0
  return be64_to_cpu(col->timestamp) >> 16;
49
#else
50
  return col->timestamp;
51
#endif /* __LITTLE_ENDIAN */
52
0
}
53
54
55
/**
56
 * @brief get the configuration identifier from the collection header
57
 *
58
 * @param col pointer to a collection header
59
 *
60
 * @returns the configuration identifier
61
 */
62
63
uint16_t cmp_col_get_configuration_id(const struct collection_hdr *col)
64
0
{
65
0
  return be16_to_cpu(col->configuration_id);
66
0
}
67
68
69
/**
70
 * @brief get the collection identifier from the collection header
71
 *
72
 * @param col pointer to a collection header
73
 *
74
 * @returns the collection identifier
75
 */
76
77
uint16_t cmp_col_get_col_id(const struct collection_hdr *col)
78
0
{
79
0
  return be16_to_cpu(col->collection_id);
80
0
}
81
82
83
/**
84
 * @brief get the packet type bit in the collection identifier field of the
85
 *  collection header
86
 *
87
 * @param col pointer to a collection header
88
 *
89
 * @returns the collection packet type a collection; 1 for science packets and
90
 *  0 for window packets
91
 *
92
 */
93
94
uint8_t cmp_col_get_pkt_type(const struct collection_hdr *col)
95
0
{
96
0
  union collection_id cid;
97
98
0
  cid.collection_id = be16_to_cpu(col->collection_id);
99
0
  return cid.field.pkt_type;
100
0
}
101
102
103
/**
104
 * @brief get the subservice field in the collection identifier field of the
105
 *  collection header
106
 *
107
 * @param col pointer to a collection header
108
 *
109
 * @returns the collection subservice type
110
 */
111
112
uint8_t cmp_col_get_subservice(const struct collection_hdr *col)
113
346k
{
114
346k
  union collection_id cid;
115
116
346k
  cid.collection_id = be16_to_cpu(col->collection_id);
117
346k
  return cid.field.subservice;
118
346k
}
119
120
121
/**
122
 * @brief get the CCD identifier field in the collection identifier field of
123
 *  the collection header
124
 *
125
 * @param col pointer to a collection header
126
 *
127
 * @returns the collection CCD identifier
128
 */
129
130
uint8_t cmp_col_get_ccd_id(const struct collection_hdr *col)
131
0
{
132
0
  union collection_id cid;
133
134
0
  cid.collection_id = be16_to_cpu(col->collection_id);
135
0
  return cid.field.ccd_id;
136
0
}
137
138
139
/**
140
 * @brief get the sequence number field in the collection identifier field of
141
 *  the collection header
142
 *
143
 * @param col pointer to a collection header
144
 *
145
 * @returns the collection sequence number
146
 */
147
148
uint8_t cmp_col_get_sequence_num(const struct collection_hdr *col)
149
0
{
150
0
  union collection_id cid;
151
152
0
  cid.collection_id = be16_to_cpu(col->collection_id);
153
0
  return cid.field.sequence_num;
154
0
}
155
156
157
/**
158
 * @brief get the collection length from the collection header
159
 *
160
 * @param col pointer to a collection header
161
 *
162
 * @returns the collection length in bytes
163
 */
164
165
uint16_t cmp_col_get_data_length(const struct collection_hdr *col)
166
3.53M
{
167
3.53M
  return be16_to_cpu(col->collection_length);
168
3.53M
}
169
170
171
/**
172
 * @brief get the entire collection size (header plus data size)
173
 *
174
 * @param col pointer to a collection header
175
 *
176
 * @returns the collection size in bytes
177
 */
178
179
uint32_t cmp_col_get_size(const struct collection_hdr *col)
180
3.31M
{
181
3.31M
  return COLLECTION_HDR_SIZE + cmp_col_get_data_length(col);
182
3.31M
}
183
184
185
/**
186
 * @brief set the timestamp in the collection header
187
 *
188
 * @param col   pointer to a collection header
189
 * @param timestamp collection timestamp (coarse and fine)
190
 *
191
 * @returns 0 on success, otherwise error
192
 */
193
194
int cmp_col_set_timestamp(struct collection_hdr *col, uint64_t timestamp)
195
0
{
196
0
  if (!col)
197
0
    return -1;
198
0
  if (timestamp >> 48)
199
0
    return -1;
200
201
0
#ifdef __LITTLE_ENDIAN
202
0
  col->timestamp = cpu_to_be64(timestamp) >> 16;
203
#else
204
  col->timestamp = timestamp;
205
#endif /* __LITTLE_ENDIAN */
206
207
0
  return 0;
208
0
}
209
210
211
/**
212
 * @brief set the configuration identifier in the collection header
213
 *
214
 * @param col     pointer to a collection header
215
 * @param configuration_id  configuration identifier
216
 *
217
 * @returns 0 on success, otherwise error
218
 */
219
220
int cmp_col_set_configuration_id(struct collection_hdr *col, uint16_t configuration_id)
221
0
{
222
0
  if (!col)
223
0
    return 1;
224
225
0
  col->configuration_id = cpu_to_be16(configuration_id);
226
0
  return 0;
227
0
}
228
229
230
/**
231
 * @brief set the collection identifier in the collection header
232
 *
233
 * @param col   pointer to a collection header
234
 * @param collection_id collection identifier
235
 *
236
 * @returns 0 on success, otherwise error
237
 */
238
239
int cmp_col_set_col_id(struct collection_hdr *col, uint16_t collection_id)
240
0
{
241
0
  if (!col)
242
0
    return -1;
243
244
0
  col->collection_id = cpu_to_be16(collection_id);
245
0
  return 0;
246
0
}
247
248
249
/**
250
 * @brief set the packet type bit in the collection identifier field of the
251
 *  collection header
252
 *
253
 * @param col   pointer to a collection header
254
 * @param pkt_type  packet type bit; 1 for science packets and 0 for window packets
255
 *
256
 * @returns 0 on success, otherwise error
257
 */
258
259
int cmp_col_set_pkt_type(struct collection_hdr *col, uint8_t pkt_type)
260
0
{
261
0
  union collection_id cid;
262
263
0
  if (!col)
264
0
    return -1;
265
0
  if (pkt_type >> 1)
266
0
    return -1;
267
268
0
  cid.collection_id = be16_to_cpu(col->collection_id);
269
0
  cid.field.pkt_type = pkt_type;
270
0
  cmp_col_set_col_id(col, cid.collection_id);
271
0
  return 0;
272
0
}
273
274
275
/**
276
 * @brief set the packet subservice field in the collection identifier field of
277
 *  the collection header
278
 *
279
 * @param col   pointer to a collection header
280
 * @param subservice  collection subservice type
281
 *
282
 * @returns 0 on success, otherwise error
283
 */
284
285
int cmp_col_set_subservice(struct collection_hdr *col, uint8_t subservice)
286
0
{
287
0
  union collection_id cid;
288
289
0
  if (!col)
290
0
    return -1;
291
0
  if (subservice >> 6)
292
0
    return -1;
293
294
0
  cid.collection_id = be16_to_cpu(col->collection_id);
295
0
  cid.field.subservice = subservice;
296
0
  cmp_col_set_col_id(col, cid.collection_id);
297
0
  return 0;
298
0
}
299
300
301
/**
302
 * @brief set the packet CCD identifier field in the collection identifier field
303
 *  of the collection header
304
 *
305
 * @param col   pointer to a collection header
306
 * @param ccd_id  collection CCD identifier
307
 *
308
 * @returns 0 on success, otherwise error
309
 */
310
311
int cmp_col_set_ccd_id(struct collection_hdr *col, uint8_t ccd_id)
312
0
{
313
0
  union collection_id cid;
314
315
0
  if (!col)
316
0
    return -1;
317
0
  if (ccd_id >> 2)
318
0
    return -1;
319
320
0
  cid.collection_id = be16_to_cpu(col->collection_id);
321
0
  cid.field.ccd_id = ccd_id;
322
0
  cmp_col_set_col_id(col, cid.collection_id);
323
0
  return 0;
324
0
}
325
326
327
/**
328
 * @brief set the collection sequence number bit field in the collection
329
 *  identifier of the collection header
330
 *
331
 * @param col   pointer to a collection header
332
 * @param sequence_num  collection sequence number
333
 *
334
 * @returns 0 on success, otherwise error
335
 */
336
337
int cmp_col_set_sequence_num(struct collection_hdr *col, uint8_t sequence_num)
338
0
{
339
0
  union collection_id cid;
340
341
0
  if (!col)
342
0
    return -1;
343
344
0
  if (sequence_num >> 7)
345
0
    return -1;
346
347
0
  cid.collection_id = be16_to_cpu(col->collection_id);
348
0
  cid.field.sequence_num = sequence_num;
349
0
  return cmp_col_set_col_id(col, cid.collection_id);
350
0
}
351
352
353
/**
354
 * @brief set the collection length in the collection header
355
 *
356
 * @param col   pointer to a collection header
357
 * @param length  length of the collection in bytes TBC: without the
358
 *      header size itself
359
 *
360
 * @returns 0 on success, otherwise error
361
 */
362
363
int cmp_col_set_data_length(struct collection_hdr *col, uint16_t length)
364
0
{
365
0
  if (!col)
366
0
    return -1;
367
368
0
  col->collection_length = cpu_to_be16(length);
369
0
  return 0;
370
0
}
371
372
373
/**
374
 * @brief converts a subservice to its associated compression data type
375
 *
376
 * @param subservice  collection subservice type
377
 *
378
 * @returns the converted compression data type; DATA_TYPE_UNKNOWN if the
379
 *  subservice is unknown
380
 */
381
382
enum cmp_data_type convert_subservice_to_cmp_data_type(uint8_t subservice)
383
225k
{
384
225k
  switch (subservice) {
385
4.74k
  case SST_NCxx_S_SCIENCE_IMAGETTE:
386
4.74k
    return DATA_TYPE_IMAGETTE;
387
40.0k
  case SST_NCxx_S_SCIENCE_SAT_IMAGETTE:
388
40.0k
    return DATA_TYPE_SAT_IMAGETTE;
389
4.14k
  case SST_NCxx_S_SCIENCE_OFFSET:
390
4.14k
    return DATA_TYPE_OFFSET;
391
2.52k
  case SST_NCxx_S_SCIENCE_BACKGROUND:
392
2.52k
    return DATA_TYPE_BACKGROUND;
393
8.48k
  case SST_NCxx_S_SCIENCE_SMEARING:
394
8.48k
    return DATA_TYPE_SMEARING;
395
84.5k
  case SST_NCxx_S_SCIENCE_S_FX:
396
84.5k
    return DATA_TYPE_S_FX;
397
6.58k
  case SST_NCxx_S_SCIENCE_S_FX_EFX:
398
6.58k
    return DATA_TYPE_S_FX_EFX;
399
11.2k
  case SST_NCxx_S_SCIENCE_S_FX_NCOB:
400
11.2k
    return DATA_TYPE_S_FX_NCOB;
401
7.57k
  case SST_NCxx_S_SCIENCE_S_FX_EFX_NCOB_ECOB:
402
7.57k
    return DATA_TYPE_S_FX_EFX_NCOB_ECOB;
403
15.2k
  case SST_NCxx_S_SCIENCE_L_FX:
404
15.2k
    return DATA_TYPE_L_FX;
405
4.10k
  case SST_NCxx_S_SCIENCE_L_FX_EFX:
406
4.10k
    return DATA_TYPE_L_FX_EFX;
407
2.97k
  case SST_NCxx_S_SCIENCE_L_FX_NCOB:
408
2.97k
    return DATA_TYPE_L_FX_NCOB;
409
7.06k
  case SST_NCxx_S_SCIENCE_L_FX_EFX_NCOB_ECOB:
410
7.06k
    return DATA_TYPE_L_FX_EFX_NCOB_ECOB;
411
326
  case SST_NCxx_S_SCIENCE_F_FX:
412
326
    return DATA_TYPE_F_FX;
413
88
  case SST_NCxx_S_SCIENCE_F_FX_EFX:
414
88
    return DATA_TYPE_F_FX_EFX;
415
79
  case SST_NCxx_S_SCIENCE_F_FX_NCOB:
416
79
    return DATA_TYPE_F_FX_NCOB;
417
132
  case SST_NCxx_S_SCIENCE_F_FX_EFX_NCOB_ECOB:
418
132
    return DATA_TYPE_F_FX_EFX_NCOB_ECOB;
419
2.24k
  case SST_FCx_S_SCIENCE_IMAGETTE:
420
2.24k
    return DATA_TYPE_F_CAM_IMAGETTE;
421
3.34k
  case SST_FCx_S_SCIENCE_OFFSET_VALUES:
422
3.34k
    return DATA_TYPE_F_CAM_OFFSET;
423
20.0k
  case SST_FCx_S_BACKGROUND_VALUES:
424
20.0k
    return DATA_TYPE_F_CAM_BACKGROUND;
425
39
  default:
426
39
    return DATA_TYPE_UNKNOWN;
427
225k
  };
428
0
}
429
430
431
/**
432
 * @brief converts a compression data type to its associated subservice.
433
 *
434
 * @param data_type compression data type
435
 *
436
 * @returns the converted subservice; -1 if the data type is unknown.
437
 */
438
439
uint8_t convert_cmp_data_type_to_subservice(enum cmp_data_type data_type)
440
0
{
441
0
  uint8_t sst = 0;
442
443
0
  switch (data_type) {
444
0
  case DATA_TYPE_IMAGETTE:
445
0
  case DATA_TYPE_IMAGETTE_ADAPTIVE:
446
0
    sst = SST_NCxx_S_SCIENCE_IMAGETTE;
447
0
    break;
448
0
  case DATA_TYPE_SAT_IMAGETTE:
449
0
  case DATA_TYPE_SAT_IMAGETTE_ADAPTIVE:
450
0
    sst = SST_NCxx_S_SCIENCE_SAT_IMAGETTE;
451
0
    break;
452
0
  case DATA_TYPE_OFFSET:
453
0
    sst = SST_NCxx_S_SCIENCE_OFFSET;
454
0
    break;
455
0
  case DATA_TYPE_BACKGROUND:
456
0
    sst = SST_NCxx_S_SCIENCE_BACKGROUND;
457
0
    break;
458
0
  case DATA_TYPE_SMEARING:
459
0
    sst = SST_NCxx_S_SCIENCE_SMEARING;
460
0
    break;
461
0
  case DATA_TYPE_S_FX:
462
0
    sst = SST_NCxx_S_SCIENCE_S_FX;
463
0
    break;
464
0
  case DATA_TYPE_S_FX_EFX:
465
0
    sst = SST_NCxx_S_SCIENCE_S_FX_EFX;
466
0
    break;
467
0
  case DATA_TYPE_S_FX_NCOB:
468
0
    sst = SST_NCxx_S_SCIENCE_S_FX_NCOB;
469
0
    break;
470
0
  case DATA_TYPE_S_FX_EFX_NCOB_ECOB:
471
0
    sst = SST_NCxx_S_SCIENCE_S_FX_EFX_NCOB_ECOB;
472
0
    break;
473
0
  case DATA_TYPE_L_FX:
474
0
    sst = SST_NCxx_S_SCIENCE_L_FX;
475
0
    break;
476
0
  case DATA_TYPE_L_FX_EFX:
477
0
    sst = SST_NCxx_S_SCIENCE_L_FX_EFX;
478
0
    break;
479
0
  case DATA_TYPE_L_FX_NCOB:
480
0
    sst = SST_NCxx_S_SCIENCE_L_FX_NCOB;
481
0
    break;
482
0
  case DATA_TYPE_L_FX_EFX_NCOB_ECOB:
483
0
    sst = SST_NCxx_S_SCIENCE_L_FX_EFX_NCOB_ECOB;
484
0
    break;
485
0
  case DATA_TYPE_F_FX:
486
0
    sst = SST_NCxx_S_SCIENCE_F_FX;
487
0
    break;
488
0
  case DATA_TYPE_F_FX_EFX:
489
0
    sst = SST_NCxx_S_SCIENCE_F_FX_EFX;
490
0
    break;
491
0
  case DATA_TYPE_F_FX_NCOB:
492
0
    sst = SST_NCxx_S_SCIENCE_F_FX_NCOB;
493
0
    break;
494
0
  case DATA_TYPE_F_FX_EFX_NCOB_ECOB:
495
0
    sst = SST_NCxx_S_SCIENCE_F_FX_EFX_NCOB_ECOB;
496
0
    break;
497
0
  case DATA_TYPE_F_CAM_IMAGETTE:
498
0
  case DATA_TYPE_F_CAM_IMAGETTE_ADAPTIVE:
499
0
    sst = SST_FCx_S_SCIENCE_IMAGETTE;
500
0
    break;
501
0
  case DATA_TYPE_F_CAM_OFFSET:
502
0
    sst = SST_FCx_S_SCIENCE_OFFSET_VALUES;
503
0
    break;
504
0
  case DATA_TYPE_F_CAM_BACKGROUND:
505
0
    sst = SST_FCx_S_BACKGROUND_VALUES;
506
0
    break;
507
0
  default:
508
0
  case DATA_TYPE_UNKNOWN:
509
0
  case DATA_TYPE_CHUNK:
510
0
    debug_print("Error: Unknown compression data type!");
511
0
    sst = (uint8_t)-1;
512
0
  };
513
514
0
  return sst;
515
0
}
516
517
518
/**
519
 * @brief calculate the size of a sample for the different compression data type
520
 *
521
 * @param data_type compression data_type
522
 *
523
 * @returns the size of a data sample in bytes for the selected compression
524
 *  data type; zero on unknown data type
525
 */
526
527
size_t size_of_a_sample(enum cmp_data_type data_type)
528
494k
{
529
494k
  size_t sample_size = 0;
530
531
494k
  switch (data_type) {
532
14.4k
  case DATA_TYPE_IMAGETTE:
533
14.4k
  case DATA_TYPE_IMAGETTE_ADAPTIVE:
534
118k
  case DATA_TYPE_SAT_IMAGETTE:
535
118k
  case DATA_TYPE_SAT_IMAGETTE_ADAPTIVE:
536
123k
  case DATA_TYPE_F_CAM_IMAGETTE:
537
123k
  case DATA_TYPE_F_CAM_IMAGETTE_ADAPTIVE:
538
123k
    sample_size = sizeof(uint16_t);
539
123k
    break;
540
10.9k
  case DATA_TYPE_OFFSET:
541
18.0k
  case DATA_TYPE_F_CAM_OFFSET:
542
18.0k
    sample_size = sizeof(struct offset);
543
18.0k
    break;
544
7.05k
  case DATA_TYPE_BACKGROUND:
545
47.8k
  case DATA_TYPE_F_CAM_BACKGROUND:
546
47.8k
    sample_size = sizeof(struct background);
547
47.8k
    break;
548
22.6k
  case DATA_TYPE_SMEARING:
549
22.6k
    sample_size = sizeof(struct smearing);
550
22.6k
    break;
551
155k
  case DATA_TYPE_S_FX:
552
155k
    sample_size = sizeof(struct s_fx);
553
155k
    break;
554
15.9k
  case DATA_TYPE_S_FX_EFX:
555
15.9k
    sample_size = sizeof(struct s_fx_efx);
556
15.9k
    break;
557
24.1k
  case DATA_TYPE_S_FX_NCOB:
558
24.1k
    sample_size = sizeof(struct s_fx_ncob);
559
24.1k
    break;
560
18.2k
  case DATA_TYPE_S_FX_EFX_NCOB_ECOB:
561
18.2k
    sample_size = sizeof(struct s_fx_efx_ncob_ecob);
562
18.2k
    break;
563
35.3k
  case DATA_TYPE_L_FX:
564
35.3k
    sample_size = sizeof(struct l_fx);
565
35.3k
    break;
566
9.15k
  case DATA_TYPE_L_FX_EFX:
567
9.15k
    sample_size = sizeof(struct l_fx_efx);
568
9.15k
    break;
569
6.98k
  case DATA_TYPE_L_FX_NCOB:
570
6.98k
    sample_size = sizeof(struct l_fx_ncob);
571
6.98k
    break;
572
16.8k
  case DATA_TYPE_L_FX_EFX_NCOB_ECOB:
573
16.8k
    sample_size = sizeof(struct l_fx_efx_ncob_ecob);
574
16.8k
    break;
575
496
  case DATA_TYPE_F_FX:
576
496
    sample_size = sizeof(struct f_fx);
577
496
    break;
578
130
  case DATA_TYPE_F_FX_EFX:
579
130
    sample_size = sizeof(struct f_fx_efx);
580
130
    break;
581
108
  case DATA_TYPE_F_FX_NCOB:
582
108
    sample_size = sizeof(struct f_fx_ncob);
583
108
    break;
584
186
  case DATA_TYPE_F_FX_EFX_NCOB_ECOB:
585
186
    sample_size = sizeof(struct f_fx_efx_ncob_ecob);
586
186
    break;
587
0
  case DATA_TYPE_CHUNK:
588
28
  case DATA_TYPE_UNKNOWN:
589
28
  default:
590
28
    debug_print("Error: Compression data type is not supported.");
591
28
    break;
592
494k
  }
593
494k
  return sample_size;
594
494k
}
595
596
597
static uint32_t be24_to_cpu(uint32_t a)
598
14.4k
{
599
14.4k
#ifdef __LITTLE_ENDIAN
600
14.4k
  return be32_to_cpu(a) >> 8;
601
#else
602
  return a;
603
#endif /* __LITTLE_ENDIAN */
604
14.4k
}
605
606
607
static void be_to_cpus_16(uint16_t *a, uint32_t samples)
608
23.2k
{
609
23.2k
  uint32_t i;
610
611
112k
  for (i = 0; i < samples; i++) {
612
89.4k
    uint16_t tmp;
613
614
89.4k
    tmp = be16_to_cpu(get_unaligned(&a[i]));
615
89.4k
    put_unaligned(tmp, &a[i]);
616
89.4k
  }
617
23.2k
}
618
619
620
static void be_to_cpus_offset(struct offset *a, uint32_t samples)
621
1.96k
{
622
1.96k
  uint32_t i;
623
624
6.39k
  for (i = 0; i < samples; i++) {
625
4.42k
    a[i].mean = be32_to_cpu(a[i].mean);
626
4.42k
    a[i].variance = be32_to_cpu(a[i].variance);
627
4.42k
  }
628
1.96k
}
629
630
631
static void be_to_cpus_background(struct background *a, uint32_t samples)
632
6.99k
{
633
6.99k
  uint32_t i;
634
635
17.6k
  for (i = 0; i < samples; i++) {
636
10.6k
    a[i].mean = be32_to_cpu(a[i].mean);
637
10.6k
    a[i].variance = be32_to_cpu(a[i].variance);
638
10.6k
    a[i].outlier_pixels = be16_to_cpu(a[i].outlier_pixels);
639
10.6k
  }
640
6.99k
}
641
642
643
static void be_to_cpus_smearing(struct smearing *a, uint32_t samples)
644
1.32k
{
645
1.32k
  uint32_t i;
646
647
6.38k
  for (i = 0; i < samples; i++) {
648
5.05k
    a[i].mean = be32_to_cpu(a[i].mean);
649
5.05k
    a[i].variance_mean = be16_to_cpu(a[i].variance_mean);
650
5.05k
    a[i].outlier_pixels = be16_to_cpu(a[i].outlier_pixels);
651
5.05k
  }
652
1.32k
}
653
654
655
static void be_to_cpus_s_fx(struct s_fx *a, uint32_t samples)
656
17.3k
{
657
17.3k
  uint32_t i;
658
659
21.3k
  for (i = 0; i < samples; i++)
660
17.3k
    a[i].fx = be32_to_cpu(a[i].fx);
661
17.3k
}
662
663
664
static void be_to_cpus_s_fx_efx(struct s_fx_efx *a, uint32_t samples)
665
1.78k
{
666
1.78k
  uint32_t i;
667
668
5.95k
  for (i = 0; i < samples; i++) {
669
4.16k
    a[i].fx = be32_to_cpu(a[i].fx);
670
4.16k
    a[i].efx = be32_to_cpu(a[i].efx);
671
4.16k
  }
672
1.78k
}
673
674
675
static void be_to_cpus_s_fx_ncob(struct s_fx_ncob *a, uint32_t samples)
676
2.63k
{
677
2.63k
  uint32_t i;
678
679
7.51k
  for (i = 0; i < samples; i++) {
680
4.87k
    a[i].fx = be32_to_cpu(a[i].fx);
681
4.87k
    a[i].ncob_x = be32_to_cpu(a[i].ncob_x);
682
4.87k
    a[i].ncob_y = be32_to_cpu(a[i].ncob_y);
683
4.87k
  }
684
2.63k
}
685
686
687
static void be_to_cpus_s_fx_efx_ncob_ecob(struct s_fx_efx_ncob_ecob *a, uint32_t samples)
688
2.51k
{
689
2.51k
  uint32_t i;
690
691
6.55k
  for (i = 0; i < samples; i++) {
692
4.03k
    a[i].fx = be32_to_cpu(a[i].fx);
693
4.03k
    a[i].ncob_x = be32_to_cpu(a[i].ncob_x);
694
4.03k
    a[i].ncob_y = be32_to_cpu(a[i].ncob_y);
695
4.03k
    a[i].efx = be32_to_cpu(a[i].efx);
696
4.03k
    a[i].ecob_x = be32_to_cpu(a[i].ecob_x);
697
4.03k
    a[i].ecob_y = be32_to_cpu(a[i].ecob_y);
698
4.03k
  }
699
2.51k
}
700
701
702
static void be_to_cpus_l_fx(struct l_fx *a, uint32_t samples)
703
2.62k
{
704
2.62k
  uint32_t i;
705
706
6.83k
  for (i = 0; i < samples; i++) {
707
4.20k
    a[i].exp_flags = be24_to_cpu(a[i].exp_flags);
708
4.20k
    a[i].fx = be32_to_cpu(a[i].fx);
709
4.20k
    a[i].fx_variance = be32_to_cpu(a[i].fx_variance);
710
4.20k
  }
711
2.62k
}
712
713
714
static void be_to_cpus_l_fx_efx(struct l_fx_efx *a, uint32_t samples)
715
1.22k
{
716
1.22k
  uint32_t i;
717
718
4.78k
  for (i = 0; i < samples; i++) {
719
3.55k
    a[i].exp_flags = be24_to_cpu(a[i].exp_flags);
720
3.55k
    a[i].fx = be32_to_cpu(a[i].fx);
721
3.55k
    a[i].efx = be32_to_cpu(a[i].efx);
722
3.55k
    a[i].fx_variance = be32_to_cpu(a[i].fx_variance);
723
3.55k
  }
724
1.22k
}
725
726
727
static void be_to_cpus_l_fx_ncob(struct l_fx_ncob *a, uint32_t samples)
728
786
{
729
786
  uint32_t i;
730
731
4.46k
  for (i = 0; i < samples; i++) {
732
3.67k
    a[i].exp_flags = be24_to_cpu(a[i].exp_flags);
733
3.67k
    a[i].fx = be32_to_cpu(a[i].fx);
734
3.67k
    a[i].ncob_x = be32_to_cpu(a[i].ncob_x);
735
3.67k
    a[i].ncob_y = be32_to_cpu(a[i].ncob_y);
736
3.67k
    a[i].fx_variance = be32_to_cpu(a[i].fx_variance);
737
3.67k
    a[i].cob_x_variance = be32_to_cpu(a[i].cob_x_variance);
738
3.67k
    a[i].cob_y_variance = be32_to_cpu(a[i].cob_y_variance);
739
3.67k
  }
740
786
}
741
742
743
static void be_to_cpus_l_fx_efx_ncob_ecob(struct l_fx_efx_ncob_ecob *a, uint32_t samples)
744
1.75k
{
745
1.75k
  uint32_t i;
746
747
4.77k
  for (i = 0; i < samples; i++) {
748
3.01k
    a[i].exp_flags = be24_to_cpu(a[i].exp_flags);
749
3.01k
    a[i].fx = be32_to_cpu(a[i].fx);
750
3.01k
    a[i].ncob_x = be32_to_cpu(a[i].ncob_x);
751
3.01k
    a[i].ncob_y = be32_to_cpu(a[i].ncob_y);
752
3.01k
    a[i].efx = be32_to_cpu(a[i].efx);
753
3.01k
    a[i].ecob_x = be32_to_cpu(a[i].ecob_x);
754
3.01k
    a[i].ecob_y = be32_to_cpu(a[i].ecob_y);
755
3.01k
    a[i].fx_variance = be32_to_cpu(a[i].fx_variance);
756
3.01k
    a[i].cob_x_variance = be32_to_cpu(a[i].cob_x_variance);
757
3.01k
    a[i].cob_y_variance = be32_to_cpu(a[i].cob_y_variance);
758
3.01k
  }
759
1.75k
}
760
761
762
static void be_to_cpus_f_fx(struct f_fx *a, uint32_t samples)
763
156
{
764
156
  uint32_t i;
765
766
366
  for (i = 0; i < samples; i++)
767
210
    a[i].fx = be32_to_cpu(a[i].fx);
768
156
}
769
770
771
static void be_to_cpus_f_fx_efx(struct f_fx_efx *a, uint32_t samples)
772
44
{
773
44
  uint32_t i;
774
775
100
  for (i = 0; i < samples; i++) {
776
56
    a[i].fx = be32_to_cpu(a[i].fx);
777
56
    a[i].efx = be32_to_cpu(a[i].efx);
778
56
  }
779
44
}
780
781
782
static void be_to_cpus_f_fx_ncob(struct f_fx_ncob *a, uint32_t samples)
783
49
{
784
49
  uint32_t i;
785
786
127
  for (i = 0; i < samples; i++) {
787
78
    a[i].fx = be32_to_cpu(a[i].fx);
788
78
    a[i].ncob_x = be32_to_cpu(a[i].ncob_x);
789
78
    a[i].ncob_y = be32_to_cpu(a[i].ncob_y);
790
78
  }
791
49
}
792
793
794
static void be_to_cpus_f_fx_efx_ncob_ecob(struct f_fx_efx_ncob_ecob *a, uint32_t samples)
795
74
{
796
74
  uint32_t i;
797
798
120
  for (i = 0; i < samples; i++) {
799
46
    a[i].fx = be32_to_cpu(a[i].fx);
800
46
    a[i].ncob_x = be32_to_cpu(a[i].ncob_x);
801
46
    a[i].ncob_y = be32_to_cpu(a[i].ncob_y);
802
46
    a[i].efx = be32_to_cpu(a[i].efx);
803
46
    a[i].ecob_x = be32_to_cpu(a[i].ecob_x);
804
46
    a[i].ecob_y = be32_to_cpu(a[i].ecob_y);
805
46
  }
806
74
}
807
808
809
/**
810
 * @brief swaps the endianness of (collection) data from big endian to the CPU
811
 *  endianness (or vice versa) in place.
812
 * @note if you want to swap the data of a whole collection, including a
813
 *  collection header or a chunk of collections use the be_to_cpu_chunk() or
814
 *  cpu_to_be_chunk() functions
815
 *
816
 * @param data      a pointer to the data to swap (not including a
817
 *        collection header); can be NULL
818
 * @param data_size_byte  size of the data in bytes
819
 * @param data_type   compression data type
820
 *
821
 * @returns 0 on success; -1 on failure
822
 */
823
824
int be_to_cpu_data_type(void *data, uint32_t data_size_byte, enum cmp_data_type data_type)
825
64.7k
{
826
64.7k
  uint32_t sample_size = (uint32_t)size_of_a_sample(data_type);
827
64.7k
  uint32_t samples;
828
829
64.7k
  if (!data) /* nothing to do */
830
146
    return 0;
831
832
64.6k
  if (!sample_size)
833
17
    return -1;
834
835
64.6k
  if (data_size_byte % sample_size) {
836
4
    debug_print("Error: Can not convert data size in samples.");
837
4
    return -1;
838
4
  }
839
64.5k
  samples = data_size_byte / sample_size;
840
841
64.5k
  if (CMP_IS_BIG_ENDIAN)
842
0
    return 0;
843
844
64.5k
  switch (data_type) {
845
1.50k
  case DATA_TYPE_IMAGETTE:
846
1.51k
  case DATA_TYPE_IMAGETTE_ADAPTIVE:
847
22.7k
  case DATA_TYPE_SAT_IMAGETTE:
848
22.7k
  case DATA_TYPE_SAT_IMAGETTE_ADAPTIVE:
849
23.2k
  case DATA_TYPE_F_CAM_IMAGETTE:
850
23.2k
  case DATA_TYPE_F_CAM_IMAGETTE_ADAPTIVE:
851
23.2k
    be_to_cpus_16(data, samples);
852
23.2k
    break;
853
1.17k
  case DATA_TYPE_OFFSET:
854
1.96k
  case DATA_TYPE_F_CAM_OFFSET:
855
1.96k
    be_to_cpus_offset(data, samples);
856
1.96k
    break;
857
974
  case DATA_TYPE_BACKGROUND:
858
6.99k
  case DATA_TYPE_F_CAM_BACKGROUND:
859
6.99k
    be_to_cpus_background(data, samples);
860
6.99k
    break;
861
1.32k
  case DATA_TYPE_SMEARING:
862
1.32k
    be_to_cpus_smearing(data, samples);
863
1.32k
    break;
864
17.3k
  case DATA_TYPE_S_FX:
865
17.3k
    be_to_cpus_s_fx(data, samples);
866
17.3k
    break;
867
1.78k
  case DATA_TYPE_S_FX_EFX:
868
1.78k
    be_to_cpus_s_fx_efx(data, samples);
869
1.78k
    break;
870
2.63k
  case DATA_TYPE_S_FX_NCOB:
871
2.63k
    be_to_cpus_s_fx_ncob(data, samples);
872
2.63k
    break;
873
2.51k
  case DATA_TYPE_S_FX_EFX_NCOB_ECOB:
874
2.51k
    be_to_cpus_s_fx_efx_ncob_ecob(data, samples);
875
2.51k
    break;
876
2.62k
  case DATA_TYPE_L_FX:
877
2.62k
    be_to_cpus_l_fx(data, samples);
878
2.62k
    break;
879
1.22k
  case DATA_TYPE_L_FX_EFX:
880
1.22k
    be_to_cpus_l_fx_efx(data, samples);
881
1.22k
    break;
882
786
  case DATA_TYPE_L_FX_NCOB:
883
786
    be_to_cpus_l_fx_ncob(data, samples);
884
786
    break;
885
1.75k
  case DATA_TYPE_L_FX_EFX_NCOB_ECOB:
886
1.75k
    be_to_cpus_l_fx_efx_ncob_ecob(data, samples);
887
1.75k
    break;
888
156
  case DATA_TYPE_F_FX:
889
156
    be_to_cpus_f_fx(data, samples);
890
156
    break;
891
44
  case DATA_TYPE_F_FX_EFX:
892
44
    be_to_cpus_f_fx_efx(data, samples);
893
44
    break;
894
49
  case DATA_TYPE_F_FX_NCOB:
895
49
    be_to_cpus_f_fx_ncob(data, samples);
896
49
    break;
897
74
  case DATA_TYPE_F_FX_EFX_NCOB_ECOB:
898
74
    be_to_cpus_f_fx_efx_ncob_ecob(data, samples);
899
74
    break;
900
  /* LCOV_EXCL_START */
901
0
  default:
902
0
    debug_print("Error: Can not swap endianness for this compression data type.");
903
0
    return -1;
904
  /* LCOV_EXCL_STOP */
905
64.5k
  }
906
907
64.5k
  return 0;
908
64.5k
}
909
910
911
/**
912
 * @brief swaps the endianness of chunk data from big endian to the CPU
913
 *  endianness (or vice versa) in place
914
 * @note the endianness of the collection header is not changed!
915
 *
916
 * @param chunk   pointer to a chunk of collections (can be NULL)
917
 * @param chunk_size  size in bytes of the chunk
918
 *
919
 * @returns 0 on success; -1 on failure
920
 */
921
922
int be_to_cpu_chunk(uint8_t *chunk, size_t chunk_size)
923
36.9k
{
924
36.9k
  uint8_t *col_p = chunk;
925
926
36.9k
  if (!chunk) /* nothing to do */
927
401
    return 0;
928
929
36.5k
  if (chunk_size < COLLECTION_HDR_SIZE)
930
15
    return -1;
931
932
74.7k
  while (col_p <= chunk + chunk_size - COLLECTION_HDR_SIZE) {
933
38.2k
    struct collection_hdr *col_hdr = (struct collection_hdr *)col_p;
934
38.2k
    enum cmp_data_type data_type = convert_subservice_to_cmp_data_type(cmp_col_get_subservice(col_hdr));
935
38.2k
    uint32_t data_size = cmp_col_get_data_length(col_hdr);
936
937
38.2k
    col_p += cmp_col_get_size(col_hdr);
938
38.2k
    if (col_p > chunk + chunk_size)  /* over read chunk? */
939
14
      break;
940
941
38.2k
    if (be_to_cpu_data_type(col_hdr->entry, data_size, data_type))
942
21
      return -1;
943
38.2k
  }
944
945
36.4k
  if (col_p != chunk + chunk_size) {
946
106
    debug_print("Error: The chunk size does not match the sum of the collection sizes.");
947
106
    return -1;
948
106
  }
949
950
36.3k
  return 0;
951
36.4k
}
952
953
954
/**
955
 * @brief swap the endianness of uncompressed data from big endian to the cpu
956
 *  endianness (or the other way around) in place
957
 *
958
 * @param data      pointer to a data sample
959
 * @param data_size_byte  size of the data in bytes
960
 * @param data_type   compression data type
961
 *
962
 * @returns 0 on success; non-zero on failure
963
 */
964
965
int cmp_input_big_to_cpu_endianness(void *data, uint32_t data_size_byte,
966
            enum cmp_data_type data_type)
967
9
{
968
9
  if (data && !rdcu_supported_data_type_is_used(data_type)) {
969
    /* skip collection header for non RDCU data types */
970
0
    data = (uint8_t *)data + COLLECTION_HDR_SIZE;
971
0
    if (data_size_byte < COLLECTION_HDR_SIZE)
972
0
      return -1;
973
0
    data_size_byte -= COLLECTION_HDR_SIZE;
974
0
  }
975
9
  return be_to_cpu_data_type(data, data_size_byte, data_type);
976
9
}