Libpolycomp
1.0
A compression/decompression library that implements the polynomial compression and other simple compression schemes
|
Enumerations | |
enum | pcomp_transform_direction_t { PCOMP_TD_DIRECT = 0, PCOMP_TD_INVERSE = 1 } |
Direction of a Chebyshev transform. More... | |
enum | pcomp_polycomp_algorithm_t { PCOMP_ALG_USE_CHEBYSHEV = 0, PCOMP_ALG_NO_CHEBYSHEV = 1 } |
Kind of algorithm used for the polynomial compression. More... | |
Functions | |
pcomp_polycomp_t * | pcomp_init_polycomp (pcomp_chunk_size_t samples_per_chunk, pcomp_poly_size_t num_of_coeffs, double max_allowable_error, pcomp_polycomp_algorithm_t algorithm) |
Allocate space for a pcomp_polycomp_t structure. More... | |
void | pcomp_free_polycomp (pcomp_polycomp_t *params) |
Free the memory allocated by pcomp_init_polycomp for a pcomp_polycomp_t structure. More... | |
pcomp_chunk_size_t | pcomp_polycomp_samples_per_chunk (const pcomp_polycomp_t *params) |
Return the number of samples per chunk. More... | |
pcomp_poly_size_t | pcomp_polycomp_num_of_poly_coeffs (const pcomp_polycomp_t *params) |
Return the number of coefficients for the fitting polynomial used in the polynomial compression. More... | |
double | pcomp_polycomp_max_error (const pcomp_polycomp_t *params) |
Return the upper bound on the error of the polynomial compression. More... | |
pcomp_polycomp_algorithm_t | pcomp_polycomp_algorithm (const pcomp_polycomp_t *params) |
Return the kind of algorithm used for a polynomial compression. More... | |
double | pcomp_polycomp_period (const pcomp_polycomp_t *params) |
Return the period of the input data, or a number less than or equal to 0 if the data have no periodicity. More... | |
void | pcomp_polycomp_set_period (pcomp_polycomp_t *params, double period) |
Set the periodicity of the data to be compressed. More... | |
int | pcomp_compress_polycomp (pcomp_polycomp_chunk_t **output_buf[], size_t *num_of_chunks, const double *input_buf, size_t input_size, const pcomp_polycomp_t *params) |
Compress the array input_buf using polynomial compression. More... | |
size_t | pcomp_total_num_of_samples (pcomp_polycomp_chunk_t *const chunk_array[], size_t num_of_chunks) |
Compute the sum of the number of samples encoded in chunk_array. More... | |
int | pcomp_decompress_polycomp (double *output_buf, pcomp_polycomp_chunk_t *const chunk_array[], size_t num_of_chunks) |
Decompress a sequence of chunks. More... | |
void | pcomp_free_chunks (pcomp_polycomp_chunk_t *chunk_array[], size_t num_of_chunks) |
Free an array of chunks. More... | |
size_t | pcomp_chunks_num_of_bytes (pcomp_polycomp_chunk_t *const chunks[], size_t num_of_chunks) |
Number of bytes required by pcomp_encode_chunks. More... | |
int | pcomp_encode_chunks (void *buf, size_t *buf_size, pcomp_polycomp_chunk_t *const chunk_array[], size_t num_of_chunks) |
Encode a list of chunks into a sequence of raw bytes. More... | |
int | pcomp_decode_chunks (pcomp_polycomp_chunk_t **chunk_array[], size_t *num_of_chunks, const void *buf) |
Decode a byte sequence created by pcomp_encode_chunks into an array of chunks. More... | |
Polynomial compression relies on a simple idea, that is to divide the input data stream into subsets of consecutive samples (called "chunks"), and to approximate each chunk by means of a polynomial. Such compression is inherently lossy, as the residuals of the fitting procedure are usually discarded. If the polynomial used for the fitting produces residuals that are too large, usually the samples in the chunk are saved in uncompressed form.
This idea has been widely applied in the literature. Libpolycomp implements an improvement over it, because if the fit residuals are too large, the library saves a chopped sequence of the Chebyshev transform of the residuals. This allows to achieve better compression ratios in those cases where polynomial fitting is not always enough to keep compression errors below the desired threshold. This kind of compression works quite well for smooth data series, where changes between consecutive samples are well described by slowly varying continuous functions. It is not suitable if the signal contains noise, unless this noise is significantly smaller than the signal and than the error threshold.
Libpolycomp allows to avoid the usage of Chebyshev transforms. In this case, if no polynomial of the desired degree are able to fit the data with the given error threshold, the data for that chunk is saved uncompressed.
The typical workflow for applying polynomial compression is the following:
The decompression workflow is specular:
The compression functions described in this page use the pcomp_polycomp_t structure to determine which parameters to use for the compression. The functions that allow to allocate/free/manage this structure are the following:
It is possible to use a set of more low-level functions to use polynomial compression. Refer to Polynomial compression (low-level functions) for further information.
Kind of algorithm used for the polynomial compression.
See the discussion in the section Polynomial compression functions for more information.
Definition at line 355 of file libpolycomp.h.
Direction of a Chebyshev transform.
Definition at line 320 of file libpolycomp.h.
size_t pcomp_chunks_num_of_bytes | ( | pcomp_polycomp_chunk_t *const | chunks[], |
size_t | num_of_chunks | ||
) |
Number of bytes required by pcomp_encode_chunks.
This function computes the number of bytes required to encode the array of chunks in the variable chunks. Unlike functions like pcomp_rle_bufsize, this function provides an exact estimate, not an upper bound.
[in] | chunks | Array of chunks to encode. This should have been initialized via a call to pcomp_compress_polycomp. |
[in] | num_of_chunks | Number of elements in chunks. |
int pcomp_compress_polycomp | ( | pcomp_polycomp_chunk_t ** | output_buf[], |
size_t * | num_of_chunks, | ||
const double * | input_buf, | ||
size_t | input_size, | ||
const pcomp_polycomp_t * | params | ||
) |
Compress the array input_buf using polynomial compression.
This function compresses the first input_size elements of the array input_buf using the polynomial compression scheme. The output is an array of chunks saved in output_buf (the number of elements of this array is saved in num_of_chunks). The params variable specifies the parameters used by the compression algorithm.
Here is an example showing how to compress a sequence of numbers in the variable input:
Once the sequence input_buf is compressed, the array of chunks can either be analyzed (e.g., using a for
loop as in the example above) or encoded using the pcomp_encode_chunks. Once the variable output_buf is no longer used, it should be freed via a call to pcomp_free_chunks.
[out] | output_buf | Pointer to a variable that will receive the address of an array of pcomp_polycomp_chunk_t variables created by the function. Such array contains the whole set of data in input in compressed format. The array can be freed via a call to pcomp_free_chunks. |
[out] | num_of_chunks | On output, the variable will contain the number of chunks saved in output_buf. |
[in] | input_buf | Pointer to the array of numbers to compress. |
[in] | input_size | Number of elements in input_buf to compress. |
[in] | params | Parameters used for the compression. The variable must have been created via a call to pcomp_init_polycomp. |
int pcomp_decode_chunks | ( | pcomp_polycomp_chunk_t ** | chunk_array[], |
size_t * | num_of_chunks, | ||
const void * | buf | ||
) |
Decode a byte sequence created by pcomp_encode_chunks into an array of chunks.
This function can be used to read from a binary file or a socket a sequence of chunks encoded by pcomp_encode_chunks. The function allocates memory for an array of pcomp_polycomp_chunk_t structures and returns it in the variable chunk_array. The latter variable must be freed using pcomp_free_chunks once it is no longer needed.
This function is the counterpart for pcomp_encode_chunks.
[out] | chunk_array | Pointer to an array that will contain the chunks decoded from buf. |
[out] | num_of_chunks | On exit, this variable will hold the number of chunks saved in chunk_array. |
[in] | Pointer | to the byte sequence to decode. |
int pcomp_decompress_polycomp | ( | double * | output_buf, |
pcomp_polycomp_chunk_t *const | chunk_array[], | ||
size_t | num_of_chunks | ||
) |
Decompress a sequence of chunks.
This function is the counterpart for pcomp_compress_polycomp.
[out] | output_buf | Pointer to the variable that will hold the uncompressed data. It must have room for a number of elements at least equal to the return value of pcomp_total_num_of_samples. |
[in] | chunk_array | Array of chunks holding the data in compressed format. |
[in] | num_of_chunks | Number of elements in the array chunk_array. |
int pcomp_encode_chunks | ( | void * | buf, |
size_t * | buf_size, | ||
pcomp_polycomp_chunk_t *const | chunk_array[], | ||
size_t | num_of_chunks | ||
) |
Encode a list of chunks into a sequence of raw bytes.
This function transforms an array of instances to pcomp_polycomp_chunk_t variables into a sequence of raw bytes, suitable for I/O. It can be used together with pcomp_compress_polycomp to compress a dataset and save it into a binary file.
To decode byte sequences produced by this function, use pcomp_decode_chunks.
[out] | buf | Pointer to a memory buffer that will receive the result of the encoding. It must have room for a number of bytes (uint8_t ) at least equal to the return value of pcomp_chunks_num_of_bytes. |
[in,out] | buf_size | On input, it should contain the number of bytes that can be written in buf. On exit, it will contain the number of bytes actually written. The latter number is equal to the value returned by pcomp_chunks_num_of_bytes. |
[in] | chunk_array | Array of chunks to encode |
[in] | num_of_chunks | Number of elements in the array chunk_array. |
void pcomp_free_chunks | ( | pcomp_polycomp_chunk_t * | chunk_array[], |
size_t | num_of_chunks | ||
) |
Free an array of chunks.
[in] | chunk_array | An array of chunks. This variable must have been allocated by a call to pcomp_compress_polycomp. |
[in] | num_of_chunks | Number of elements in the array chunk_array |
void pcomp_free_polycomp | ( | pcomp_polycomp_t * | params | ) |
Free the memory allocated by pcomp_init_polycomp for a pcomp_polycomp_t structure.
[in] | params | Pointer to the structure to be freed |
pcomp_polycomp_t* pcomp_init_polycomp | ( | pcomp_chunk_size_t | samples_per_chunk, |
pcomp_poly_size_t | num_of_coeffs, | ||
double | max_allowable_error, | ||
pcomp_polycomp_algorithm_t | algorithm | ||
) |
Allocate space for a pcomp_polycomp_t structure.
[in] | samples_per_chunk | Number of samples in each chunk |
[in] | num_of_coeffs | Number of polynomial coefficients to use |
[in] | max_allowable_error | Upper bound for the compression error (positive value) |
[in] | algorithm | Kind of compression algorithm to use |
pcomp_polycomp_algorithm_t pcomp_polycomp_algorithm | ( | const pcomp_polycomp_t * | params | ) |
double pcomp_polycomp_max_error | ( | const pcomp_polycomp_t * | params | ) |
pcomp_poly_size_t pcomp_polycomp_num_of_poly_coeffs | ( | const pcomp_polycomp_t * | params | ) |
Return the number of coefficients for the fitting polynomial used in the polynomial compression.
The return value has the same meaning as the value returned by the pcomp_poly_fit_num_of_coeffs.
[in] | params | Pointer to a pcomp_polycomp_t structure containing the compression parameters |
double pcomp_polycomp_period | ( | const pcomp_polycomp_t * | params | ) |
Return the period of the input data, or a number less than or equal to 0 if the data have no periodicity.
See also pcomp_polycomp_set_period.
[in] | params | Pointer to a pcomp_polycomp_t structure containing the compression parameters |
pcomp_chunk_size_t pcomp_polycomp_samples_per_chunk | ( | const pcomp_polycomp_t * | params | ) |
Return the number of samples per chunk.
This function returns the size of each chunk but the last one in the input data for a polynomial compression. Such chunks contain a set of consecutive values in the input array passed to routines as pcomp_compress_polycomp.
[in] | params | Pointer to a pcomp_polycomp_t structure containing the compression parameters |
void pcomp_polycomp_set_period | ( | pcomp_polycomp_t * | params, |
double | period | ||
) |
Set the periodicity of the data to be compressed.
If period is a value greater than zero, this is assumed to be the periodicity of the input data: the value x is therefore assumed equivalent to x + period and to x - period. It is typically a multiple of Pi = 3.14159...
The polynomial compressor can improve the compression ratio for data if they have some form of periodicity.
[in] | params | Pointer to a pcomp_polycomp_t structure containing the compression parameters |
[in] | period | The periodicity of the data, or a zero/negative value if no periodicity should be assumed by the compressor. |
size_t pcomp_total_num_of_samples | ( | pcomp_polycomp_chunk_t *const | chunk_array[], |
size_t | num_of_chunks | ||
) |
Compute the sum of the number of samples encoded in chunk_array.
[in] | chunk_array | Array of pcomp_polycomp_chunk_t variables. Typically, such array is created via a call to pcomp_compress_polycomp. |
[in] | num_of_chunks | Number of elements in chunk_array |