/src/cmp_tool/lib/common/cmp_entity.c
Line | Count | Source (jump to first uncovered line) |
1 | | /** |
2 | | * @file cmp_entity.c |
3 | | * @author Dominik Loidolt (dominik.loidolt@univie.ac.at) |
4 | | * @date May 2021 |
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 functions and definition to handle a compression entity |
17 | | * @see Data Compression User Manual PLATO-UVIE-PL-UM-0001 |
18 | | */ |
19 | | |
20 | | |
21 | | #include <stdint.h> |
22 | | #include <string.h> |
23 | | |
24 | | #ifndef ICU_ASW |
25 | | # if defined __has_include |
26 | | # if __has_include(<time.h>) |
27 | | # include <time.h> |
28 | | # include <stdlib.h> |
29 | | # define HAS_TIME_H 1 |
30 | 0 | # define my_timercmp(s, t, op) (((s)->tv_sec == (t)->tv_sec) ? ((s)->tv_nsec op (t)->tv_nsec) : ((s)->tv_sec op (t)->tv_sec)) |
31 | | # endif |
32 | | # endif |
33 | | #endif |
34 | | |
35 | | #include "compiler.h" |
36 | | #include "byteorder.h" |
37 | | #include "cmp_debug.h" |
38 | | #include "cmp_support.h" |
39 | | #include "cmp_entity.h" |
40 | | #include "leon_inttypes.h" |
41 | | |
42 | | |
43 | | #ifdef HAS_TIME_H |
44 | | /* Used as epoch Wed Jan 1 00:00:00 2020 */ |
45 | | # if defined(_WIN32) || defined(_WIN64) |
46 | | const struct tm PLATO_EPOCH_DATE = { 0, 0, 0, 1, 0, 120, 0, 0, 0 }; |
47 | | # else |
48 | | const struct tm PLATO_EPOCH_DATE = { 0, 0, 0, 1, 0, 120, 0, 0, 0, 0, NULL }; |
49 | | # endif /* _WIN */ |
50 | | #endif /* time.h */ |
51 | | |
52 | | |
53 | | /** |
54 | | * @brief calculate the size of the compression entity header based on a |
55 | | * compression data product type |
56 | | * |
57 | | * @param data_type compression data product type |
58 | | * @param raw_mode_flag set this flag if the raw compression mode (CMP_MODE_RAW) is used |
59 | | * |
60 | | * @returns size of the compression entity header in bytes, 0 on unknown data |
61 | | * type |
62 | | */ |
63 | | |
64 | | uint32_t cmp_ent_cal_hdr_size(enum cmp_data_type data_type, int raw_mode_flag) |
65 | 0 | { |
66 | 0 | uint32_t size = 0; |
67 | |
|
68 | 0 | if (raw_mode_flag) { |
69 | 0 | if (!cmp_data_type_is_invalid(data_type)) |
70 | | /* for raw data we do not need a specific header */ |
71 | 0 | size = GENERIC_HEADER_SIZE; |
72 | 0 | } else { |
73 | 0 | switch (data_type) { |
74 | 0 | case DATA_TYPE_IMAGETTE: |
75 | 0 | case DATA_TYPE_SAT_IMAGETTE: |
76 | 0 | case DATA_TYPE_F_CAM_IMAGETTE: |
77 | 0 | size = IMAGETTE_HEADER_SIZE; |
78 | 0 | break; |
79 | 0 | case DATA_TYPE_IMAGETTE_ADAPTIVE: |
80 | 0 | case DATA_TYPE_SAT_IMAGETTE_ADAPTIVE: |
81 | 0 | case DATA_TYPE_F_CAM_IMAGETTE_ADAPTIVE: |
82 | 0 | size = IMAGETTE_ADAPTIVE_HEADER_SIZE; |
83 | 0 | break; |
84 | 0 | case DATA_TYPE_OFFSET: |
85 | 0 | case DATA_TYPE_BACKGROUND: |
86 | 0 | case DATA_TYPE_SMEARING: |
87 | 0 | case DATA_TYPE_S_FX: |
88 | 0 | case DATA_TYPE_S_FX_EFX: |
89 | 0 | case DATA_TYPE_S_FX_NCOB: |
90 | 0 | case DATA_TYPE_S_FX_EFX_NCOB_ECOB: |
91 | 0 | case DATA_TYPE_L_FX: |
92 | 0 | case DATA_TYPE_L_FX_EFX: |
93 | 0 | case DATA_TYPE_L_FX_NCOB: |
94 | 0 | case DATA_TYPE_L_FX_EFX_NCOB_ECOB: |
95 | 0 | case DATA_TYPE_F_FX: |
96 | 0 | case DATA_TYPE_F_FX_EFX: |
97 | 0 | case DATA_TYPE_F_FX_NCOB: |
98 | 0 | case DATA_TYPE_F_FX_EFX_NCOB_ECOB: |
99 | 0 | case DATA_TYPE_F_CAM_OFFSET: |
100 | 0 | case DATA_TYPE_F_CAM_BACKGROUND: |
101 | 0 | case DATA_TYPE_CHUNK: |
102 | 0 | size = NON_IMAGETTE_HEADER_SIZE; |
103 | 0 | break; |
104 | 0 | case DATA_TYPE_UNKNOWN: |
105 | 0 | size = 0; |
106 | 0 | break; |
107 | 0 | } |
108 | 0 | } |
109 | 0 | return size; |
110 | 0 | } |
111 | | |
112 | | |
113 | | /** |
114 | | * @brief set ICU ASW Version ID in the compression entity header |
115 | | * |
116 | | * @param ent pointer to a compression entity |
117 | | * @param version_id the applications software version identifier |
118 | | * |
119 | | * @returns 0 on success, otherwise error |
120 | | */ |
121 | | |
122 | | int cmp_ent_set_version_id(struct cmp_entity *ent, uint32_t version_id) |
123 | 442 | { |
124 | 442 | if (!ent) |
125 | 0 | return -1; |
126 | | |
127 | 442 | ent->version_id = cpu_to_be32(version_id); |
128 | | |
129 | 442 | return 0; |
130 | 442 | } |
131 | | |
132 | | |
133 | | /** |
134 | | * @brief set the size of the compression entity in the entity header |
135 | | * |
136 | | * @param ent pointer to a compression entity |
137 | | * @param cmp_ent_size the compression entity size measured in bytes |
138 | | * |
139 | | * @note maximum size is CMP_ENTITY_MAX_SIZE |
140 | | * |
141 | | * @returns 0 on success, otherwise error |
142 | | */ |
143 | | |
144 | | int cmp_ent_set_size(struct cmp_entity *ent, uint32_t cmp_ent_size) |
145 | 442 | { |
146 | 442 | if (!ent) |
147 | 0 | return -1; |
148 | | |
149 | 442 | if (cmp_ent_size > CMP_ENTITY_MAX_SIZE) |
150 | 0 | return -1; |
151 | | |
152 | 442 | #ifdef __LITTLE_ENDIAN |
153 | 442 | ent->cmp_ent_size = cpu_to_be32(cmp_ent_size) >> 8; |
154 | | #else |
155 | | ent->cmp_ent_size = cmp_ent_size; |
156 | | #endif /* __LITTLE_ENDIAN */ |
157 | | |
158 | 442 | return 0; |
159 | 442 | } |
160 | | |
161 | | |
162 | | /** |
163 | | * @brief set the original size of the compressed data in the entity header |
164 | | * |
165 | | * @param ent pointer to a compression entity |
166 | | * @param original_size the original size of the compressed data measured in |
167 | | * bytes |
168 | | * |
169 | | * @returns 0 on success, otherwise error |
170 | | */ |
171 | | |
172 | | int cmp_ent_set_original_size(struct cmp_entity *ent, uint32_t original_size) |
173 | 442 | { |
174 | 442 | if (!ent) |
175 | 0 | return -1; |
176 | | |
177 | 442 | if (original_size > 0xFFFFFFUL) |
178 | 0 | return -1; |
179 | | |
180 | 442 | #ifdef __LITTLE_ENDIAN |
181 | 442 | ent->original_size = cpu_to_be32(original_size) >> 8; |
182 | | #else |
183 | | ent->original_size = original_size; |
184 | | #endif /* __LITTLE_ENDIAN */ |
185 | | |
186 | 442 | return 0; |
187 | 442 | } |
188 | | |
189 | | |
190 | | /** |
191 | | * @brief set the compression start timestamp in the compression entity header |
192 | | * |
193 | | * @param ent pointer to a compression entity |
194 | | * @param start_timestamp compression start timestamp (coarse and fine) |
195 | | * |
196 | | * @returns 0 on success, otherwise error |
197 | | */ |
198 | | |
199 | | int cmp_ent_set_start_timestamp(struct cmp_entity *ent, uint64_t start_timestamp) |
200 | 201 | { |
201 | 201 | if (!ent) |
202 | 0 | return -1; |
203 | | |
204 | 201 | if (start_timestamp > 0xFFFFFFFFFFFFULL) |
205 | 0 | return -1; |
206 | | |
207 | 201 | #ifdef __LITTLE_ENDIAN |
208 | 201 | ent->start_timestamp = cpu_to_be64(start_timestamp) >> 16; |
209 | | #else |
210 | | ent->start_timestamp = start_timestamp; |
211 | | #endif /* __LITTLE_ENDIAN */ |
212 | | |
213 | 201 | return 0; |
214 | 201 | } |
215 | | |
216 | | |
217 | | /** |
218 | | * @brief set the coarse time in the compression start timestamp in the |
219 | | * compression entity header |
220 | | * |
221 | | * @param ent pointer to a compression entity |
222 | | * @param coarse_time coarse part of the compression start timestamp |
223 | | * |
224 | | * @returns 0 on success, otherwise error |
225 | | */ |
226 | | |
227 | | int cmp_ent_set_coarse_start_time(struct cmp_entity *ent, uint32_t coarse_time) |
228 | 0 | { |
229 | 0 | if (!ent) |
230 | 0 | return -1; |
231 | | |
232 | 0 | ent->start_time.coarse = cpu_to_be32(coarse_time); |
233 | |
|
234 | 0 | return 0; |
235 | 0 | } |
236 | | |
237 | | |
238 | | /** |
239 | | * @brief set the fine time in the compression start timestamp in the |
240 | | * compression entity header |
241 | | * |
242 | | * @param ent pointer to a compression entity |
243 | | * @param fine_time fine part of the compression start timestamp |
244 | | * |
245 | | * @returns 0 on success, otherwise error |
246 | | */ |
247 | | |
248 | | int cmp_ent_set_fine_start_time(struct cmp_entity *ent, uint16_t fine_time) |
249 | 0 | { |
250 | 0 | if (!ent) |
251 | 0 | return -1; |
252 | | |
253 | 0 | ent->start_time.fine = cpu_to_be16(fine_time); |
254 | |
|
255 | 0 | return 0; |
256 | 0 | } |
257 | | |
258 | | |
259 | | /** |
260 | | * @brief set the compression end timestamp in the compression entity header |
261 | | * |
262 | | * @param ent pointer to a compression entity |
263 | | * @param end_timestamp compression end timestamp (coarse and fine) |
264 | | * |
265 | | * @returns 0 on success, otherwise error |
266 | | */ |
267 | | |
268 | | int cmp_ent_set_end_timestamp(struct cmp_entity *ent, uint64_t end_timestamp) |
269 | 201 | { |
270 | 201 | if (!ent) |
271 | 0 | return -1; |
272 | | |
273 | 201 | if (end_timestamp > 0xFFFFFFFFFFFFULL) |
274 | 0 | return -1; |
275 | | |
276 | 201 | #ifdef __LITTLE_ENDIAN |
277 | 201 | ent->end_timestamp = cpu_to_be64(end_timestamp) >> 16; |
278 | | #else |
279 | | ent->end_timestamp = end_timestamp; |
280 | | #endif /* __LITTLE_ENDIAN */ |
281 | | |
282 | 201 | return 0; |
283 | 201 | } |
284 | | |
285 | | |
286 | | /** |
287 | | * @brief set the coarse time in the compression end timestamp in the |
288 | | * compression entity header |
289 | | * |
290 | | * @param ent pointer to a compression entity |
291 | | * @param coarse_time coarse part of the compression end timestamp |
292 | | * |
293 | | * @returns 0 on success, otherwise error |
294 | | */ |
295 | | |
296 | | int cmp_ent_set_coarse_end_time(struct cmp_entity *ent, uint32_t coarse_time) |
297 | 0 | { |
298 | 0 | if (!ent) |
299 | 0 | return -1; |
300 | | |
301 | 0 | ent->end_time.coarse = cpu_to_be32(coarse_time); |
302 | |
|
303 | 0 | return 0; |
304 | 0 | } |
305 | | |
306 | | |
307 | | /** |
308 | | * @brief set the fine time in the compression end timestamp in the compression |
309 | | * entity header |
310 | | * |
311 | | * @param ent pointer to a compression entity |
312 | | * @param fine_time fine part of the compression end timestamp |
313 | | * |
314 | | * @returns 0 on success, otherwise error |
315 | | */ |
316 | | |
317 | | int cmp_ent_set_fine_end_time(struct cmp_entity *ent, uint16_t fine_time) |
318 | 0 | { |
319 | 0 | if (!ent) |
320 | 0 | return -1; |
321 | | |
322 | 0 | ent->end_time.fine = cpu_to_be16(fine_time); |
323 | |
|
324 | 0 | return 0; |
325 | 0 | } |
326 | | |
327 | | |
328 | | /** |
329 | | * @brief set the compression data product type in the compression entity header |
330 | | * |
331 | | * @param ent pointer to a compression entity |
332 | | * @param data_type compression data product type |
333 | | * @param raw_mode_flag set this flag if the raw compression mode (CMP_MODE_RAW) is used |
334 | | * |
335 | | * @returns 0 on success, otherwise error |
336 | | */ |
337 | | |
338 | | int cmp_ent_set_data_type(struct cmp_entity *ent, enum cmp_data_type data_type, |
339 | | int raw_mode_flag) |
340 | 442 | { |
341 | 442 | if (!ent) |
342 | 0 | return -1; |
343 | | |
344 | 442 | if (data_type > 0x7FF) |
345 | 0 | return -1; |
346 | | |
347 | 442 | if (raw_mode_flag) |
348 | 109 | data_type |= 1U << RAW_BIT_DATA_TYPE_POS; |
349 | | |
350 | 442 | ent->data_type = cpu_to_be16((uint16_t)data_type); |
351 | | |
352 | 442 | return 0; |
353 | 442 | } |
354 | | |
355 | | |
356 | | /** |
357 | | * @brief set the used compression mode in the compression entity header |
358 | | * |
359 | | * @param ent pointer to a compression entity |
360 | | * @param cmp_mode_used used compression mode parameter |
361 | | * |
362 | | * @returns 0 on success, otherwise error |
363 | | */ |
364 | | |
365 | | int cmp_ent_set_cmp_mode(struct cmp_entity *ent, enum cmp_mode cmp_mode_used) |
366 | 442 | { |
367 | 442 | if (!ent) |
368 | 0 | return -1; |
369 | | |
370 | 442 | if (cmp_mode_used > UINT8_MAX) |
371 | 0 | return -1; |
372 | | |
373 | 442 | ent->cmp_mode_used = (uint8_t)cmp_mode_used; |
374 | | |
375 | 442 | return 0; |
376 | 442 | } |
377 | | |
378 | | |
379 | | /** |
380 | | * @brief set the used model weighing value in the compression entity header |
381 | | * |
382 | | * @param ent pointer to a compression entity |
383 | | * @param model_value_used used model weighing value parameter |
384 | | * |
385 | | * @returns 0 on success, otherwise error |
386 | | */ |
387 | | |
388 | | int cmp_ent_set_model_value(struct cmp_entity *ent, uint32_t model_value_used) |
389 | 442 | { |
390 | 442 | if (!ent) |
391 | 0 | return -1; |
392 | | |
393 | 442 | if (model_value_used > UINT8_MAX) |
394 | 171 | return -1; |
395 | | |
396 | 271 | ent->model_value_used = (uint8_t)model_value_used; |
397 | | |
398 | 271 | return 0; |
399 | 442 | } |
400 | | |
401 | | |
402 | | /** |
403 | | * @brief set model id in the compression entity header |
404 | | * |
405 | | * @param ent pointer to a compression entity |
406 | | * @param model_id the model identifier |
407 | | * |
408 | | * @returns 0 on success, otherwise error |
409 | | */ |
410 | | |
411 | | int cmp_ent_set_model_id(struct cmp_entity *ent, uint32_t model_id) |
412 | 442 | { |
413 | 442 | if (!ent) |
414 | 0 | return -1; |
415 | | |
416 | 442 | if (model_id > UINT16_MAX) |
417 | 0 | return -1; |
418 | | |
419 | 442 | ent->model_id = cpu_to_be16((uint16_t)model_id); |
420 | | |
421 | 442 | return 0; |
422 | 442 | } |
423 | | |
424 | | |
425 | | /** |
426 | | * @brief set model counter in the compression entity header |
427 | | * |
428 | | * @param ent pointer to a compression entity |
429 | | * @param model_counter the model counter |
430 | | * |
431 | | * @returns 0 on success, otherwise error |
432 | | */ |
433 | | |
434 | | int cmp_ent_set_model_counter(struct cmp_entity *ent, uint32_t model_counter) |
435 | 442 | { |
436 | 442 | if (!ent) |
437 | 0 | return -1; |
438 | | |
439 | 442 | if (model_counter > UINT8_MAX) |
440 | 0 | return -1; |
441 | | |
442 | 442 | ent->model_counter = (uint8_t)model_counter; |
443 | | |
444 | 442 | return 0; |
445 | 442 | } |
446 | | |
447 | | |
448 | | /** |
449 | | * @brief set reserved field in the compression entity header |
450 | | * |
451 | | * @param ent pointer to a compression entity |
452 | | * @param reserved intentionally reserved |
453 | | * |
454 | | * @returns 0 on success, otherwise error |
455 | | */ |
456 | | |
457 | | int cmp_ent_set_reserved(struct cmp_entity *ent, uint8_t reserved) |
458 | 442 | { |
459 | 442 | if (!ent) |
460 | 0 | return -1; |
461 | | |
462 | 442 | ent->reserved = reserved; |
463 | | |
464 | 442 | return 0; |
465 | 442 | } |
466 | | |
467 | | |
468 | | /** |
469 | | * @brief set the used lossy compression parameter in the compression entity |
470 | | * header |
471 | | * |
472 | | * @param ent pointer to a compression entity |
473 | | * @param lossy_cmp_par_used used lossy compression parameter/round parameter |
474 | | * |
475 | | * @returns 0 on success, otherwise error |
476 | | */ |
477 | | |
478 | | int cmp_ent_set_lossy_cmp_par(struct cmp_entity *ent, uint32_t lossy_cmp_par_used) |
479 | 442 | { |
480 | 442 | if (!ent) |
481 | 0 | return -1; |
482 | | |
483 | 442 | if (lossy_cmp_par_used > UINT16_MAX) |
484 | 0 | return -1; |
485 | | |
486 | 442 | ent->lossy_cmp_par_used = cpu_to_be16((uint16_t)lossy_cmp_par_used); |
487 | | |
488 | 442 | return 0; |
489 | 442 | } |
490 | | |
491 | | |
492 | | /** |
493 | | * @brief set the used spillover threshold parameter in the (adaptive) imagette |
494 | | * specific compression entity header |
495 | | * |
496 | | * @param ent pointer to a compression entity |
497 | | * @param spill_used used spillover threshold for imagette data_type |
498 | | * |
499 | | * @returns 0 on success, otherwise error |
500 | | */ |
501 | | |
502 | | int cmp_ent_set_ima_spill(struct cmp_entity *ent, uint32_t spill_used) |
503 | 0 | { |
504 | 0 | if (!ent) |
505 | 0 | return -1; |
506 | | |
507 | 0 | if (spill_used > UINT16_MAX) |
508 | 0 | return -1; |
509 | | |
510 | 0 | ent->ima.spill_used = cpu_to_be16((uint16_t)spill_used); |
511 | |
|
512 | 0 | return 0; |
513 | 0 | } |
514 | | |
515 | | |
516 | | /** |
517 | | * @brief set used Golomb parameter in the (adaptive) imagette specific |
518 | | * compression entity header |
519 | | * |
520 | | * @param ent pointer to a compression entity |
521 | | * @param golomb_par_used used Golomb parameter used for imagette |
522 | | * data_type |
523 | | * |
524 | | * @returns 0 on success, otherwise error |
525 | | */ |
526 | | |
527 | | int cmp_ent_set_ima_golomb_par(struct cmp_entity *ent, uint32_t golomb_par_used) |
528 | 0 | { |
529 | 0 | if (!ent) |
530 | 0 | return -1; |
531 | | |
532 | 0 | if (golomb_par_used > UINT8_MAX) |
533 | 0 | return -1; |
534 | | |
535 | 0 | ent->ima.golomb_par_used = (uint8_t)golomb_par_used; |
536 | |
|
537 | 0 | return 0; |
538 | 0 | } |
539 | | |
540 | | |
541 | | /** |
542 | | * @brief set the used adaptive 1 spillover threshold parameter in the adaptive |
543 | | * imagette specific compression entity header |
544 | | * |
545 | | * @param ent pointer to a compression entity |
546 | | * @param ap1_spill_used used adaptive 1 spillover threshold used for |
547 | | * semi-adaptive compression feature |
548 | | * |
549 | | * @returns 0 on success, otherwise error |
550 | | */ |
551 | | |
552 | | int cmp_ent_set_ima_ap1_spill(struct cmp_entity *ent, uint32_t ap1_spill_used) |
553 | 0 | { |
554 | 0 | if (!ent) |
555 | 0 | return -1; |
556 | | |
557 | 0 | if (ap1_spill_used > UINT16_MAX) |
558 | 0 | return -1; |
559 | | |
560 | 0 | ent->ima.ap1_spill_used = cpu_to_be16((uint16_t)ap1_spill_used); |
561 | |
|
562 | 0 | return 0; |
563 | 0 | } |
564 | | |
565 | | |
566 | | /** |
567 | | * @brief set adaptive 1 Golomb parameter in the adaptive imagette specific |
568 | | * compression entity header |
569 | | * |
570 | | * @param ent pointer to a compression entity |
571 | | * @param ap1_golomb_par_used used adaptive 1 Golomb parameter for |
572 | | * semi-adaptive compression feature |
573 | | * |
574 | | * @returns 0 on success, otherwise error |
575 | | */ |
576 | | |
577 | | int cmp_ent_set_ima_ap1_golomb_par(struct cmp_entity *ent, uint32_t ap1_golomb_par_used) |
578 | 0 | { |
579 | 0 | if (!ent) |
580 | 0 | return -1; |
581 | | |
582 | 0 | if (ap1_golomb_par_used > UINT8_MAX) |
583 | 0 | return -1; |
584 | | |
585 | 0 | ent->ima.ap1_golomb_par_used = (uint8_t)ap1_golomb_par_used; |
586 | |
|
587 | 0 | return 0; |
588 | 0 | } |
589 | | |
590 | | |
591 | | /** |
592 | | * @brief set the used adaptive 2 spillover threshold parameter in the adaptive |
593 | | * imagette specific compression entity header |
594 | | * |
595 | | * @param ent pointer to a compression entity |
596 | | * @param ap2_spill_used used adaptive 2 spillover threshold used for |
597 | | * semi-adaptive compression feature |
598 | | * |
599 | | * @returns 0 on success, otherwise error |
600 | | */ |
601 | | |
602 | | int cmp_ent_set_ima_ap2_spill(struct cmp_entity *ent, uint32_t ap2_spill_used) |
603 | 0 | { |
604 | 0 | if (!ent) |
605 | 0 | return -1; |
606 | | |
607 | 0 | if (ap2_spill_used > UINT16_MAX) |
608 | 0 | return -1; |
609 | | |
610 | 0 | ent->ima.ap2_spill_used = cpu_to_be16((uint16_t)ap2_spill_used); |
611 | |
|
612 | 0 | return 0; |
613 | 0 | } |
614 | | |
615 | | |
616 | | /** |
617 | | * @brief set adaptive 2 Golomb parameter in the adaptive imagette specific |
618 | | * compression entity header |
619 | | * |
620 | | * @param ent pointer to a compression entity |
621 | | * @param ap2_golomb_par_used used adaptive 2 Golomb parameter for |
622 | | * semi-adaptive compression feature |
623 | | * |
624 | | * @returns 0 on success, otherwise error |
625 | | */ |
626 | | |
627 | | int cmp_ent_set_ima_ap2_golomb_par(struct cmp_entity *ent, uint32_t ap2_golomb_par_used) |
628 | 0 | { |
629 | 0 | if (!ent) |
630 | 0 | return -1; |
631 | | |
632 | 0 | if (ap2_golomb_par_used > UINT8_MAX) |
633 | 0 | return -1; |
634 | | |
635 | 0 | ent->ima.ap2_golomb_par_used = (uint8_t)ap2_golomb_par_used; |
636 | |
|
637 | 0 | return 0; |
638 | 0 | } |
639 | | |
640 | | |
641 | | /** |
642 | | * @brief set the used spillover threshold 1 parameter in the non-imagette |
643 | | * specific compression entity header |
644 | | * |
645 | | * @param ent pointer to a compression entity |
646 | | * @param spill_1_used used spillover threshold parameter 1 for non-imagette |
647 | | * data_types |
648 | | * |
649 | | * @returns 0 on success, otherwise error |
650 | | */ |
651 | | |
652 | | int cmp_ent_set_non_ima_spill1(struct cmp_entity *ent, uint32_t spill_1_used) |
653 | 333 | { |
654 | 333 | if (!ent) |
655 | 0 | return -1; |
656 | | |
657 | 333 | if (spill_1_used > 0xFFFFFFUL) |
658 | 0 | return -1; |
659 | | |
660 | 333 | #ifdef __LITTLE_ENDIAN |
661 | 333 | ent->non_ima.spill_1_used = cpu_to_be32(spill_1_used) >> 8; |
662 | | #else |
663 | | ent->non_ima.spill_1_used = spill_1_used; |
664 | | #endif /* __LITTLE_ENDIAN */ |
665 | | |
666 | 333 | return 0; |
667 | 333 | } |
668 | | |
669 | | |
670 | | /** |
671 | | * @brief set used compression parameter 1 in the non-imagette specific |
672 | | * compression entity header |
673 | | * |
674 | | * @param ent pointer to a compression entity |
675 | | * @param cmp_par_1_used used compression parameter 1 |
676 | | * |
677 | | * @returns 0 on success, otherwise error |
678 | | */ |
679 | | |
680 | | int cmp_ent_set_non_ima_cmp_par1(struct cmp_entity *ent, uint32_t cmp_par_1_used) |
681 | 333 | { |
682 | 333 | if (!ent) |
683 | 0 | return -1; |
684 | | |
685 | 333 | if (cmp_par_1_used > UINT16_MAX) |
686 | 10 | return -1; |
687 | | |
688 | 323 | ent->non_ima.cmp_par_1_used = cpu_to_be16((uint16_t)cmp_par_1_used); |
689 | | |
690 | 323 | return 0; |
691 | 333 | } |
692 | | |
693 | | |
694 | | /** |
695 | | * @brief set the used spillover threshold 2 parameter in the non-imagette |
696 | | * specific compression entity header |
697 | | * |
698 | | * @param ent pointer to a compression entity |
699 | | * @param spill_2_used used spillover threshold parameter 2 for non-imagette |
700 | | * data_types |
701 | | * |
702 | | * @returns 0 on success, otherwise error |
703 | | */ |
704 | | |
705 | | int cmp_ent_set_non_ima_spill2(struct cmp_entity *ent, uint32_t spill_2_used) |
706 | 333 | { |
707 | 333 | if (!ent) |
708 | 0 | return -1; |
709 | | |
710 | 333 | if (spill_2_used > 0xFFFFFFUL) |
711 | 0 | return -1; |
712 | | |
713 | 333 | #ifdef __LITTLE_ENDIAN |
714 | 333 | ent->non_ima.spill_2_used = cpu_to_be32(spill_2_used) >> 8; |
715 | | #else |
716 | | ent->non_ima.spill_2_used = spill_2_used; |
717 | | #endif /* __LITTLE_ENDIAN */ |
718 | | |
719 | 333 | return 0; |
720 | 333 | } |
721 | | |
722 | | |
723 | | /** |
724 | | * @brief set used compression parameter 2 in the non-imagette specific |
725 | | * compression entity header |
726 | | * |
727 | | * @param ent pointer to a compression entity |
728 | | * @param cmp_par_2_used used compression parameter 2 |
729 | | * |
730 | | * @returns 0 on success, otherwise error |
731 | | */ |
732 | | |
733 | | int cmp_ent_set_non_ima_cmp_par2(struct cmp_entity *ent, uint32_t cmp_par_2_used) |
734 | 333 | { |
735 | 333 | if (!ent) |
736 | 0 | return -1; |
737 | | |
738 | 333 | if (cmp_par_2_used > UINT16_MAX) |
739 | 16 | return -1; |
740 | | |
741 | 317 | ent->non_ima.cmp_par_2_used = cpu_to_be16((uint16_t)cmp_par_2_used); |
742 | | |
743 | 317 | return 0; |
744 | 333 | } |
745 | | |
746 | | |
747 | | /** |
748 | | * @brief set the used spillover threshold 3 parameter in the non-imagette |
749 | | * specific compression entity header |
750 | | * |
751 | | * @param ent pointer to a compression entity |
752 | | * @param spill_3_used used spillover threshold parameter 3 for non-imagette |
753 | | * data_types |
754 | | * |
755 | | * @returns 0 on success, otherwise error |
756 | | */ |
757 | | |
758 | | int cmp_ent_set_non_ima_spill3(struct cmp_entity *ent, uint32_t spill_3_used) |
759 | 333 | { |
760 | 333 | if (!ent) |
761 | 0 | return -1; |
762 | | |
763 | 333 | if (spill_3_used > 0xFFFFFFUL) |
764 | 0 | return -1; |
765 | | |
766 | 333 | #ifdef __LITTLE_ENDIAN |
767 | 333 | ent->non_ima.spill_3_used = cpu_to_be32(spill_3_used) >> 8; |
768 | | #else |
769 | | ent->non_ima.spill_3_used = spill_3_used; |
770 | | #endif /* __LITTLE_ENDIAN */ |
771 | | |
772 | 333 | return 0; |
773 | 333 | } |
774 | | |
775 | | |
776 | | /** |
777 | | * @brief set used compression parameter 3 in the non-imagette specific |
778 | | * compression entity header |
779 | | * |
780 | | * @param ent pointer to a compression entity |
781 | | * @param cmp_par_3_used used compression parameter 3 |
782 | | * |
783 | | * @returns 0 on success, otherwise error |
784 | | */ |
785 | | |
786 | | int cmp_ent_set_non_ima_cmp_par3(struct cmp_entity *ent, uint32_t cmp_par_3_used) |
787 | 333 | { |
788 | 333 | if (!ent) |
789 | 0 | return -1; |
790 | | |
791 | 333 | if (cmp_par_3_used > UINT16_MAX) |
792 | 32 | return -1; |
793 | | |
794 | 301 | ent->non_ima.cmp_par_3_used = cpu_to_be16((uint16_t)cmp_par_3_used); |
795 | | |
796 | 301 | return 0; |
797 | 333 | } |
798 | | |
799 | | |
800 | | /** |
801 | | * @brief set the used spillover threshold 4 parameter in the non-imagette |
802 | | * specific compression entity header |
803 | | * |
804 | | * @param ent pointer to a compression entity |
805 | | * @param spill_4_used used spillover threshold parameter 4 for non-imagette |
806 | | * data_types |
807 | | * |
808 | | * @returns 0 on success, otherwise error |
809 | | */ |
810 | | |
811 | | int cmp_ent_set_non_ima_spill4(struct cmp_entity *ent, uint32_t spill_4_used) |
812 | 333 | { |
813 | 333 | if (!ent) |
814 | 0 | return -1; |
815 | | |
816 | 333 | if (spill_4_used > 0xFFFFFFUL) |
817 | 0 | return -1; |
818 | | |
819 | 333 | #ifdef __LITTLE_ENDIAN |
820 | 333 | ent->non_ima.spill_4_used = cpu_to_be32(spill_4_used) >> 8; |
821 | | #else |
822 | | ent->non_ima.spill_4_used = spill_4_used; |
823 | | #endif /* __LITTLE_ENDIAN */ |
824 | | |
825 | 333 | return 0; |
826 | 333 | } |
827 | | |
828 | | |
829 | | /** |
830 | | * @brief set used compression parameter 4 in the non-imagette specific |
831 | | * compression entity header |
832 | | * |
833 | | * @param ent pointer to a compression entity |
834 | | * @param cmp_par_4_used used compression parameter 4 |
835 | | * |
836 | | * @returns 0 on success, otherwise error |
837 | | */ |
838 | | |
839 | | int cmp_ent_set_non_ima_cmp_par4(struct cmp_entity *ent, uint32_t cmp_par_4_used) |
840 | 333 | { |
841 | 333 | if (!ent) |
842 | 0 | return -1; |
843 | | |
844 | 333 | if (cmp_par_4_used > UINT16_MAX) |
845 | 55 | return -1; |
846 | | |
847 | 278 | ent->non_ima.cmp_par_4_used = cpu_to_be16((uint16_t)cmp_par_4_used); |
848 | | |
849 | 278 | return 0; |
850 | 333 | } |
851 | | |
852 | | |
853 | | /** |
854 | | * @brief set the used spillover threshold 5 parameter in the non-imagette |
855 | | * specific compression entity header |
856 | | * |
857 | | * @param ent pointer to a compression entity |
858 | | * @param spill_5_used used spillover threshold parameter 5 for non-imagette |
859 | | * data_types |
860 | | * |
861 | | * @returns 0 on success, otherwise error |
862 | | */ |
863 | | |
864 | | int cmp_ent_set_non_ima_spill5(struct cmp_entity *ent, uint32_t spill_5_used) |
865 | 333 | { |
866 | 333 | if (!ent) |
867 | 0 | return -1; |
868 | | |
869 | 333 | if (spill_5_used > 0xFFFFFFUL) |
870 | 0 | return -1; |
871 | | |
872 | 333 | #ifdef __LITTLE_ENDIAN |
873 | 333 | ent->non_ima.spill_5_used = cpu_to_be32(spill_5_used) >> 8; |
874 | | #else |
875 | | ent->non_ima.spill_5_used = spill_5_used; |
876 | | #endif /* __LITTLE_ENDIAN */ |
877 | | |
878 | 333 | return 0; |
879 | 333 | } |
880 | | |
881 | | |
882 | | /** |
883 | | * @brief set used compression parameter 5 in the non-imagette specific |
884 | | * compression entity header |
885 | | * |
886 | | * @param ent pointer to a compression entity |
887 | | * @param cmp_par_5_used used compression parameter 5 |
888 | | * |
889 | | * @returns 0 on success, otherwise error |
890 | | */ |
891 | | |
892 | | int cmp_ent_set_non_ima_cmp_par5(struct cmp_entity *ent, uint32_t cmp_par_5_used) |
893 | 333 | { |
894 | 333 | if (!ent) |
895 | 0 | return -1; |
896 | | |
897 | 333 | if (cmp_par_5_used > UINT16_MAX) |
898 | 76 | return -1; |
899 | | |
900 | 257 | ent->non_ima.cmp_par_5_used = cpu_to_be16((uint16_t)cmp_par_5_used); |
901 | | |
902 | 257 | return 0; |
903 | 333 | } |
904 | | |
905 | | |
906 | | /** |
907 | | * @brief set the used spillover threshold 6 parameter in the non-imagette |
908 | | * specific compression entity header |
909 | | * |
910 | | * @param ent pointer to a compression entity |
911 | | * @param spill_6_used used spillover threshold parameter 6 for non-imagette |
912 | | * data_types |
913 | | * |
914 | | * @returns 0 on success, otherwise error |
915 | | */ |
916 | | |
917 | | int cmp_ent_set_non_ima_spill6(struct cmp_entity *ent, uint32_t spill_6_used) |
918 | 333 | { |
919 | 333 | if (!ent) |
920 | 0 | return -1; |
921 | | |
922 | 333 | if (spill_6_used > 0xFFFFFFUL) |
923 | 0 | return -1; |
924 | | |
925 | 333 | #ifdef __LITTLE_ENDIAN |
926 | 333 | ent->non_ima.spill_6_used = cpu_to_be32(spill_6_used) >> 8; |
927 | | #else |
928 | | ent->non_ima.spill_6_used = spill_6_used; |
929 | | #endif /* __LITTLE_ENDIAN */ |
930 | | |
931 | 333 | return 0; |
932 | 333 | } |
933 | | |
934 | | |
935 | | /** |
936 | | * @brief set used compression parameter 6 in the non-imagette specific |
937 | | * compression entity header |
938 | | * |
939 | | * @param ent pointer to a compression entity |
940 | | * @param cmp_par_6_used used compression parameter 6 |
941 | | * |
942 | | * @returns 0 on success, otherwise error |
943 | | */ |
944 | | |
945 | | int cmp_ent_set_non_ima_cmp_par6(struct cmp_entity *ent, uint32_t cmp_par_6_used) |
946 | 333 | { |
947 | 333 | if (!ent) |
948 | 0 | return -1; |
949 | | |
950 | 333 | if (cmp_par_6_used > UINT16_MAX) |
951 | 27 | return -1; |
952 | | |
953 | 306 | ent->non_ima.cmp_par_6_used = cpu_to_be16((uint16_t)cmp_par_6_used); |
954 | | |
955 | 306 | return 0; |
956 | 333 | } |
957 | | |
958 | | |
959 | | /** |
960 | | * @brief get the ASW version identifier from the compression entity header |
961 | | * |
962 | | * @param ent pointer to a compression entity |
963 | | * |
964 | | * @returns the ASW version identifier on success, 0 on error |
965 | | */ |
966 | | |
967 | | uint32_t cmp_ent_get_version_id(const struct cmp_entity *ent) |
968 | 0 | { |
969 | 0 | if (!ent) |
970 | 0 | return 0; |
971 | | |
972 | 0 | return be32_to_cpu(ent->version_id); |
973 | 0 | } |
974 | | |
975 | | |
976 | | /** |
977 | | * @brief get the size of the compression entity from the compression entity header |
978 | | * |
979 | | * @param ent pointer to a compression entity |
980 | | * |
981 | | * @returns the size of the compression entity in bytes on success, 0 on error |
982 | | */ |
983 | | |
984 | | uint32_t cmp_ent_get_size(const struct cmp_entity *ent) |
985 | 0 | { |
986 | 0 | if (!ent) |
987 | 0 | return 0; |
988 | | |
989 | 0 | #ifdef __LITTLE_ENDIAN |
990 | 0 | return be32_to_cpu(ent->cmp_ent_size) >> 8; |
991 | | #else |
992 | | return ent->cmp_ent_size; |
993 | | #endif /* __LITTLE_ENDIAN */ |
994 | 0 | } |
995 | | |
996 | | |
997 | | /** |
998 | | * @brief get the original data size from the compression entity header |
999 | | * |
1000 | | * @param ent pointer to a compression entity |
1001 | | * |
1002 | | * @returns the original size of the compressed data in bytes on success, 0 on error |
1003 | | */ |
1004 | | |
1005 | | uint32_t cmp_ent_get_original_size(const struct cmp_entity *ent) |
1006 | 0 | { |
1007 | 0 | if (!ent) |
1008 | 0 | return 0; |
1009 | | |
1010 | 0 | #ifdef __LITTLE_ENDIAN |
1011 | 0 | return be32_to_cpu(ent->original_size) >> 8; |
1012 | | #else |
1013 | | return ent->original_size; |
1014 | | #endif /* __LITTLE_ENDIAN */ |
1015 | 0 | } |
1016 | | |
1017 | | |
1018 | | /** |
1019 | | * @brief get the compression start timestamp from the compression entity header |
1020 | | * |
1021 | | * @param ent pointer to a compression entity |
1022 | | * |
1023 | | * @returns the compression start timestamp on success, 0 on error |
1024 | | */ |
1025 | | |
1026 | | uint64_t cmp_ent_get_start_timestamp(const struct cmp_entity *ent) |
1027 | 0 | { |
1028 | 0 | if (!ent) |
1029 | 0 | return 0; |
1030 | | |
1031 | 0 | #ifdef __LITTLE_ENDIAN |
1032 | 0 | return be64_to_cpu(ent->start_timestamp) >> 16; |
1033 | | #else |
1034 | | return ent->start_timestamp; |
1035 | | #endif /* __LITTLE_ENDIAN */ |
1036 | 0 | } |
1037 | | |
1038 | | |
1039 | | /** |
1040 | | * @brief get the coarse time from the compression start timestamp in the |
1041 | | * compression entity header |
1042 | | * |
1043 | | * @returns the coarse part of the compression start timestamp on success, 0 on |
1044 | | * error |
1045 | | */ |
1046 | | |
1047 | | uint32_t cmp_ent_get_coarse_start_time(const struct cmp_entity *ent) |
1048 | 0 | { |
1049 | 0 | if (!ent) |
1050 | 0 | return 0; |
1051 | | |
1052 | 0 | return be32_to_cpu(ent->start_time.coarse); |
1053 | 0 | } |
1054 | | |
1055 | | |
1056 | | /** |
1057 | | * @brief get the fine time from the compression start timestamp in the |
1058 | | * compression entity header |
1059 | | * |
1060 | | * @returns the fine part of the compression start timestamp on success, 0 on |
1061 | | * error |
1062 | | */ |
1063 | | |
1064 | | uint16_t cmp_ent_get_fine_start_time(const struct cmp_entity *ent) |
1065 | 0 | { |
1066 | 0 | if (!ent) |
1067 | 0 | return 0; |
1068 | | |
1069 | 0 | return be16_to_cpu(ent->start_time.fine); |
1070 | 0 | } |
1071 | | |
1072 | | |
1073 | | /** |
1074 | | * @brief get the compression end timestamp from the compression entity header |
1075 | | * |
1076 | | * @param ent pointer to a compression entity |
1077 | | * |
1078 | | * @returns the compression end timestamp on success, 0 on error |
1079 | | */ |
1080 | | |
1081 | | uint64_t cmp_ent_get_end_timestamp(const struct cmp_entity *ent) |
1082 | 0 | { |
1083 | 0 | if (!ent) |
1084 | 0 | return 0; |
1085 | | |
1086 | 0 | #ifdef __LITTLE_ENDIAN |
1087 | 0 | return be64_to_cpu(ent->end_timestamp) >> 16; |
1088 | | #else |
1089 | | return ent->end_timestamp; |
1090 | | #endif /* __LITTLE_ENDIAN */ |
1091 | 0 | } |
1092 | | |
1093 | | |
1094 | | /** |
1095 | | * @brief get the coarse time from the compression end timestamp in the |
1096 | | * compression entity header |
1097 | | * |
1098 | | * @returns the coarse part of the compression end timestamp on success, 0 on |
1099 | | * error |
1100 | | */ |
1101 | | |
1102 | | uint32_t cmp_ent_get_coarse_end_time(const struct cmp_entity *ent) |
1103 | 0 | { |
1104 | 0 | if (!ent) |
1105 | 0 | return 0; |
1106 | | |
1107 | 0 | return be32_to_cpu(ent->end_time.coarse); |
1108 | 0 | } |
1109 | | |
1110 | | |
1111 | | /** |
1112 | | * @brief get the fine time from the compression end timestamp in the |
1113 | | * compression entity header |
1114 | | * |
1115 | | * @returns the fine part of the compression end timestamp on success, 0 on |
1116 | | * error |
1117 | | */ |
1118 | | |
1119 | | uint16_t cmp_ent_get_fine_end_time(const struct cmp_entity *ent) |
1120 | 0 | { |
1121 | 0 | if (!ent) |
1122 | 0 | return 0; |
1123 | | |
1124 | 0 | return be16_to_cpu(ent->end_time.fine); |
1125 | 0 | } |
1126 | | |
1127 | | |
1128 | | /** |
1129 | | * @brief get data_type from the compression entity header |
1130 | | * |
1131 | | * @param ent pointer to a compression entity |
1132 | | * |
1133 | | * @returns the data_type NOT including the uncompressed data bit on success, |
1134 | | * DATA_TYPE_UNKNOWN on error |
1135 | | */ |
1136 | | |
1137 | | enum cmp_data_type cmp_ent_get_data_type(const struct cmp_entity *ent) |
1138 | 0 | { |
1139 | 0 | enum cmp_data_type data_type; |
1140 | |
|
1141 | 0 | if (!ent) |
1142 | 0 | return DATA_TYPE_UNKNOWN; |
1143 | | |
1144 | 0 | data_type = be16_to_cpu(ent->data_type); |
1145 | 0 | data_type &= (1U << RAW_BIT_DATA_TYPE_POS)-1; /* remove uncompressed data flag */ |
1146 | |
|
1147 | 0 | if (cmp_data_type_is_invalid(data_type)) |
1148 | 0 | data_type = DATA_TYPE_UNKNOWN; |
1149 | |
|
1150 | 0 | return data_type; |
1151 | 0 | } |
1152 | | |
1153 | | |
1154 | | /** |
1155 | | * @brief get the raw bit from the data_type field of the compression entity header |
1156 | | * |
1157 | | * @param ent pointer to a compression entity |
1158 | | * |
1159 | | * @returns the data_type raw bit on success, 0 on error |
1160 | | */ |
1161 | | |
1162 | | int cmp_ent_get_data_type_raw_bit(const struct cmp_entity *ent) |
1163 | 0 | { |
1164 | 0 | if (!ent) |
1165 | 0 | return 0; |
1166 | | |
1167 | 0 | return (be16_to_cpu(ent->data_type) >> RAW_BIT_DATA_TYPE_POS) & 1U; |
1168 | 0 | } |
1169 | | |
1170 | | |
1171 | | /** |
1172 | | * @brief get the used compression mode parameter from the compression entity header |
1173 | | * |
1174 | | * @param ent pointer to a compression entity |
1175 | | * |
1176 | | * @returns the used compression mode on success, 0 on error |
1177 | | */ |
1178 | | |
1179 | | uint8_t cmp_ent_get_cmp_mode(const struct cmp_entity *ent) |
1180 | 0 | { |
1181 | 0 | if (!ent) |
1182 | 0 | return 0; |
1183 | | |
1184 | 0 | return ent->cmp_mode_used; |
1185 | 0 | } |
1186 | | |
1187 | | |
1188 | | /** |
1189 | | * @brief get used model value from the compression entity header |
1190 | | * |
1191 | | * @param ent pointer to a compression entity |
1192 | | * |
1193 | | * @returns the used model value used on success, 0 on error |
1194 | | */ |
1195 | | |
1196 | | uint8_t cmp_ent_get_model_value(const struct cmp_entity *ent) |
1197 | 0 | { |
1198 | 0 | if (!ent) |
1199 | 0 | return 0; |
1200 | | |
1201 | 0 | return ent->model_value_used; |
1202 | |
|
1203 | 0 | } |
1204 | | |
1205 | | |
1206 | | /** |
1207 | | * @brief get model id from the compression entity header |
1208 | | * |
1209 | | * @param ent pointer to a compression entity |
1210 | | * |
1211 | | * @returns the model identifier on success, 0 on error |
1212 | | */ |
1213 | | |
1214 | | uint16_t cmp_ent_get_model_id(const struct cmp_entity *ent) |
1215 | 0 | { |
1216 | 0 | if (!ent) |
1217 | 0 | return 0; |
1218 | | |
1219 | 0 | return be16_to_cpu(ent->model_id); |
1220 | 0 | } |
1221 | | |
1222 | | |
1223 | | /** |
1224 | | * @brief get the model counter from the compression entity header |
1225 | | * |
1226 | | * @param ent pointer to a compression entity |
1227 | | * |
1228 | | * @returns the model counter on success, 0 on error |
1229 | | */ |
1230 | | |
1231 | | uint8_t cmp_ent_get_model_counter(const struct cmp_entity *ent) |
1232 | 0 | { |
1233 | 0 | if (!ent) |
1234 | 0 | return 0; |
1235 | | |
1236 | 0 | return ent->model_counter; |
1237 | 0 | } |
1238 | | |
1239 | | |
1240 | | /** |
1241 | | * @brief get the reserved field from the compression entity header |
1242 | | * |
1243 | | * @param ent pointer to a compression entity |
1244 | | * |
1245 | | * @returns the reserved filed on success, 0 on error |
1246 | | */ |
1247 | | |
1248 | | uint8_t cmp_ent_get_reserved(const struct cmp_entity *ent) |
1249 | 0 | { |
1250 | 0 | if (!ent) |
1251 | 0 | return 0; |
1252 | | |
1253 | 0 | return ent->reserved; |
1254 | 0 | } |
1255 | | |
1256 | | |
1257 | | /** |
1258 | | * @brief get the used lossy compression parameter from the compression entity header |
1259 | | * |
1260 | | * @param ent pointer to a compression entity |
1261 | | * |
1262 | | * @returns the used lossy compression/round parameter on success, 0 on error |
1263 | | */ |
1264 | | |
1265 | | uint16_t cmp_ent_get_lossy_cmp_par(const struct cmp_entity *ent) |
1266 | 0 | { |
1267 | 0 | if (!ent) |
1268 | 0 | return 0; |
1269 | | |
1270 | 0 | return be16_to_cpu(ent->lossy_cmp_par_used); |
1271 | 0 | } |
1272 | | |
1273 | | |
1274 | | /** |
1275 | | * @brief get the used spillover threshold parameter from the (adaptive) |
1276 | | * imagette specific compression entity header |
1277 | | * |
1278 | | * @param ent pointer to a compression entity |
1279 | | * |
1280 | | * @returns the used spillover threshold on success, 0 on error |
1281 | | */ |
1282 | | |
1283 | | uint16_t cmp_ent_get_ima_spill(const struct cmp_entity *ent) |
1284 | 0 | { |
1285 | 0 | if (!ent) |
1286 | 0 | return 0; |
1287 | | |
1288 | 0 | return be16_to_cpu(ent->ima.spill_used); |
1289 | 0 | } |
1290 | | |
1291 | | |
1292 | | /** |
1293 | | * @brief get the used Golomb parameter from the (adaptive) imagette specific |
1294 | | * compression entity header |
1295 | | * |
1296 | | * @param ent pointer to a compression entity |
1297 | | * |
1298 | | * @returns the used Golomb parameter on success, 0 on error |
1299 | | */ |
1300 | | |
1301 | | uint8_t cmp_ent_get_ima_golomb_par(const struct cmp_entity *ent) |
1302 | 0 | { |
1303 | 0 | if (!ent) |
1304 | 0 | return 0; |
1305 | | |
1306 | 0 | return ent->ima.golomb_par_used; |
1307 | 0 | } |
1308 | | |
1309 | | |
1310 | | /** |
1311 | | * @brief get the used adaptive 1 spillover threshold parameter from the |
1312 | | * adaptive imagette specific compression entity header |
1313 | | * |
1314 | | * @param ent pointer to a compression entity |
1315 | | * |
1316 | | * @returns the used adaptive 1 spillover threshold on success, 0 on error |
1317 | | */ |
1318 | | |
1319 | | uint16_t cmp_ent_get_ima_ap1_spill(const struct cmp_entity *ent) |
1320 | 0 | { |
1321 | 0 | if (!ent) |
1322 | 0 | return 0; |
1323 | | |
1324 | 0 | return be16_to_cpu(ent->ima.ap1_spill_used); |
1325 | 0 | } |
1326 | | |
1327 | | |
1328 | | /** |
1329 | | * @brief get the used adaptive 1 Golomb parameter from adaptive imagette |
1330 | | * specific compression entity header |
1331 | | * |
1332 | | * @param ent pointer to a compression entity |
1333 | | * |
1334 | | * @returns the used adaptive 1 Golomb parameter on success, 0 on error |
1335 | | */ |
1336 | | |
1337 | | uint8_t cmp_ent_get_ima_ap1_golomb_par(const struct cmp_entity *ent) |
1338 | 0 | { |
1339 | 0 | if (!ent) |
1340 | 0 | return 0; |
1341 | | |
1342 | 0 | return ent->ima.ap1_golomb_par_used; |
1343 | 0 | } |
1344 | | |
1345 | | |
1346 | | /** |
1347 | | * @brief get the used adaptive 2 spillover threshold parameter from the |
1348 | | * adaptive imagette specific compression entity header |
1349 | | * |
1350 | | * @param ent pointer to a compression entity |
1351 | | * |
1352 | | * @returns the used adaptive 2 spillover threshold on success, 0 on error |
1353 | | */ |
1354 | | |
1355 | | uint16_t cmp_ent_get_ima_ap2_spill(const struct cmp_entity *ent) |
1356 | 0 | { |
1357 | 0 | if (!ent) |
1358 | 0 | return 0; |
1359 | | |
1360 | 0 | return be16_to_cpu(ent->ima.ap2_spill_used); |
1361 | 0 | } |
1362 | | |
1363 | | |
1364 | | /** |
1365 | | * @brief get the used adaptive 2 spillover threshold parameter from the |
1366 | | * adaptive imagette specific compression entity header |
1367 | | * |
1368 | | * @param ent pointer to a compression entity |
1369 | | * |
1370 | | * @returns the used adaptive 2 Golomb parameter on success, 0 on error |
1371 | | */ |
1372 | | |
1373 | | uint8_t cmp_ent_get_ima_ap2_golomb_par(const struct cmp_entity *ent) |
1374 | 0 | { |
1375 | 0 | if (!ent) |
1376 | 0 | return 0; |
1377 | | |
1378 | 0 | return ent->ima.ap2_golomb_par_used; |
1379 | 0 | } |
1380 | | |
1381 | | |
1382 | | /** |
1383 | | * @brief get the used spillover threshold 1 parameter from the non-imagette |
1384 | | * specific compression entity header |
1385 | | * |
1386 | | * @param ent pointer to a compression entity |
1387 | | * |
1388 | | * @returns the used spillover threshold 1 parameter on success, 0 on error |
1389 | | */ |
1390 | | |
1391 | | uint32_t cmp_ent_get_non_ima_spill1(const struct cmp_entity *ent) |
1392 | 0 | { |
1393 | 0 | if (!ent) |
1394 | 0 | return 0; |
1395 | | |
1396 | 0 | #ifdef __LITTLE_ENDIAN |
1397 | 0 | return be32_to_cpu(ent->non_ima.spill_1_used) >> 8; |
1398 | | #else |
1399 | | return ent->non_ima.spill_1_used; |
1400 | | #endif /* __LITTLE_ENDIAN */ |
1401 | 0 | } |
1402 | | |
1403 | | |
1404 | | /** |
1405 | | * @brief get the used compression parameter 1 from the non-imagette specific |
1406 | | * compression entity header |
1407 | | * |
1408 | | * @param ent pointer to a compression entity |
1409 | | * |
1410 | | * @returns the used compression parameter 1 on success, 0 on error |
1411 | | */ |
1412 | | |
1413 | | uint16_t cmp_ent_get_non_ima_cmp_par1(const struct cmp_entity *ent) |
1414 | 0 | { |
1415 | 0 | if (!ent) |
1416 | 0 | return 0; |
1417 | | |
1418 | 0 | return be16_to_cpu(ent->non_ima.cmp_par_1_used); |
1419 | 0 | } |
1420 | | |
1421 | | |
1422 | | /** |
1423 | | * @brief get the used spillover threshold 2 parameter from the non-imagette |
1424 | | * specific compression entity header |
1425 | | * |
1426 | | * @param ent pointer to a compression entity |
1427 | | * |
1428 | | * @returns the used spillover threshold 2 parameter on success, 0 on error |
1429 | | */ |
1430 | | |
1431 | | uint32_t cmp_ent_get_non_ima_spill2(const struct cmp_entity *ent) |
1432 | 0 | { |
1433 | 0 | if (!ent) |
1434 | 0 | return 0; |
1435 | | |
1436 | 0 | #ifdef __LITTLE_ENDIAN |
1437 | 0 | return be32_to_cpu(ent->non_ima.spill_2_used) >> 8; |
1438 | | #else |
1439 | | return ent->non_ima.spill_2_used; |
1440 | | #endif /* __LITTLE_ENDIAN */ |
1441 | 0 | } |
1442 | | |
1443 | | |
1444 | | /** |
1445 | | * @brief get the used compression parameter 2 from the non-imagette specific |
1446 | | * compression entity header |
1447 | | * |
1448 | | * @param ent pointer to a compression entity |
1449 | | * |
1450 | | * @returns the used compression parameter 2 on success, 0 on error |
1451 | | */ |
1452 | | |
1453 | | uint16_t cmp_ent_get_non_ima_cmp_par2(const struct cmp_entity *ent) |
1454 | 0 | { |
1455 | 0 | if (!ent) |
1456 | 0 | return 0; |
1457 | | |
1458 | 0 | return be16_to_cpu(ent->non_ima.cmp_par_2_used); |
1459 | 0 | } |
1460 | | |
1461 | | |
1462 | | /** |
1463 | | * @brief get the used spillover threshold 3 parameter from the non-imagette |
1464 | | * specific compression entity header |
1465 | | * |
1466 | | * @param ent pointer to a compression entity |
1467 | | * |
1468 | | * @returns the used spillover threshold 3 parameter on success, 0 on error |
1469 | | */ |
1470 | | |
1471 | | uint32_t cmp_ent_get_non_ima_spill3(const struct cmp_entity *ent) |
1472 | 0 | { |
1473 | 0 | if (!ent) |
1474 | 0 | return 0; |
1475 | | |
1476 | 0 | #ifdef __LITTLE_ENDIAN |
1477 | 0 | return be32_to_cpu(ent->non_ima.spill_3_used) >> 8; |
1478 | | #else |
1479 | | return ent->non_ima.spill_3_used; |
1480 | | #endif /* __LITTLE_ENDIAN */ |
1481 | 0 | } |
1482 | | |
1483 | | |
1484 | | /** |
1485 | | * @brief get the used compression parameter 3 from the non-imagette specific |
1486 | | * compression entity header |
1487 | | * |
1488 | | * @param ent pointer to a compression entity |
1489 | | * |
1490 | | * @returns the used compression parameter 3 on success, 0 on error |
1491 | | */ |
1492 | | |
1493 | | uint16_t cmp_ent_get_non_ima_cmp_par3(const struct cmp_entity *ent) |
1494 | 0 | { |
1495 | 0 | if (!ent) |
1496 | 0 | return 0; |
1497 | | |
1498 | 0 | return be16_to_cpu(ent->non_ima.cmp_par_3_used); |
1499 | 0 | } |
1500 | | |
1501 | | |
1502 | | /** |
1503 | | * @brief get the used spillover threshold 4 parameter from the non-imagette |
1504 | | * specific compression entity header |
1505 | | * |
1506 | | * @param ent pointer to a compression entity |
1507 | | * |
1508 | | * @returns the used spillover threshold 4 parameter on success, 0 on error |
1509 | | */ |
1510 | | |
1511 | | uint32_t cmp_ent_get_non_ima_spill4(const struct cmp_entity *ent) |
1512 | 0 | { |
1513 | 0 | if (!ent) |
1514 | 0 | return 0; |
1515 | | |
1516 | 0 | #ifdef __LITTLE_ENDIAN |
1517 | 0 | return be32_to_cpu(ent->non_ima.spill_4_used) >> 8; |
1518 | | #else |
1519 | | return ent->non_ima.spill_4_used; |
1520 | | #endif /* __LITTLE_ENDIAN */ |
1521 | 0 | } |
1522 | | |
1523 | | |
1524 | | /** |
1525 | | * @brief get the used compression parameter 4 from the non-imagette specific |
1526 | | * compression entity header |
1527 | | * |
1528 | | * @param ent pointer to a compression entity |
1529 | | * |
1530 | | * @returns the used compression parameter 4 on success, 0 on error |
1531 | | */ |
1532 | | |
1533 | | uint16_t cmp_ent_get_non_ima_cmp_par4(const struct cmp_entity *ent) |
1534 | 0 | { |
1535 | 0 | if (!ent) |
1536 | 0 | return 0; |
1537 | | |
1538 | 0 | return be16_to_cpu(ent->non_ima.cmp_par_4_used); |
1539 | 0 | } |
1540 | | |
1541 | | |
1542 | | /** |
1543 | | * @brief get the used spillover threshold 5 parameter from the non-imagette |
1544 | | * specific compression entity header |
1545 | | * |
1546 | | * @param ent pointer to a compression entity |
1547 | | * |
1548 | | * @returns the used spillover threshold 5 parameter on success, 0 on error |
1549 | | */ |
1550 | | |
1551 | | uint32_t cmp_ent_get_non_ima_spill5(const struct cmp_entity *ent) |
1552 | 0 | { |
1553 | 0 | if (!ent) |
1554 | 0 | return 0; |
1555 | | |
1556 | 0 | #ifdef __LITTLE_ENDIAN |
1557 | 0 | return be32_to_cpu(ent->non_ima.spill_5_used) >> 8; |
1558 | | #else |
1559 | | return ent->non_ima.spill_5_used; |
1560 | | #endif /* __LITTLE_ENDIAN */ |
1561 | 0 | } |
1562 | | |
1563 | | |
1564 | | /** |
1565 | | * @brief get the used compression parameter 5 from the non-imagette specific |
1566 | | * compression entity header |
1567 | | * |
1568 | | * @param ent pointer to a compression entity |
1569 | | * |
1570 | | * @returns the used compression parameter 5 on success, 0 on error |
1571 | | */ |
1572 | | |
1573 | | uint16_t cmp_ent_get_non_ima_cmp_par5(const struct cmp_entity *ent) |
1574 | 0 | { |
1575 | 0 | if (!ent) |
1576 | 0 | return 0; |
1577 | | |
1578 | 0 | return be16_to_cpu(ent->non_ima.cmp_par_5_used); |
1579 | 0 | } |
1580 | | |
1581 | | |
1582 | | /** |
1583 | | * @brief get the used spillover threshold 6 parameter from the non-imagette |
1584 | | * specific compression entity header |
1585 | | * |
1586 | | * @param ent pointer to a compression entity |
1587 | | * |
1588 | | * @returns the used spillover threshold 6 parameter on success, 0 on error |
1589 | | */ |
1590 | | |
1591 | | uint32_t cmp_ent_get_non_ima_spill6(const struct cmp_entity *ent) |
1592 | 0 | { |
1593 | 0 | if (!ent) |
1594 | 0 | return 0; |
1595 | | |
1596 | 0 | #ifdef __LITTLE_ENDIAN |
1597 | 0 | return be32_to_cpu(ent->non_ima.spill_6_used) >> 8; |
1598 | | #else |
1599 | | return ent->non_ima.spill_6_used; |
1600 | | #endif /* __LITTLE_ENDIAN */ |
1601 | 0 | } |
1602 | | |
1603 | | |
1604 | | /** |
1605 | | * @brief get the used compression parameter 6 from the non-imagette specific |
1606 | | * compression entity header |
1607 | | * |
1608 | | * @param ent pointer to a compression entity |
1609 | | * |
1610 | | * @returns the used compression parameter 6 on success, 0 on error |
1611 | | */ |
1612 | | |
1613 | | uint16_t cmp_ent_get_non_ima_cmp_par6(const struct cmp_entity *ent) |
1614 | 0 | { |
1615 | 0 | if (!ent) |
1616 | 0 | return 0; |
1617 | | |
1618 | 0 | return be16_to_cpu(ent->non_ima.cmp_par_6_used); |
1619 | 0 | } |
1620 | | |
1621 | | |
1622 | | /** |
1623 | | * @brief copy the data from a compression entity to a buffer |
1624 | | * |
1625 | | * @param ent pointer to the compression entity containing the compressed data |
1626 | | * @param data_buf pointer to the destination data buffer to which the |
1627 | | * compressed data are copied (can be NULL) |
1628 | | * @param data_buf_size size of the destination data buffer |
1629 | | * |
1630 | | * @returns the size in bytes to store the compressed data; negative on error |
1631 | | * |
1632 | | * @note converts the data to the system endianness |
1633 | | */ |
1634 | | |
1635 | | int32_t cmp_ent_get_cmp_data(struct cmp_entity *ent, uint32_t *data_buf, |
1636 | | uint32_t data_buf_size) |
1637 | 0 | { |
1638 | 0 | uint32_t *cmp_ent_data_adr; |
1639 | 0 | uint32_t cmp_size_byte; |
1640 | |
|
1641 | 0 | if (!ent) |
1642 | 0 | return -1; |
1643 | | |
1644 | 0 | cmp_ent_data_adr = cmp_ent_get_data_buf(ent); |
1645 | 0 | if (!cmp_ent_data_adr) { |
1646 | 0 | debug_print("Error: Compression data type is not supported."); |
1647 | 0 | return -1; |
1648 | 0 | } |
1649 | | |
1650 | 0 | cmp_size_byte = cmp_ent_get_cmp_data_size(ent); |
1651 | 0 | if (cmp_size_byte & 0x3) { |
1652 | 0 | debug_print("Error: The compressed data are not correct formatted. Expected multiple of 4 hex words."); |
1653 | 0 | return -1; |
1654 | 0 | } |
1655 | | |
1656 | 0 | if (data_buf) { |
1657 | 0 | uint32_t i; |
1658 | 0 | uint32_t cmp_data_len_32; |
1659 | |
|
1660 | 0 | if (cmp_size_byte > data_buf_size) { |
1661 | 0 | debug_print("Error: data_buf size to small to hold the data."); |
1662 | 0 | return -1; |
1663 | 0 | } |
1664 | | |
1665 | 0 | memcpy(data_buf, cmp_ent_data_adr, cmp_size_byte); |
1666 | |
|
1667 | 0 | cmp_data_len_32 = cmp_size_byte/sizeof(uint32_t); |
1668 | 0 | for (i = 0; i < cmp_data_len_32; i++) |
1669 | 0 | be32_to_cpus(&data_buf[i]); |
1670 | 0 | } |
1671 | | |
1672 | 0 | return (int32_t)cmp_size_byte; |
1673 | 0 | } |
1674 | | |
1675 | | |
1676 | | /** |
1677 | | * @brief get the size of the compression entity header based on the set data |
1678 | | * product type in compression entity |
1679 | | * |
1680 | | * @param ent pointer to a compression entity |
1681 | | * |
1682 | | * @returns the size of the entity header in bytes on success, 0 on error |
1683 | | */ |
1684 | | |
1685 | | static uint32_t cmp_ent_get_hdr_size(const struct cmp_entity *ent) |
1686 | 0 | { |
1687 | 0 | return cmp_ent_cal_hdr_size(cmp_ent_get_data_type(ent), |
1688 | 0 | cmp_ent_get_data_type_raw_bit(ent)); |
1689 | 0 | } |
1690 | | |
1691 | | |
1692 | | /** |
1693 | | * @brief get the start address of the compressed data in the compression |
1694 | | * entity |
1695 | | * |
1696 | | * @param ent pointer to a compression entity |
1697 | | * |
1698 | | * @note this only works if the data_type in the compression entity is set |
1699 | | * |
1700 | | * @returns a pointer to the location where the compressed data are located in entity |
1701 | | * on success, NULL on error |
1702 | | */ |
1703 | | |
1704 | | void *cmp_ent_get_data_buf(struct cmp_entity *ent) |
1705 | 0 | { |
1706 | 0 | uint32_t hdr_size = cmp_ent_get_hdr_size(ent); |
1707 | 0 | if (!hdr_size) |
1708 | 0 | return NULL; |
1709 | 0 | return (uint8_t *)ent + hdr_size; |
1710 | 0 | } |
1711 | | |
1712 | | |
1713 | | /** |
1714 | | * @brief same as cmp_ent_get_data_buf but with const pointers |
1715 | | * |
1716 | | * @param ent const pointer to a compression entity |
1717 | | * |
1718 | | * @note this only works if the data_type in the compression entity is set |
1719 | | * |
1720 | | * @returns a const pointer to the location where the compressed data are located |
1721 | | * in entity on success, NULL on error |
1722 | | */ |
1723 | | |
1724 | | const void *cmp_ent_get_data_buf_const(const struct cmp_entity *ent) |
1725 | 0 | { |
1726 | 0 | uint32_t hdr_size = cmp_ent_get_hdr_size(ent); |
1727 | 0 | if (!hdr_size) |
1728 | 0 | return NULL; |
1729 | 0 | return (const uint8_t *)ent + hdr_size; |
1730 | 0 | } |
1731 | | |
1732 | | |
1733 | | /** |
1734 | | * @brief get the size of the compressed data based on the set data product |
1735 | | * type and compressed entity size in the compression entity |
1736 | | * |
1737 | | * @param ent pointer to a compression entity |
1738 | | * |
1739 | | * @returns the size of the compressed data in bytes on success, 0 on error |
1740 | | */ |
1741 | | |
1742 | | uint32_t cmp_ent_get_cmp_data_size(const struct cmp_entity *ent) |
1743 | 0 | { |
1744 | 0 | uint32_t cmp_ent_size, header_size; |
1745 | |
|
1746 | 0 | header_size = cmp_ent_get_hdr_size(ent); |
1747 | 0 | cmp_ent_size = cmp_ent_get_size(ent); |
1748 | |
|
1749 | 0 | if (header_size > cmp_ent_size) |
1750 | 0 | return 0; |
1751 | | |
1752 | 0 | return cmp_ent_size - header_size; |
1753 | 0 | } |
1754 | | |
1755 | | |
1756 | | /** |
1757 | | * @brief write the parameters from the RDCU decompression information structure |
1758 | | * in the compression entity header |
1759 | | * @note no compressed data are put into the entity and no change of the entity |
1760 | | * size |
1761 | | * |
1762 | | * @param ent pointer to a compression entity |
1763 | | * @param info pointer to a decompression information structure |
1764 | | * @param rcfg pointer to a RDCU compression configuration structure for |
1765 | | * adaptive compression parameters (can be NULL if non adaptive data_type |
1766 | | * is used) |
1767 | | * |
1768 | | * @returns 0 on success, negative on error |
1769 | | */ |
1770 | | |
1771 | | int cmp_ent_write_rdcu_cmp_pars(struct cmp_entity *ent, const struct cmp_info *info, |
1772 | | const struct rdcu_cfg *rcfg) |
1773 | 0 | { |
1774 | 0 | uint32_t ent_cmp_data_size; |
1775 | 0 | enum cmp_data_type data_type; |
1776 | |
|
1777 | 0 | if (!ent) |
1778 | 0 | return -1; |
1779 | | |
1780 | 0 | if (!info) |
1781 | 0 | return -1; |
1782 | | |
1783 | 0 | if (info->cmp_err) { |
1784 | 0 | debug_print("Error: The decompression information contains an compression error."); |
1785 | 0 | return -1; |
1786 | 0 | } |
1787 | | |
1788 | 0 | data_type = cmp_ent_get_data_type(ent); |
1789 | 0 | if (!rdcu_supported_data_type_is_used(data_type)) { |
1790 | 0 | debug_print("Error: The compression data type is not one of the types supported by the RDCU."); |
1791 | 0 | return -1; |
1792 | 0 | } |
1793 | | |
1794 | 0 | if (cmp_ent_get_data_type_raw_bit(ent) != raw_mode_is_used(info->cmp_mode_used)) { |
1795 | 0 | debug_print("Error: The entity's raw data bit does not match up with the compression mode."); |
1796 | 0 | return -1; |
1797 | 0 | } |
1798 | | |
1799 | | /* check if the entity can hold the compressed data */ |
1800 | 0 | ent_cmp_data_size = cmp_ent_get_cmp_data_size(ent); |
1801 | 0 | if (ent_cmp_data_size < cmp_bit_to_byte(info->cmp_size)) { |
1802 | 0 | debug_print("Error: The entity size is to small to hold the compressed data."); |
1803 | 0 | return -2; |
1804 | 0 | } |
1805 | | |
1806 | | /* set compression parameter fields in the generic entity header */ |
1807 | 0 | if (cmp_ent_set_original_size(ent, info->samples_used * sizeof(uint16_t))) |
1808 | 0 | return -1; |
1809 | 0 | if (cmp_ent_set_cmp_mode(ent, info->cmp_mode_used)) |
1810 | 0 | return -1; |
1811 | 0 | cmp_ent_set_model_value(ent, info->model_value_used); |
1812 | |
|
1813 | 0 | cmp_ent_set_reserved(ent, 0); |
1814 | |
|
1815 | 0 | cmp_ent_set_lossy_cmp_par(ent, info->round_used); |
1816 | |
|
1817 | 0 | if (raw_mode_is_used(info->cmp_mode_used)) |
1818 | | /* no specific header is used for raw data we are done */ |
1819 | 0 | return 0; |
1820 | | |
1821 | 0 | if (cmp_ent_set_ima_spill(ent, info->spill_used)) |
1822 | 0 | return -1; |
1823 | 0 | if (cmp_ent_set_ima_golomb_par(ent, info->golomb_par_used)) |
1824 | 0 | return -1; |
1825 | | |
1826 | | /* use the adaptive imagette parameter from the compression configuration |
1827 | | * if an adaptive imagette compression data type is ent in the entity |
1828 | | */ |
1829 | 0 | if (cmp_ap_imagette_data_type_is_used(data_type)) { |
1830 | 0 | if (!rcfg) { |
1831 | 0 | debug_print("Error: Need the compression configuration to get the adaptive parameters."); |
1832 | 0 | return -1; |
1833 | 0 | } |
1834 | 0 | if (cmp_ent_set_ima_ap1_spill(ent, rcfg->ap1_spill)) |
1835 | 0 | return -1; |
1836 | 0 | if (cmp_ent_set_ima_ap1_golomb_par(ent, rcfg->ap1_golomb_par)) |
1837 | 0 | return -1; |
1838 | 0 | if (cmp_ent_set_ima_ap2_spill(ent, rcfg->ap2_spill)) |
1839 | 0 | return -1; |
1840 | 0 | if (cmp_ent_set_ima_ap2_golomb_par(ent, rcfg->ap2_golomb_par)) |
1841 | 0 | return -1; |
1842 | 0 | } |
1843 | | |
1844 | 0 | return 0; |
1845 | 0 | } |
1846 | | |
1847 | | |
1848 | | /** |
1849 | | * @brief create a compression entity by setting the size of the compression |
1850 | | * entity and the data product type in the entity header |
1851 | | * |
1852 | | * @param ent pointer to a compression entity; if NULL, the function |
1853 | | * returns the needed size |
1854 | | * @param data_type compression data product type |
1855 | | * @param raw_mode_flag set this flag if the raw compression mode (CMP_MODE_RAW) is used |
1856 | | * @param cmp_size_byte size of the compressed data in bytes (should be a multiple of 4) |
1857 | | * |
1858 | | * @note if the entity size is smaller than the largest header, the function |
1859 | | * rounds up the entity size to the largest header |
1860 | | * |
1861 | | * @returns the size of the compression entity or 0 on error |
1862 | | */ |
1863 | | |
1864 | | uint32_t cmp_ent_create(struct cmp_entity *ent, enum cmp_data_type data_type, |
1865 | | int raw_mode_flag, uint32_t cmp_size_byte) |
1866 | 0 | { |
1867 | 0 | uint32_t hdr_size = cmp_ent_cal_hdr_size(data_type, raw_mode_flag); |
1868 | 0 | uint32_t ent_size = hdr_size + cmp_size_byte; |
1869 | 0 | uint32_t ent_size_cpy = ent_size; |
1870 | |
|
1871 | 0 | if (!hdr_size) |
1872 | 0 | return 0; |
1873 | | |
1874 | | /* catch overflows */ |
1875 | 0 | if (cmp_size_byte > CMP_ENTITY_MAX_SIZE) |
1876 | 0 | return 0; |
1877 | 0 | if (ent_size > CMP_ENTITY_MAX_SIZE) |
1878 | 0 | return 0; |
1879 | | |
1880 | | /* to be safe a compression entity should be at least the size of the |
1881 | | * largest entity header */ |
1882 | 0 | if (ent_size < sizeof(struct cmp_entity)) |
1883 | 0 | ent_size = sizeof(struct cmp_entity); |
1884 | |
|
1885 | 0 | if (!ent) |
1886 | 0 | return ent_size; |
1887 | | |
1888 | 0 | memset(ent, 0, hdr_size); |
1889 | |
|
1890 | 0 | cmp_ent_set_size(ent, ent_size_cpy); |
1891 | 0 | cmp_ent_set_data_type(ent, data_type, raw_mode_flag); |
1892 | |
|
1893 | 0 | return ent_size; |
1894 | 0 | } |
1895 | | |
1896 | | |
1897 | | #ifdef HAS_TIME_H |
1898 | | /** |
1899 | | * @brief Convert a calendar time expressed as a struct tm object to time since |
1900 | | * epoch as a time_t object. The function interprets the input structure |
1901 | | * as representing Universal Coordinated Time (UTC). |
1902 | | * @note timegm is a GNU C Library extension, not standardized. This function |
1903 | | * is used as a portable alternative |
1904 | | * @note The function is thread-unsafe |
1905 | | * |
1906 | | * @param tm pointer to a broken-down time representation, expressed in |
1907 | | * Coordinated Universal Time (UTC) |
1908 | | * |
1909 | | * @returns time since epoch as a time_t object on success; or -1 if time cannot |
1910 | | * be represented as a time_t object |
1911 | | * |
1912 | | * @see http://www.catb.org/esr/time-programming/#_unix_time_and_utc_gmt_zulu |
1913 | | */ |
1914 | | |
1915 | | static time_t my_timegm(struct tm *tm) |
1916 | 0 | { |
1917 | | # if defined(_WIN32) || defined(_WIN64) |
1918 | | return _mkgmtime(tm); |
1919 | | # else |
1920 | 0 | time_t ret; |
1921 | 0 | char *tz; |
1922 | |
|
1923 | 0 | tz = getenv("TZ"); |
1924 | 0 | if (tz) |
1925 | 0 | tz = strdup(tz); |
1926 | 0 | setenv("TZ", "", 1); |
1927 | 0 | tzset(); |
1928 | 0 | ret = mktime(tm); |
1929 | 0 | if (tz) { |
1930 | 0 | setenv("TZ", tz, 1); |
1931 | 0 | free(tz); |
1932 | 0 | } else |
1933 | 0 | unsetenv("TZ"); |
1934 | 0 | tzset(); |
1935 | 0 | return ret; |
1936 | 0 | # endif /* _WIN32 || _WIN64 */ |
1937 | 0 | } |
1938 | | #endif /* HAS_TIME_H */ |
1939 | | |
1940 | | |
1941 | | #ifdef HAS_TIME_H |
1942 | | /** |
1943 | | * @brief Generate a timestamp for the compression header |
1944 | | * |
1945 | | * @param ts pointer to an object of type struct timespec of the |
1946 | | * timestamp time, NULL for now |
1947 | | * |
1948 | | * @returns returns compression header timestamp or 0 on error |
1949 | | */ |
1950 | | |
1951 | | uint64_t cmp_ent_create_timestamp(const struct timespec *ts) |
1952 | 0 | { |
1953 | 0 | struct tm epoch_date = PLATO_EPOCH_DATE; |
1954 | 0 | struct timespec epoch = {0, 0 }; |
1955 | 0 | struct timespec now = { 0, 0 }; |
1956 | 0 | double seconds; |
1957 | 0 | uint64_t coarse, fine; |
1958 | |
|
1959 | 0 | epoch.tv_sec = my_timegm(&epoch_date); |
1960 | | |
1961 | | /* LCOV_EXCL_START */ |
1962 | | /* if time cannot be represented as a time_t object epoch.tv_sec = -1 */ |
1963 | 0 | if (epoch.tv_sec == -1) |
1964 | 0 | return 0; |
1965 | | /* LCOV_EXCL_STOP */ |
1966 | | |
1967 | 0 | if (ts) { |
1968 | 0 | if (my_timercmp(ts, &epoch, <)) { |
1969 | 0 | debug_print("Error: Time is before PLATO epoch."); |
1970 | 0 | return 0; |
1971 | 0 | } |
1972 | 0 | now = *ts; |
1973 | 0 | } else { |
1974 | 0 | (void)clock_gettime(CLOCK_REALTIME, &now); |
1975 | 0 | } |
1976 | | |
1977 | 0 | seconds = ((double)now.tv_sec + 1.0e-9 * (double)now.tv_nsec) - |
1978 | 0 | ((double)epoch.tv_sec + 1.0e-9 * (double)epoch.tv_nsec); |
1979 | |
|
1980 | 0 | coarse = (uint64_t)seconds; |
1981 | 0 | fine = (uint64_t)((seconds - (double)coarse) * 256 * 256); |
1982 | |
|
1983 | 0 | return (coarse << 16) + fine; |
1984 | 0 | } |
1985 | | #endif /* HAS_TIME_H */ |
1986 | | |
1987 | | |
1988 | | /** |
1989 | | * @brief print the content of the compression entity header |
1990 | | * |
1991 | | * @param ent pointer to a compression entity |
1992 | | */ |
1993 | | |
1994 | | void cmp_ent_print_header(const struct cmp_entity *ent) |
1995 | 0 | { |
1996 | 0 | MAYBE_UNUSED const uint8_t *p = (const uint8_t *)ent; |
1997 | 0 | uint32_t hdr_size = cmp_ent_get_hdr_size(ent); |
1998 | 0 | size_t i; |
1999 | |
|
2000 | 0 | for (i = 0; i < hdr_size; ++i) |
2001 | 0 | debug_print("%02X", p[i]); |
2002 | 0 | } |
2003 | | |
2004 | | |
2005 | | /** |
2006 | | * @brief print the compressed data of the entity |
2007 | | * |
2008 | | * @param ent pointer to a compression entity |
2009 | | */ |
2010 | | |
2011 | | void cmp_ent_print_data(struct cmp_entity *ent) |
2012 | 0 | { |
2013 | 0 | const uint8_t *p = cmp_ent_get_data_buf(ent); |
2014 | 0 | size_t data_size = cmp_ent_get_cmp_data_size(ent); |
2015 | 0 | size_t i; |
2016 | |
|
2017 | 0 | if (!p) |
2018 | 0 | return; |
2019 | | |
2020 | 0 | for (i = 0; i < data_size; ++i) |
2021 | 0 | debug_print("%02X", p[i]); |
2022 | 0 | } |
2023 | | |
2024 | | |
2025 | | /** |
2026 | | * @brief print the entire compressed entity header plus data |
2027 | | * |
2028 | | * @param ent pointer to a compression entity |
2029 | | */ |
2030 | | |
2031 | | void cmp_ent_print(struct cmp_entity *ent) |
2032 | 0 | { |
2033 | 0 | debug_print("compression entity header:"); |
2034 | 0 | cmp_ent_print_header(ent); |
2035 | 0 | debug_print("compressed data in the compressed entity:"); |
2036 | 0 | cmp_ent_print_data(ent); |
2037 | 0 | } |
2038 | | |
2039 | | |
2040 | | /** |
2041 | | * @brief parses the generic compressed entity header |
2042 | | * |
2043 | | * @param ent pointer to a compression entity |
2044 | | */ |
2045 | | |
2046 | | static void cmp_ent_parse_generic_header(const struct cmp_entity *ent) |
2047 | 0 | { |
2048 | 0 | MAYBE_UNUSED uint32_t version_id, cmp_ent_size, original_size, cmp_mode_used, |
2049 | 0 | model_value_used, model_id, model_counter, reserved, |
2050 | 0 | lossy_cmp_par_used, start_coarse_time, end_coarse_time; |
2051 | 0 | MAYBE_UNUSED uint16_t start_fine_time, end_fine_time; |
2052 | 0 | MAYBE_UNUSED enum cmp_data_type data_type; |
2053 | 0 | MAYBE_UNUSED int raw_bit; |
2054 | |
|
2055 | 0 | version_id = cmp_ent_get_version_id(ent); |
2056 | 0 | if (version_id & CMP_TOOL_VERSION_ID_BIT) { |
2057 | 0 | MAYBE_UNUSED uint16_t major = (version_id & 0x7FFF0000U) >> 16U; |
2058 | 0 | MAYBE_UNUSED uint16_t minor = version_id & 0xFFFFU; |
2059 | |
|
2060 | 0 | debug_print("Compressed with cmp_tool version: %u.%02u", major, minor); |
2061 | 0 | } else |
2062 | 0 | debug_print("ICU ASW Version ID: 0x%08" PRIx32, version_id); |
2063 | |
|
2064 | 0 | cmp_ent_size = cmp_ent_get_size(ent); |
2065 | 0 | debug_print("Compression Entity Size: %" PRIu32 " byte", cmp_ent_size); |
2066 | |
|
2067 | 0 | original_size = cmp_ent_get_original_size(ent); |
2068 | 0 | debug_print("Original Data Size: %" PRIu32 " byte", original_size); |
2069 | |
|
2070 | 0 | start_coarse_time = cmp_ent_get_coarse_start_time(ent); |
2071 | 0 | debug_print("Compression Coarse Start Time: 0x%" PRIx32, start_coarse_time); |
2072 | |
|
2073 | 0 | start_fine_time = cmp_ent_get_fine_start_time(ent); |
2074 | 0 | debug_print("Compression Fine Start Time: 0x%x", start_fine_time); |
2075 | |
|
2076 | 0 | end_coarse_time = cmp_ent_get_coarse_end_time(ent); |
2077 | 0 | debug_print("Compression Coarse End Time: 0x%" PRIx32, end_coarse_time); |
2078 | |
|
2079 | 0 | end_fine_time = cmp_ent_get_fine_end_time(ent); |
2080 | 0 | debug_print("Compression Fine End Time: 0x%x", end_fine_time); |
2081 | |
|
2082 | 0 | #ifdef HAS_TIME_H |
2083 | 0 | { |
2084 | 0 | struct tm epoch_date = PLATO_EPOCH_DATE; |
2085 | 0 | MAYBE_UNUSED time_t time = my_timegm(&epoch_date) + start_coarse_time; |
2086 | |
|
2087 | 0 | debug_print("Data were compressed on (local time): %s", ctime(&time)); |
2088 | 0 | } |
2089 | 0 | #endif |
2090 | 0 | debug_print("The compression took %f second", end_coarse_time - start_coarse_time |
2091 | 0 | + ((end_fine_time - start_fine_time)/256./256.)); |
2092 | |
|
2093 | 0 | data_type = cmp_ent_get_data_type(ent); |
2094 | 0 | debug_print("Data Product Type: %d", data_type); |
2095 | |
|
2096 | 0 | raw_bit = cmp_ent_get_data_type_raw_bit(ent); |
2097 | 0 | debug_print("RAW bit in the Data Product Type is%s set", raw_bit ? "" : " not"); |
2098 | |
|
2099 | 0 | cmp_mode_used = cmp_ent_get_cmp_mode(ent); |
2100 | 0 | debug_print("Used Compression Mode: %" PRIu32, cmp_mode_used); |
2101 | |
|
2102 | 0 | model_value_used = cmp_ent_get_model_value(ent); |
2103 | 0 | debug_print("Used Model Updating Weighing Value: %" PRIu32, model_value_used); |
2104 | |
|
2105 | 0 | model_id = cmp_ent_get_model_id(ent); |
2106 | 0 | debug_print("Model ID: %" PRIu32, model_id); |
2107 | |
|
2108 | 0 | model_counter = cmp_ent_get_model_counter(ent); |
2109 | 0 | debug_print("Model Counter: %" PRIu32, model_counter); |
2110 | |
|
2111 | 0 | reserved = cmp_ent_get_reserved(ent); |
2112 | 0 | debug_print("Reserved Field: %" PRIu32, reserved); |
2113 | |
|
2114 | 0 | lossy_cmp_par_used = cmp_ent_get_lossy_cmp_par(ent); |
2115 | 0 | debug_print("Used Lossy Compression Parameters: %" PRIu32, lossy_cmp_par_used); |
2116 | 0 | } |
2117 | | |
2118 | | |
2119 | | /** |
2120 | | * @brief parse the imagette specific compressed entity header |
2121 | | * |
2122 | | * @param ent pointer to a compression entity |
2123 | | */ |
2124 | | |
2125 | | static void cmp_ent_parese_imagette_header(const struct cmp_entity *ent) |
2126 | 0 | { |
2127 | 0 | MAYBE_UNUSED uint32_t spill_used, golomb_par_used; |
2128 | |
|
2129 | 0 | spill_used = cmp_ent_get_ima_spill(ent); |
2130 | 0 | debug_print("Used Spillover Threshold Parameter: %" PRIu32, spill_used); |
2131 | |
|
2132 | 0 | golomb_par_used = cmp_ent_get_ima_golomb_par(ent); |
2133 | 0 | debug_print("Used Golomb Parameter: %" PRIu32, golomb_par_used); |
2134 | 0 | } |
2135 | | |
2136 | | |
2137 | | /** |
2138 | | * @brief parse the adaptive imagette specific compressed entity header |
2139 | | * |
2140 | | * @param ent pointer to a compression entity |
2141 | | */ |
2142 | | |
2143 | | static void cmp_ent_parese_adaptive_imagette_header(const struct cmp_entity *ent) |
2144 | 0 | { |
2145 | 0 | MAYBE_UNUSED uint32_t spill_used, golomb_par_used, ap1_spill_used, |
2146 | 0 | ap1_golomb_par_used, ap2_spill_used, ap2_golomb_par_used; |
2147 | |
|
2148 | 0 | spill_used = cmp_ent_get_ima_spill(ent); |
2149 | 0 | debug_print("Used Spillover Threshold Parameter: %" PRIu32, spill_used); |
2150 | |
|
2151 | 0 | golomb_par_used = cmp_ent_get_ima_golomb_par(ent); |
2152 | 0 | debug_print("Used Golomb Parameter: %" PRIu32, golomb_par_used); |
2153 | |
|
2154 | 0 | ap1_spill_used = cmp_ent_get_ima_ap1_spill(ent); |
2155 | 0 | debug_print("Used Adaptive 1 Spillover Threshold Parameter: %" PRIu32, ap1_spill_used); |
2156 | |
|
2157 | 0 | ap1_golomb_par_used = cmp_ent_get_ima_ap1_golomb_par(ent); |
2158 | 0 | debug_print("Used Adaptive 1 Golomb Parameter: %" PRIu32, ap1_golomb_par_used); |
2159 | |
|
2160 | 0 | ap2_spill_used = cmp_ent_get_ima_ap2_spill(ent); |
2161 | 0 | debug_print("Used Adaptive 2 Spillover Threshold Parameter: %" PRIu32, ap2_spill_used); |
2162 | |
|
2163 | 0 | ap2_golomb_par_used = cmp_ent_get_ima_ap2_golomb_par(ent); |
2164 | 0 | debug_print("Used Adaptive 2 Golomb Parameter: %" PRIu32, ap2_golomb_par_used); |
2165 | 0 | } |
2166 | | |
2167 | | |
2168 | | /** |
2169 | | * @brief parse the non-imagette specific compressed entity header |
2170 | | * |
2171 | | * @param ent pointer to a compression entity |
2172 | | */ |
2173 | | |
2174 | | static void cmp_ent_parese_non_imagette_header(const struct cmp_entity *ent) |
2175 | 0 | { |
2176 | 0 | MAYBE_UNUSED uint32_t spill_1_used, cmp_par_1_used, spill_2_used, cmp_par_2_used, |
2177 | 0 | spill_3_used, cmp_par_3_used, spill_4_used, cmp_par_4_used, |
2178 | 0 | spill_5_used, cmp_par_5_used; |
2179 | |
|
2180 | 0 | spill_1_used = cmp_ent_get_non_ima_spill1(ent); |
2181 | 0 | debug_print("Used Spillover Threshold Parameter 1: %" PRIu32, spill_1_used); |
2182 | |
|
2183 | 0 | cmp_par_1_used = cmp_ent_get_non_ima_cmp_par1(ent); |
2184 | 0 | debug_print("Used Compression Parameter 1: %" PRIu32, cmp_par_1_used); |
2185 | |
|
2186 | 0 | spill_2_used = cmp_ent_get_non_ima_spill2(ent); |
2187 | 0 | debug_print("Used Spillover Threshold Parameter 2: %" PRIu32, spill_2_used); |
2188 | |
|
2189 | 0 | cmp_par_2_used = cmp_ent_get_non_ima_cmp_par2(ent); |
2190 | 0 | debug_print("Used Compression Parameter 2: %" PRIu32, cmp_par_2_used); |
2191 | |
|
2192 | 0 | spill_3_used = cmp_ent_get_non_ima_spill3(ent); |
2193 | 0 | debug_print("Used Spillover Threshold Parameter 3: %" PRIu32, spill_3_used); |
2194 | |
|
2195 | 0 | cmp_par_3_used = cmp_ent_get_non_ima_cmp_par3(ent); |
2196 | 0 | debug_print("Used Compression Parameter 3: %" PRIu32, cmp_par_3_used); |
2197 | |
|
2198 | 0 | spill_4_used = cmp_ent_get_non_ima_spill4(ent); |
2199 | 0 | debug_print("Used Spillover Threshold Parameter 4: %" PRIu32, spill_4_used); |
2200 | |
|
2201 | 0 | cmp_par_4_used = cmp_ent_get_non_ima_cmp_par4(ent); |
2202 | 0 | debug_print("Used Compression Parameter 4: %" PRIu32, cmp_par_4_used); |
2203 | |
|
2204 | 0 | spill_5_used = cmp_ent_get_non_ima_spill5(ent); |
2205 | 0 | debug_print("Used Spillover Threshold Parameter 5: %" PRIu32, spill_5_used); |
2206 | |
|
2207 | 0 | cmp_par_5_used = cmp_ent_get_non_ima_cmp_par5(ent); |
2208 | 0 | debug_print("Used Compression Parameter 5: %" PRIu32, cmp_par_5_used); |
2209 | 0 | } |
2210 | | |
2211 | | |
2212 | | /** |
2213 | | * @brief parse the specific compressed entity header |
2214 | | * |
2215 | | * @param ent pointer to a compression entity |
2216 | | */ |
2217 | | |
2218 | | static void cmp_ent_parese_specific_header(const struct cmp_entity *ent) |
2219 | 0 | { |
2220 | 0 | enum cmp_data_type data_type = cmp_ent_get_data_type(ent); |
2221 | |
|
2222 | 0 | if (cmp_ent_get_data_type_raw_bit(ent)) { |
2223 | 0 | debug_print("Uncompressed data bit is set. No specific header is used."); |
2224 | 0 | return; |
2225 | 0 | } |
2226 | | |
2227 | 0 | switch (data_type) { |
2228 | 0 | case DATA_TYPE_IMAGETTE: |
2229 | 0 | case DATA_TYPE_SAT_IMAGETTE: |
2230 | 0 | case DATA_TYPE_F_CAM_IMAGETTE: |
2231 | 0 | cmp_ent_parese_imagette_header(ent); |
2232 | 0 | break; |
2233 | 0 | case DATA_TYPE_IMAGETTE_ADAPTIVE: |
2234 | 0 | case DATA_TYPE_SAT_IMAGETTE_ADAPTIVE: |
2235 | 0 | case DATA_TYPE_F_CAM_IMAGETTE_ADAPTIVE: |
2236 | 0 | cmp_ent_parese_adaptive_imagette_header(ent); |
2237 | 0 | break; |
2238 | 0 | case DATA_TYPE_OFFSET: |
2239 | 0 | case DATA_TYPE_BACKGROUND: |
2240 | 0 | case DATA_TYPE_SMEARING: |
2241 | 0 | case DATA_TYPE_S_FX: |
2242 | 0 | case DATA_TYPE_S_FX_EFX: |
2243 | 0 | case DATA_TYPE_S_FX_NCOB: |
2244 | 0 | case DATA_TYPE_S_FX_EFX_NCOB_ECOB: |
2245 | 0 | case DATA_TYPE_L_FX: |
2246 | 0 | case DATA_TYPE_L_FX_EFX: |
2247 | 0 | case DATA_TYPE_L_FX_NCOB: |
2248 | 0 | case DATA_TYPE_L_FX_EFX_NCOB_ECOB: |
2249 | 0 | case DATA_TYPE_F_FX: |
2250 | 0 | case DATA_TYPE_F_FX_EFX: |
2251 | 0 | case DATA_TYPE_F_FX_NCOB: |
2252 | 0 | case DATA_TYPE_F_FX_EFX_NCOB_ECOB: |
2253 | 0 | case DATA_TYPE_F_CAM_OFFSET: |
2254 | 0 | case DATA_TYPE_F_CAM_BACKGROUND: |
2255 | 0 | case DATA_TYPE_CHUNK: |
2256 | 0 | cmp_ent_parese_non_imagette_header(ent); |
2257 | 0 | break; |
2258 | 0 | case DATA_TYPE_UNKNOWN: |
2259 | 0 | default: |
2260 | 0 | debug_print("For this data product type no parse functions is implemented!"); |
2261 | 0 | break; |
2262 | 0 | } |
2263 | 0 | } |
2264 | | |
2265 | | |
2266 | | /** |
2267 | | * @brief parse the compressed entity header |
2268 | | * |
2269 | | * @param ent pointer to a compression entity |
2270 | | */ |
2271 | | |
2272 | | void cmp_ent_parse(struct cmp_entity *ent) |
2273 | 0 | { |
2274 | 0 | cmp_ent_parse_generic_header(ent); |
2275 | |
|
2276 | 0 | cmp_ent_parese_specific_header(ent); |
2277 | 0 | } |
2278 | | |