79 size_t bits_per_sample;
105 size_t bits_per_sample)
108 params->element_size = element_size;
109 params->bits_per_sample = bits_per_sample;
110 params->min_value = 0.0;
111 params->normalization = 1.0;
147 return params->element_size;
160 return params->bits_per_sample;
175 return params->normalization;
190 return params->min_value;
213 double normalization,
double offset)
218 params->normalization = normalization;
219 params->min_value = offset;
253 if (params->element_size == 0 || params->bits_per_sample == 0)
256 num_of_bits = input_size * params->element_size * CHAR_BIT;
257 result = num_of_bits / params->bits_per_sample;
258 if (num_of_bits % params->bits_per_sample > 0)
356 #define DEFINE_FIND_BOUNDS_FN(name, datatype_t) \
357 static void name(const datatype_t* values, size_t num, \
358 double* min, double* max) \
362 if (values == NULL || num == 0 || min == NULL || max == NULL) \
365 *min = *max = values[0]; \
366 for (idx = 1; idx < num; ++idx) { \
367 if (values[idx] < *min) \
368 *min = values[idx]; \
369 else if (values[idx] > *max) \
370 *max = values[idx]; \
374 DEFINE_FIND_BOUNDS_FN(find_bounds_float,
float)
375 DEFINE_FIND_BOUNDS_FN(find_bounds_double,
double)
377 static
double two_to(
int exponent)
381 for (idx = 2; idx <= exponent; ++idx)
387 #define DEFINE_COMPRESS_QUANT_FN(name, find_bounds_fn, datatype_t) \
388 int name(void* output_buf, size_t* output_size, \
389 const datatype_t* input_buf, size_t input_size, \
390 pcomp_quant_params_t* params) \
395 uint8_t cur_byte_buf = 0; \
396 size_t bits_in_buffer = 0; \
399 if (output_buf == NULL || output_size == NULL \
400 || input_buf == NULL || params == NULL) \
403 find_bounds_fn(input_buf, input_size, ¶ms->min_value, \
405 params->normalization = (two_to(params->bits_per_sample) \
406 - 1.0) / (max - params->min_value); \
408 for (idx = 0; idx < input_size; ++idx) { \
410 double scaled_value \
411 = floor((input_buf[idx] - params->min_value) \
412 * params->normalization \
415 for (bit_idx = 0; bit_idx < params->bits_per_sample; \
417 uint8_t bit = (uint8_t)floor(fmod(scaled_value, 2.0)); \
418 cur_byte_buf = (cur_byte_buf << 1) + bit; \
420 scaled_value /= 2.0; \
422 if (bits_in_buffer >= CHAR_BIT) { \
424 if (byte_buf - (uint8_t*)output_buf \
426 return PCOMP_STAT_INVALID_BUFFER; \
430 *byte_buf++ = cur_byte_buf; \
432 bits_in_buffer = 0; \
441 if (bits_in_buffer > 0) { \
442 *byte_buf++ = cur_byte_buf; \
445 *output_size = byte_buf - (uint8_t*)output_buf; \
446 return PCOMP_STAT_SUCCESS; \
452 find_bounds_double,
double)
458 #define DEFINE_DECOMPRESS_QUANT_FN(name, datatype_t) \
459 int name(datatype_t* output_buf, size_t output_size, \
460 const void* input_buf, size_t input_size, \
461 const pcomp_quant_params_t* params) \
465 size_t bits_in_cache; \
466 const uint8_t* byte_buf = input_buf; \
468 if (output_buf == NULL || input_buf == NULL || params == NULL) \
471 if (input_size == 0) \
472 return PCOMP_STAT_SUCCESS; \
474 if (output_size == 0) \
475 return PCOMP_STAT_INVALID_BUFFER; \
477 byte = *byte_buf++; \
478 bits_in_cache = CHAR_BIT; \
481 while (output_idx < output_size) { \
486 for (bit_idx = 0; bit_idx < params->bits_per_sample; \
488 buffer = (buffer << 1) \
489 + ((uint64_t)byte >> (CHAR_BIT - 1)); \
492 if (bits_in_cache == 0 && output_idx < output_size \
493 && (byte_buf - (uint8_t*)input_buf) \
495 byte = *byte_buf++; \
496 bits_in_cache = CHAR_BIT; \
500 output_buf[output_idx] = buffer / params->normalization \
501 + params->min_value; \
505 return PCOMP_STAT_SUCCESS; \
508 DEFINE_DECOMPRESS_QUANT_FN(pcomp_decompress_quant_float,
float)
509 DEFINE_DECOMPRESS_QUANT_FN(pcomp_decompress_quant_double,
double)
double pcomp_quant_normalization(const pcomp_quant_params_t *params)
Return the normalization constant used for converting floating-point numbers into quantized integers...
size_t pcomp_quant_element_size(const pcomp_quant_params_t *params)
Return the size (in bytes) of the elements to be quantized.
size_t pcomp_quant_bits_per_sample(const pcomp_quant_params_t *params)
Return the number of bits that must be used for each quantized sample.
int pcomp_compress_quant_float(void *output_buf, size_t *output_size, const float *input_buf, size_t input_size, pcomp_quant_params_t *params)
Quantize a stream of 32-bit floating point numbers.
int pcomp_compress_quant_double(void *output_buf, size_t *output_size, const double *input_buf, size_t input_size, pcomp_quant_params_t *params)
Quantize a stream of 64-bit floating point numbers.
pcomp_quant_params_t * pcomp_init_quant_params(size_t element_size, size_t bits_per_sample)
Initialize a pcomp_quant_params_t structure.
double pcomp_quant_offset(const pcomp_quant_params_t *params)
Return the additive constant used for converting floating-point numbers into quantized integers...
size_t pcomp_quant_bufsize(size_t input_size, const pcomp_quant_params_t *params)
Return the size (in bytes) of the buffer that will contain a quantized stream of input_size floating ...
void pcomp_quant_set_normalization(pcomp_quant_params_t *params, double normalization, double offset)
Set the normalization constants (multiplicative and additive) used to quantize floating-point numbers...
void pcomp_free_quant_params(pcomp_quant_params_t *params)
Free a pcomp_quant_params_t structure.
Header file for Libpolycomp.