ascii-chat 0.6.0
Real-time terminal-based video chat with ASCII art conversion
Loading...
Searching...
No Matches
compression.c
Go to the documentation of this file.
1
7#include <zstd.h>
8#include <string.h>
9#include "compression.h"
10#include "common.h"
11#include "asciichat_errno.h" // For asciichat_errno system
12
13// Compress data using zstd with configurable compression level
14asciichat_error_t compress_data(const void *input, size_t input_size, void **output, size_t *output_size,
15 int compression_level) {
16 if (!input || input_size == 0 || !output || !output_size) {
17 return SET_ERRNO(ERROR_INVALID_PARAM, "Invalid parameters: input=%p, input_size=%zu, output=%p, output_size=%p",
18 input, input_size, output, output_size);
19 }
20
21 // Validate compression level (1-9 for real-time streaming)
22 if (compression_level < 1 || compression_level > 9) {
23 return SET_ERRNO(ERROR_INVALID_PARAM, "Invalid compression level %d: must be between 1 and 9", compression_level);
24 }
25
26 // Calculate maximum compressed size
27 size_t compressed_size = ZSTD_compressBound(input_size);
28
29 // Sanity check ZSTD_compressBound result
30 // ZSTD_compressBound returns 0 for errors or very large values for huge inputs
31 if (compressed_size == 0 || compressed_size > 256 * 1024 * 1024) { // Max 256MB compressed buffer
32 return SET_ERRNO(ERROR_INVALID_PARAM, "ZSTD_compressBound returned unreasonable size: %zu for input %zu",
33 compressed_size, input_size);
34 }
35
36 unsigned char *compressed_data = NULL;
37 compressed_data = SAFE_MALLOC(compressed_size, unsigned char *);
38
39 if (!compressed_data) {
40 return SET_ERRNO(ERROR_MEMORY, "Failed to allocate compressed data buffer");
41 }
42
43 // Compress using zstd with user-specified compression level
44 size_t ret = ZSTD_compress(compressed_data, compressed_size, input, input_size, compression_level);
45
46 if (ZSTD_isError(ret)) {
47 SAFE_FREE(compressed_data);
48 return SET_ERRNO(ERROR_GENERAL, "zstd compression failed: %s", ZSTD_getErrorName(ret));
49 }
50
51 *output = compressed_data;
52 *output_size = ret;
53
54 return ASCIICHAT_OK;
55}
56
57// Decompress data using zstd
58asciichat_error_t decompress_data(const void *input, size_t input_size, void *output, size_t output_size) {
59 if (!input || input_size == 0 || !output || output_size == 0) {
60 return SET_ERRNO(ERROR_INVALID_PARAM, "Invalid parameters: input=%p, input_size=%zu, output=%p, output_size=%zu",
61 input, input_size, output, output_size);
62 }
63
64 size_t ret = ZSTD_decompress(output, output_size, input, input_size);
65
66 if (ZSTD_isError(ret)) {
67 return SET_ERRNO(ERROR_GENERAL, "zstd decompression failed: %s", ZSTD_getErrorName(ret));
68 }
69
70 return ASCIICHAT_OK;
71}
72
73// Check if compression is worthwhile based on ratio
74bool should_compress(size_t original_size, size_t compressed_size) {
75 if (original_size == 0)
76 return false;
77
78 float ratio = (float)compressed_size / (float)original_size;
79 return ratio < COMPRESSION_RATIO_THRESHOLD;
80}
⚠️‼️ Error and/or exit() when things go bad.
📦 Network Packet Compression Utilities
#define SAFE_FREE(ptr)
Definition common.h:320
#define SAFE_MALLOC(size, cast)
Definition common.h:208
asciichat_error_t decompress_data(const void *input, size_t input_size, void *output, size_t output_size)
Decompress data using zstd.
Definition compression.c:58
bool should_compress(size_t original_size, size_t compressed_size)
Determine if compression should be used for given data sizes.
Definition compression.c:74
asciichat_error_t compress_data(const void *input, size_t input_size, void **output, size_t *output_size, int compression_level)
Compress data using zstd with configurable compression level.
Definition compression.c:14
#define COMPRESSION_RATIO_THRESHOLD
Compression ratio threshold - only use if <80% original size.
Definition compression.h:58
#define SET_ERRNO(code, context_msg,...)
Set error code with custom context message and log it.
asciichat_error_t
Error and exit codes - unified status values (0-255)
Definition error_codes.h:46
@ ERROR_MEMORY
Definition error_codes.h:53
@ ASCIICHAT_OK
Definition error_codes.h:48
@ ERROR_GENERAL
Definition error_codes.h:49
@ ERROR_INVALID_PARAM