Libpolycomp  1.0
A compression/decompression library that implements the polynomial compression and other simple compression schemes
test_rle.c
1 /* test_rle.c - Tests for RLE functions
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 <assert.h>
28 #include <stdlib.h>
29 
30 /***********************************************************************
31  * Check that the RLE routines encode the output sequence in the
32  * required format */
33 
34 #define DEFINE_RLE_BINARY_FORMAT_TEST(fn_name, pcomp_fn, datatype_t) \
35  void fn_name(void) \
36  { \
37  datatype_t input_buf[] = { 10, 10, 20, 30, 30, 30 }; \
38  size_t input_size = sizeof(input_buf) / sizeof(input_buf[0]); \
39  size_t output_size = pcomp_rle_bufsize(input_size) \
40  * sizeof(datatype_t); \
41  datatype_t* output_buf = malloc(output_size); \
42  \
43  assert(pcomp_fn(output_buf, &output_size, input_buf, \
44  input_size) == PCOMP_STAT_SUCCESS); \
45  \
46  assert(output_buf[0] == 2); /* Count */ \
47  assert(output_buf[1] == 10); /* Value */ \
48  assert(output_buf[2] == 1); /* Count */ \
49  assert(output_buf[3] == 20); /* Value */ \
50  assert(output_buf[4] == 3); /* Count */ \
51  assert(output_buf[5] == 30); /* Value */ \
52  \
53  free(output_buf); \
54  }
55 
56 DEFINE_RLE_BINARY_FORMAT_TEST(test_rle_binary_format_int8,
58 DEFINE_RLE_BINARY_FORMAT_TEST(test_rle_binary_format_int16,
59  pcomp_compress_rle_int16, int16_t)
60 DEFINE_RLE_BINARY_FORMAT_TEST(test_rle_binary_format_int32,
61  pcomp_compress_rle_int32, int32_t)
62 DEFINE_RLE_BINARY_FORMAT_TEST(test_rle_binary_format_int64,
63  pcomp_compress_rle_int64, int64_t)
64 
65 DEFINE_RLE_BINARY_FORMAT_TEST(test_rle_binary_format_uint8,
66  pcomp_compress_rle_uint8, uint8_t)
67 DEFINE_RLE_BINARY_FORMAT_TEST(test_rle_binary_format_uint16,
68  pcomp_compress_rle_uint16, uint16_t)
69 DEFINE_RLE_BINARY_FORMAT_TEST(test_rle_binary_format_uint32,
70  pcomp_compress_rle_uint32, uint32_t)
71 DEFINE_RLE_BINARY_FORMAT_TEST(test_rle_binary_format_uint64,
72  pcomp_compress_rle_uint64, uint64_t)
73 
74 void test_rle_binary_format(void)
75 {
76  test_rle_binary_format_int8();
77  test_rle_binary_format_int16();
78  test_rle_binary_format_int32();
79  test_rle_binary_format_int64();
80 
81  test_rle_binary_format_uint8();
82  test_rle_binary_format_uint16();
83  test_rle_binary_format_uint32();
84  test_rle_binary_format_uint64();
85 }
86 
87 /***********************************************************************
88  * Check that the RLE routines are able to properly decompress a
89  * (long) sequence of data. */
90 
91 #define DEFINE_RLE_DECOMPRESS_TEST(fn_name, pcomp_compr_fn, \
92  pcomp_decompr_fn, datatype_t) \
93  void fn_name(void) \
94  { \
95  const size_t input_size = 10000; \
96  datatype_t* input_buf \
97  = malloc(input_size * sizeof(datatype_t)); \
98  size_t compr_size = pcomp_rle_bufsize(input_size) \
99  * sizeof(datatype_t); \
100  datatype_t* compr_buf = malloc(compr_size); \
101  datatype_t* decompr_buf \
102  = malloc(input_size * sizeof(datatype_t)); \
103  size_t decompr_size = input_size; \
104  size_t idx; \
105  \
106  for (idx = 0; idx < input_size; ++idx) { \
107  /* Pick a number between 0 and 9 */ \
108  input_buf[idx] = random() % 10; \
109  } \
110  \
111  assert(pcomp_compr_fn(compr_buf, &compr_size, input_buf, \
112  input_size) == PCOMP_STAT_SUCCESS); \
113  assert(pcomp_decompr_fn(decompr_buf, decompr_size, compr_buf, \
114  compr_size) == PCOMP_STAT_SUCCESS); \
115  \
116  assert(decompr_size == input_size); \
117  for (idx = 0; idx < input_size; ++idx) { \
118  assert(decompr_buf[idx] == input_buf[idx]); \
119  } \
120  \
121  free(input_buf); \
122  free(compr_buf); \
123  free(decompr_buf); \
124  }
125 
126 DEFINE_RLE_DECOMPRESS_TEST(test_rle_decompress_int8,
128  pcomp_decompress_rle_int8, int8_t)
129 DEFINE_RLE_DECOMPRESS_TEST(test_rle_decompress_int16,
131  pcomp_decompress_rle_int16, int16_t)
132 DEFINE_RLE_DECOMPRESS_TEST(test_rle_decompress_int32,
134  pcomp_decompress_rle_int32, int32_t)
135 DEFINE_RLE_DECOMPRESS_TEST(test_rle_decompress_int64,
137  pcomp_decompress_rle_int64, int64_t)
138 
139 DEFINE_RLE_DECOMPRESS_TEST(test_rle_decompress_uint8,
141  pcomp_decompress_rle_uint8, uint8_t)
142 DEFINE_RLE_DECOMPRESS_TEST(test_rle_decompress_uint16,
144  pcomp_decompress_rle_uint16, uint16_t)
145 DEFINE_RLE_DECOMPRESS_TEST(test_rle_decompress_uint32,
147  pcomp_decompress_rle_uint32, uint32_t)
148 DEFINE_RLE_DECOMPRESS_TEST(test_rle_decompress_uint64,
150  pcomp_decompress_rle_uint64, uint64_t)
151 
152 void test_rle_decompression(void)
153 {
154  test_rle_decompress_int8();
155  test_rle_decompress_int16();
156  test_rle_decompress_int32();
157  test_rle_decompress_int64();
158 
159  test_rle_decompress_uint8();
160  test_rle_decompress_uint16();
161  test_rle_decompress_uint32();
162  test_rle_decompress_uint64();
163 }
164 
165 /***********************************************************************
166  * Check that there are no overflows when the sequence of repeated
167  * values is very long. */
168 
169 void test_rle_no_overflow(void)
170 {
171  size_t input_size = INT8_MAX + 2;
172  int8_t* input_buf = malloc(input_size * sizeof(int8_t));
173  size_t output_size = pcomp_rle_bufsize(input_size) * sizeof(int8_t);
174  int8_t* output_buf = malloc(output_size);
175  size_t idx;
176  const int8_t value = 123;
177 
178  for (idx = 0; idx < input_size; ++idx) {
179  input_buf[idx] = value;
180  }
181 
182  assert(pcomp_compress_rle_int8(output_buf, &output_size, input_buf,
183  input_size) == PCOMP_STAT_SUCCESS);
184 
185  assert(output_size == 4);
186  assert(output_buf[0] == INT8_MAX); /* Count */
187  assert(output_buf[1] == value); /* Value */
188  assert(output_buf[2] == 2); /* Count */
189  assert(output_buf[3] == value); /* Value */
190 
191  free(output_buf);
192 }
193 
194 int main(void)
195 {
196  test_rle_binary_format();
197  test_rle_decompression();
198  test_rle_no_overflow();
199 
200  return 0;
201 }
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_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.
size_t pcomp_rle_bufsize(size_t input_size)
Calculate an upper limit for the size of a buffer holding RLE-encoded streams.
Definition: rle.c:95
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_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_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_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_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.
Header file for Libpolycomp.