Libpolycomp  1.0
A compression/decompression library that implements the polynomial compression and other simple compression schemes
diff_rle.c
1 /* diff_rle.c - Differenced run-length encoding
2  *
3  * Copyright (c) 2015 Maurizio Tomasi
4  *
5  * Permission is hereby granted, free of charge, to any person
6  * obtaining a copy of this software and associated documentation
7  * files (the "Software"), to deal in the Software without
8  * restriction, including without limitation the rights to use, copy,
9  * modify, merge, publish, distribute, sublicense, and/or sell copies
10  * of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be
14  * included in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23  * SOFTWARE.
24  */
25 
26 #include "libpolycomp.h"
27 #include <stdlib.h>
28 
78 size_t pcomp_diffrle_bufsize(size_t input_size)
79 {
80  return 1 + 2 * input_size;
81 }
82 
359 /***********************************************************************
360  * Differenced run-length compression routines
361  */
362 
363 #define IMPLEMENT_DIFFRLE_COMPR_FN(name, rle_compr_fn, datatype_t) \
364  int name(datatype_t* output_buf, size_t* output_size, \
365  const datatype_t* input_buf, size_t input_size) \
366  { \
367  size_t rle_output_size; \
368  datatype_t* diff_buf = NULL; \
369  int rle_compr_result; \
370  size_t idx; \
371  \
372  if (output_buf == NULL || output_size == NULL \
373  || input_buf == NULL) \
374  abort(); \
375  \
376  if (input_size == 0) { \
377  *output_size = 0; \
378  return PCOMP_STAT_SUCCESS; \
379  } \
380  \
381  output_buf[0] = input_buf[0]; \
382  if (input_size == 1) { \
383  *output_size = 1; \
384  return PCOMP_STAT_SUCCESS; \
385  } \
386  \
387  diff_buf = malloc((input_size - 1) * sizeof(datatype_t)); \
388  for (idx = 0; idx < input_size - 1; ++idx) { \
389  diff_buf[idx] = input_buf[idx + 1] - input_buf[idx]; \
390  } \
391  \
392  rle_output_size = *output_size - 1; \
393  rle_compr_result \
394  = rle_compr_fn(output_buf + 1, &rle_output_size, diff_buf, \
395  input_size - 1); \
396  free(diff_buf); \
397  if (rle_compr_result != PCOMP_STAT_SUCCESS) \
398  return rle_compr_result; \
399  \
400  *output_size = rle_output_size + 1; \
401  return PCOMP_STAT_SUCCESS; \
402  }
403 
404 IMPLEMENT_DIFFRLE_COMPR_FN(pcomp_compress_diffrle_int8,
405  pcomp_compress_rle_int8, int8_t)
406 IMPLEMENT_DIFFRLE_COMPR_FN(pcomp_compress_diffrle_int16,
407  pcomp_compress_rle_int16, int16_t)
408 IMPLEMENT_DIFFRLE_COMPR_FN(pcomp_compress_diffrle_int32,
409  pcomp_compress_rle_int32, int32_t)
410 IMPLEMENT_DIFFRLE_COMPR_FN(pcomp_compress_diffrle_int64,
411  pcomp_compress_rle_int64, int64_t)
412 
413 IMPLEMENT_DIFFRLE_COMPR_FN(pcomp_compress_diffrle_uint8,
414  pcomp_compress_rle_uint8, uint8_t)
415 IMPLEMENT_DIFFRLE_COMPR_FN(pcomp_compress_diffrle_uint16,
416  pcomp_compress_rle_uint16, uint16_t)
417 IMPLEMENT_DIFFRLE_COMPR_FN(pcomp_compress_diffrle_uint32,
418  pcomp_compress_rle_uint32, uint32_t)
419 IMPLEMENT_DIFFRLE_COMPR_FN(pcomp_compress_diffrle_uint64,
420  pcomp_compress_rle_uint64, uint64_t)
421 
422 /***********************************************************************
423  * Differenced run-length decompression routines
424  */
425 
426 #define IMPLEMENT_DIFFRLE_DECOMPR_FN(name, datatype_t) \
427  int name(datatype_t* output_buf, size_t output_size, \
428  const datatype_t* input_buf, size_t input_size) \
429  { \
430  size_t input_idx = 0; \
431  size_t output_idx = 0; \
432  \
433  if (output_buf == NULL || input_buf == NULL) \
434  abort(); \
435  \
436  if (input_size == 0) { \
437  return PCOMP_STAT_SUCCESS; \
438  } \
439  \
440  if (input_size % 2 != 1) { \
441  return PCOMP_STAT_INVALID_ENCODING; \
442  } \
443  \
444  output_buf[output_idx++] = input_buf[input_idx++]; \
445  \
446  while (output_idx < output_size \
447  && input_idx < input_size - 1) { \
448  datatype_t count = input_buf[input_idx]; \
449  datatype_t incr = input_buf[input_idx + 1]; \
450  datatype_t idx; \
451  \
452  for (idx = 0; idx < count; ++idx) { \
453  output_buf[output_idx] = output_buf[output_idx - 1] \
454  + incr; \
455  output_idx++; \
456  } \
457  \
458  input_idx += 2; \
459  } \
460  \
461  return PCOMP_STAT_SUCCESS; \
462  }
463 
464 IMPLEMENT_DIFFRLE_DECOMPR_FN(pcomp_decompress_diffrle_int8, int8_t)
465 IMPLEMENT_DIFFRLE_DECOMPR_FN(pcomp_decompress_diffrle_int16, int16_t)
466 IMPLEMENT_DIFFRLE_DECOMPR_FN(pcomp_decompress_diffrle_int32, int32_t)
467 IMPLEMENT_DIFFRLE_DECOMPR_FN(pcomp_decompress_diffrle_int64, int64_t)
468 
469 IMPLEMENT_DIFFRLE_DECOMPR_FN(pcomp_decompress_diffrle_uint8, uint8_t)
470 IMPLEMENT_DIFFRLE_DECOMPR_FN(pcomp_decompress_diffrle_uint16, uint16_t)
471 IMPLEMENT_DIFFRLE_DECOMPR_FN(pcomp_decompress_diffrle_uint32, uint32_t)
472 IMPLEMENT_DIFFRLE_DECOMPR_FN(pcomp_decompress_diffrle_uint64, uint64_t)
int pcomp_decompress_diffrle_uint32(uint32_t *output_buf, size_t output_size, const uint32_t *input_buf, size_t input_size)
Compress an array of uint32_t values using the diffRLE compression.
int pcomp_compress_rle_int16(int16_t *output_buf, size_t *output_size, const int16_t *input_buf, size_t input_size)
Compress an array of int16_t values using the RLE compression.
int pcomp_compress_diffrle_uint8(uint8_t *output_buf, size_t *output_size, const uint8_t *input_buf, size_t input_size)
Compress an array of uint8_t values using the diffRLE compression.
int pcomp_decompress_diffrle_int16(int16_t *output_buf, size_t output_size, const int16_t *input_buf, size_t input_size)
Compress an array of int16_t values using the diffRLE compression.
int pcomp_compress_rle_int32(int32_t *output_buf, size_t *output_size, const int32_t *input_buf, size_t input_size)
Compress an array of int32_t values using the RLE compression.
int pcomp_compress_diffrle_int32(int32_t *output_buf, size_t *output_size, const int32_t *input_buf, size_t input_size)
Compress an array of int32_t values using the diffRLE compression.
int pcomp_decompress_diffrle_uint8(uint8_t *output_buf, size_t output_size, const uint8_t *input_buf, size_t input_size)
Compress an array of uint8_t values using the diffRLE compression.
int pcomp_compress_rle_uint64(uint64_t *output_buf, size_t *output_size, const uint64_t *input_buf, size_t input_size)
Compress an array of uint64_t values using the RLE compression.
int pcomp_compress_diffrle_uint16(uint16_t *output_buf, size_t *output_size, const uint16_t *input_buf, size_t input_size)
Compress an array of uint16_t values using the diffRLE compression.
size_t pcomp_diffrle_bufsize(size_t input_size)
Calculate an upper limit for the size of a buffer holding streams encoded using differenced RLE...
Definition: diff_rle.c:78
int pcomp_decompress_diffrle_int32(int32_t *output_buf, size_t output_size, const int32_t *input_buf, size_t input_size)
Compress an array of int32_t values using the diffRLE compression.
int pcomp_decompress_diffrle_uint16(uint16_t *output_buf, size_t output_size, const uint16_t *input_buf, size_t input_size)
Compress an array of uint16_t values using the diffRLE compression.
int pcomp_compress_rle_uint16(uint16_t *output_buf, size_t *output_size, const uint16_t *input_buf, size_t input_size)
Compress an array of uint16_t values using the RLE compression.
int pcomp_compress_diffrle_uint32(uint32_t *output_buf, size_t *output_size, const uint32_t *input_buf, size_t input_size)
Compress an array of uint32_t values using the diffRLE compression.
int pcomp_decompress_diffrle_int8(int8_t *output_buf, size_t output_size, const int8_t *input_buf, size_t input_size)
Decompress an array of int8_t values encoded using the diffRLE compression.
int pcomp_compress_diffrle_int16(int16_t *output_buf, size_t *output_size, const int16_t *input_buf, size_t input_size)
Compress an array of int16_t values using the diffRLE compression.
int pcomp_compress_rle_int64(int64_t *output_buf, size_t *output_size, const int64_t *input_buf, size_t input_size)
Compress an array of int64_t values using the RLE compression.
int pcomp_compress_rle_int8(int8_t *output_buf, size_t *output_size, const int8_t *input_buf, size_t input_size)
Compress an array of int8_t values using the RLE compression.
int pcomp_decompress_diffrle_uint64(uint64_t *output_buf, size_t output_size, const uint64_t *input_buf, size_t input_size)
Compress an array of uint64_t values using the diffRLE compression.
int pcomp_compress_rle_uint32(uint32_t *output_buf, size_t *output_size, const uint32_t *input_buf, size_t input_size)
Compress an array of uint32_t values using the RLE compression.
int pcomp_decompress_diffrle_int64(int64_t *output_buf, size_t output_size, const int64_t *input_buf, size_t input_size)
Compress an array of int64_t values using the diffRLE compression.
int pcomp_compress_diffrle_int8(int8_t *output_buf, size_t *output_size, const int8_t *input_buf, size_t input_size)
Compress an array of int8_t values using the diffRLE compression.
int pcomp_compress_rle_uint8(uint8_t *output_buf, size_t *output_size, const uint8_t *input_buf, size_t input_size)
Compress an array of uint8_t values using the RLE compression.
int pcomp_compress_diffrle_int64(int64_t *output_buf, size_t *output_size, const int64_t *input_buf, size_t input_size)
Compress an array of int64_t values using the diffRLE compression.
Header file for Libpolycomp.
int pcomp_compress_diffrle_uint64(uint64_t *output_buf, size_t *output_size, const uint64_t *input_buf, size_t input_size)
Compress an array of uint64_t values using the diffRLE compression.