lz4s.c
Go to the documentation of this file.
1 /*********************************************************************
2 * Software License Agreement (BSD License)
3 *
4 * Copyright (c) 2014, Ben Charrow
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
17 * * Neither the name of Willow Garage, Inc. nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 ********************************************************************/
34 
35 #include "roslz4/lz4s.h"
36 
37 #include "xxhash.h"
38 
39 #include <stdint.h>
40 #include <string.h>
41 #include <stdio.h>
42 #include <stdlib.h>
43 
44 #if 0
45 #define DEBUG(...) fprintf(stderr, __VA_ARGS__)
46 #else
47 #define DEBUG(...)
48 #endif
49 
50 // magic numbers
51 const uint32_t kMagicNumber = 0x184D2204;
52 const uint32_t kEndOfStream = 0x00000000;
53 
54 // Bitmasks
55 const uint8_t k1Bits = 0x01;
56 const uint8_t k2Bits = 0x03;
57 const uint8_t k3Bits = 0x07;
58 const uint8_t k4Bits = 0x0F;
59 const uint8_t k8Bits = 0xFF;
60 
61 uint32_t readUInt32(unsigned char *buffer) {
62  return ((buffer[0] << 0) | (buffer[1] << 8) |
63  (buffer[2] << 16) | (buffer[3] << 24));
64 }
65 
66 void writeUInt32(unsigned char *buffer, uint32_t val) {
67  buffer[0] = val & 0xFF;
68  buffer[1] = (val >> 8) & 0xFF;
69  buffer[2] = (val >> 16) & 0xFF;
70  buffer[3] = (val >> 24) & 0xFF;
71 }
72 
73 int min(int a, int b) {
74  return a < b ? a : b;
75 }
76 
77 /*========================== Low level compression ==========================*/
78 
79 typedef struct {
83 
84  char *buffer;
87 
88  int finished; // 1 if done compressing/decompressing; 0 otherwise
89 
90  void* xxh32_state;
91 
92  // Compression state
94 
95  // Decompression state
96  char header[10];
97  uint32_t block_size; // Size of current block
98  int block_size_read; // # of bytes read for current block_size
99  int block_uncompressed; // 1 if block is uncompressed, 0 otherwise
100  uint32_t stream_checksum; // Storage for checksum
101  int stream_checksum_read; // # of bytes read for stream_checksum
102 } stream_state;
103 
104 void advanceInput(roslz4_stream *str, int nbytes) {
105  str->input_next += nbytes;
106  str->input_left -= nbytes;
107  str->total_in += nbytes;
108 }
109 
110 void advanceOutput(roslz4_stream *str, int nbytes) {
111  str->output_next += nbytes;
112  str->output_left -= nbytes;
113  str->total_out += nbytes;
114 }
115 
116 void fillUInt32(roslz4_stream *str, uint32_t *dest_val, int *offset) {
117  char *dest = (char*) dest_val;
118  int to_copy = min(4 - *offset, str->input_left);
119  memcpy(dest + *offset, str->input_next, to_copy);
120  advanceInput(str, to_copy);
121  *offset += to_copy;
122 }
123 
125  if (str->output_left < 7) {
126  return ROSLZ4_OUTPUT_SMALL; // Output must have 7 bytes
127  }
128 
129  stream_state *state = str->state;
130  writeUInt32((unsigned char*) str->output_next, kMagicNumber);
131  int version = 1;
132  char *out = str->output_next;
133  *(out+4) = ((unsigned)version & k2Bits) << 6;
134  *(out+4) |= ((unsigned)state->block_independence_flag & k1Bits) << 5;
135  *(out+4) |= ((unsigned)state->block_checksum_flag & k1Bits) << 4;
136  *(out+4) |= ((unsigned)state->stream_checksum_flag & k1Bits) << 2;
137  *(out+5) = ((unsigned)str->block_size_id & k3Bits) << 4;
138 
139  // Checksum: 2nd byte of hash of header flags
140  unsigned char checksum = (XXH32(str->output_next + 4, 2, 0) >> 8) & k8Bits;
141  *(str->output_next+6) = checksum;
142 
143  advanceOutput(str, 7);
144  DEBUG("writeHeader() Put 7 bytes in output\n");
145 
146  return ROSLZ4_OK;
147 }
148 
150  if (str->output_left < 8) {
151  return ROSLZ4_OUTPUT_SMALL;
152  }
153 
154  stream_state *state = str->state;
155  state->finished = 1;
156  writeUInt32((unsigned char*) str->output_next, kEndOfStream);
157  advanceOutput(str, 4);
158 
159  uint32_t stream_checksum = XXH32_digest(state->xxh32_state);
160  writeUInt32((unsigned char*) str->output_next, stream_checksum);
161  advanceOutput(str, 4);
162  state->xxh32_state = NULL;
163 
164  DEBUG("writeEOS() Wrote 8 bytes to output %i\n", str->output_left);
165  return ROSLZ4_STREAM_END;
166 }
167 
168 // If successfull, number of bytes written to output
169 // If error, LZ4 return code
171  stream_state *state = str->state;
172  uint32_t uncomp_size = state->buffer_offset;
173  if (state->buffer_offset == 0) {
174  return 0; // No data to flush
175  } else if (str->output_left - 4 < uncomp_size) {
176  DEBUG("bufferToOutput() Not enough space left in output\n");
177  return ROSLZ4_OUTPUT_SMALL;
178  }
179 
180  DEBUG("bufferToOutput() Flushing %i bytes, %i left in output\n",
181  state->buffer_offset, str->output_left);
182 
183  // Shrink output by 1 to detect if data is not compressible
184  uint32_t comp_size = LZ4_compress_limitedOutput(state->buffer,
185  str->output_next + 4,
186  (int) state->buffer_offset,
187  (int) uncomp_size - 1);
188  uint32_t wrote;
189  if (comp_size > 0) {
190  DEBUG("bufferToOutput() Compressed to %i bytes\n", comp_size);
191  // Write compressed data size
192  wrote = 4 + comp_size;
193  writeUInt32((unsigned char*)str->output_next, comp_size);
194  } else {
195  // Write uncompressed data
196  DEBUG("bufferToOutput() Can't compress, copying input\n");
197  memcpy(str->output_next + 4, state->buffer, uncomp_size);
198  // Write uncompressed data size. Signal data is uncompressed with high
199  // order bit; won't confuse decompression because max block size is < 2GB
200  wrote = 4 + uncomp_size;
201  writeUInt32((unsigned char*) str->output_next, uncomp_size | 0x80000000);
202  }
203 
204  advanceOutput(str, wrote);
205  state->buffer_offset -= uncomp_size;
206 
207  DEBUG("bufferToOutput() Ate %i from buffer, wrote %i to output (%i)\n",
208  uncomp_size, wrote, str->output_left);
209  return wrote;
210 }
211 
212 // Copy as much data as possible from input to internal buffer
213 // Return number of bytes written if successful, LZ4 error code on error
215  stream_state *state = str->state;
216  if (str->input_left == 0 ||
217  state->buffer_size == state->buffer_offset) {
218  return 0;
219  }
220  int buffer_left = state->buffer_size - state->buffer_offset;
221  int to_copy = min(str->input_left, buffer_left);
222 
223  int ret = XXH32_update(state->xxh32_state, str->input_next, to_copy);
224  if (ret == XXH_ERROR) { return ROSLZ4_ERROR; }
225 
226  memcpy(state->buffer + state->buffer_offset, str->input_next, to_copy);
227  advanceInput(str, to_copy);
228  state->buffer_offset += to_copy;
229 
230  DEBUG("inputToBuffer() Wrote % 5i bytes to buffer (size=% 5i)\n",
231  to_copy, state->buffer_offset);
232  return to_copy;
233 }
234 
236  stream_state *state = (stream_state*) malloc(sizeof(stream_state));
237  if (state == NULL) {
238  return ROSLZ4_MEMORY_ERROR; // Allocation of state failed
239  }
240  str->state = state;
241 
242  str->block_size_id = -1;
243  state->block_independence_flag = 1;
244  state->block_checksum_flag = 0;
245  state->stream_checksum_flag = 1;
246 
247  state->finished = 0;
248 
249  state->xxh32_state = XXH32_init(0);
250  if (state->xxh32_state == NULL) {
251  if (state->buffer != NULL) {
252  free(state->buffer);
253  }
254  free(state);
255  str->state = NULL;
256  return ROSLZ4_MEMORY_ERROR; // Allocation failed
257  }
258  state->stream_checksum = 0;
259  state->stream_checksum_read = 0;
260 
261  state->wrote_header = 0;
262 
263  state->buffer_offset = 0;
264  state->buffer_size = 0;
265  state->buffer = NULL;
266 
267  state->block_size = 0;
268  state->block_size_read = 0;
269  state->block_uncompressed = 0;
270 
271  str->total_in = 0;
272  str->total_out = 0;
273 
274  return ROSLZ4_OK;
275 }
276 
277 int streamResizeBuffer(roslz4_stream *str, int block_size_id) {
278  stream_state *state = str->state;
279  if (!(4 <= block_size_id && block_size_id <= 7)) {
280  return ROSLZ4_PARAM_ERROR; // Invalid block size
281  }
282 
283  str->block_size_id = block_size_id;
284  state->buffer_offset = 0;
286  state->buffer = (char*) malloc(sizeof(char) * state->buffer_size);
287  if (state->buffer == NULL) {
288  return ROSLZ4_MEMORY_ERROR; // Allocation of buffer failed
289  }
290  return ROSLZ4_OK;
291 }
292 
294  stream_state *state = str->state;
295  if (state != NULL) {
296  if (state->buffer != NULL) {
297  free(state->buffer);
298  }
299  if (state->xxh32_state != NULL) {
300  XXH32_digest(state->xxh32_state);
301  }
302  free(state);
303  str->state = NULL;
304  }
305 }
306 
307 int roslz4_blockSizeFromIndex(int block_id) {
308  return (1 << (8 + (2 * block_id)));
309 }
310 
311 int roslz4_compressStart(roslz4_stream *str, int block_size_id) {
312  int ret = streamStateAlloc(str);
313  if (ret < 0) { return ret; }
314  return streamResizeBuffer(str, block_size_id);
315 }
316 
317 int roslz4_compress(roslz4_stream *str, int action) {
318  int ret;
319  stream_state *state = str->state;
320  if (action != ROSLZ4_RUN && action != ROSLZ4_FINISH) {
321  return ROSLZ4_PARAM_ERROR; // Unrecognized compression action
322  } else if (state->finished) {
323  return ROSLZ4_ERROR; // Cannot call action on finished stream
324  }
325 
326  if (!state->wrote_header) {
327  ret = writeHeader(str);
328  if (ret < 0) { return ret; }
329  state->wrote_header = 1;
330  }
331 
332  // Copy input to internal buffer, compressing when full or finishing stream
333  int read = 0, wrote = 0;
334  do {
335  read = inputToBuffer(str);
336  if (read < 0) { return read; }
337 
338  wrote = 0;
339  if (action == ROSLZ4_FINISH || state->buffer_offset == state->buffer_size) {
340  wrote = bufferToOutput(str);
341  if (wrote < 0) { return wrote; }
342  }
343  } while (read > 0 || wrote > 0);
344 
345  // Signal end of stream if finishing up, otherwise done
346  if (action == ROSLZ4_FINISH) {
347  return writeEOS(str);
348  } else {
349  return ROSLZ4_OK;
350  }
351 }
352 
354  streamStateFree(str);
355 }
356 
357 /*========================= Low level decompression =========================*/
358 
360  return streamStateAlloc(str);
361  // Can't allocate internal buffer, block size is unknown until header is read
362 }
363 
364 // Return 1 if header is present, 0 if more data is needed,
365 // LZ4 error code (< 0) if error
367  stream_state *state = str->state;
368  if (str->total_in >= 7) {
369  return 1;
370  }
371  // Populate header buffer
372  int to_copy = min(7 - str->total_in, str->input_left);
373  memcpy(state->header + str->total_in, str->input_next, to_copy);
374  advanceInput(str, to_copy);
375  if (str->total_in < 7) {
376  return 0;
377  }
378 
379  // Parse header buffer
380  unsigned char *header = (unsigned char*) state->header;
381  uint32_t magic_number = readUInt32(header);
382  if (magic_number != kMagicNumber) {
383  return ROSLZ4_DATA_ERROR; // Stream does not start with magic number
384  }
385  // Check descriptor flags
386  int version = (header[4] >> 6) & k2Bits;
387  int block_independence_flag = (header[4] >> 5) & k1Bits;
388  int block_checksum_flag = (header[4] >> 4) & k1Bits;
389  int stream_size_flag = (header[4] >> 3) & k1Bits;
390  int stream_checksum_flag = (header[4] >> 2) & k1Bits;
391  int reserved1 = (header[4] >> 1) & k1Bits;
392  int preset_dictionary_flag = (header[4] >> 0) & k1Bits;
393 
394  int reserved2 = (header[5] >> 7) & k1Bits;
395  int block_max_id = (header[5] >> 4) & k3Bits;
396  int reserved3 = (header[5] >> 0) & k4Bits;
397 
398  // LZ4 standard requirements
399  if (version != 1) {
400  return ROSLZ4_DATA_ERROR; // Wrong version number
401  }
402  if (reserved1 != 0 || reserved2 != 0 || reserved3 != 0) {
403  return ROSLZ4_DATA_ERROR; // Reserved bits must be 0
404  }
405  if (!(4 <= block_max_id && block_max_id <= 7)) {
406  return ROSLZ4_DATA_ERROR; // Invalid block size
407  }
408 
409  // Implementation requirements
410  if (stream_size_flag != 0) {
411  return ROSLZ4_DATA_ERROR; // Stream size not supported
412  }
413  if (preset_dictionary_flag != 0) {
414  return ROSLZ4_DATA_ERROR; // Dictionary not supported
415  }
416  if (block_independence_flag != 1) {
417  return ROSLZ4_DATA_ERROR; // Block dependence not supported
418  }
419  if (block_checksum_flag != 0) {
420  return ROSLZ4_DATA_ERROR; // Block checksums not supported
421  }
422  if (stream_checksum_flag != 1) {
423  return ROSLZ4_DATA_ERROR; // Must have stream checksum
424  }
425 
426  int header_checksum = (XXH32(header + 4, 2, 0) >> 8) & k8Bits;
427  int stored_header_checksum = (header[6] >> 0) & k8Bits;
428  if (header_checksum != stored_header_checksum) {
429  return ROSLZ4_DATA_ERROR; // Header checksum doesn't match
430  }
431 
432  int ret = streamResizeBuffer(str, block_max_id);
433  if (ret == ROSLZ4_OK) {
434  return 1;
435  } else {
436  return ret;
437  }
438 }
439 
440 // Read block size, return 1 if value is stored in state->block_size 0 otherwise
442  stream_state *state = str->state;
443  if (state->block_size_read < 4) {
444  fillUInt32(str, &state->block_size, &state->block_size_read);
445  if (state->block_size_read == 4) {
446  state->block_size = readUInt32((unsigned char*)&state->block_size);
447  state->block_uncompressed = ((unsigned)state->block_size >> 31) & k1Bits;
448  state->block_size &= 0x7FFFFFFF;
449  DEBUG("readBlockSize() Block size = %i uncompressed = %i\n",
450  state->block_size, state->block_uncompressed);
451  return 1;
452  } else {
453  return 0;
454  }
455  }
456  return 1;
457 }
458 
459 // Copy at most one blocks worth of data from input to internal buffer.
460 // Return 1 if whole block has been read, 0 if not, LZ4 error otherwise
462  stream_state *state = str->state;
463  if (state->block_size_read != 4 || state->block_size == kEndOfStream) {
464  return ROSLZ4_ERROR;
465  }
466 
467  int block_left = state->block_size - state->buffer_offset;
468  int to_copy = min(str->input_left, block_left);
469  memcpy(state->buffer + state->buffer_offset, str->input_next, to_copy);
470  advanceInput(str, to_copy);
471  state->buffer_offset += to_copy;
472  DEBUG("readBlock() Read %i bytes from input (block = %i/%i)\n",
473  to_copy, state->buffer_offset, state->block_size);
474  return state->buffer_offset == state->block_size;
475 }
476 
478  stream_state *state = str->state;
479  if (state->block_size_read != 4 || state->block_size != state->buffer_offset) {
480  // Internal error: Can't decompress block, it's not in buffer
481  return ROSLZ4_ERROR;
482  }
483 
484  if (state->block_uncompressed) {
485  if (str->output_left >= state->block_size) {
486  memcpy(str->output_next, state->buffer, state->block_size);
487  int ret = XXH32_update(state->xxh32_state, str->output_next,
488  state->block_size);
489  if (ret == XXH_ERROR) { return ROSLZ4_ERROR; }
490  advanceOutput(str, state->block_size);
491  state->block_size_read = 0;
492  state->buffer_offset = 0;
493  return ROSLZ4_OK;
494  } else {
495  return ROSLZ4_OUTPUT_SMALL;
496  }
497  } else {
498  int decomp_size;
499  decomp_size = LZ4_decompress_safe(state->buffer, str->output_next,
500  state->block_size, str->output_left);
501  if (decomp_size < 0) {
502  if (str->output_left >= state->buffer_size) {
503  return ROSLZ4_DATA_ERROR; // Must be a problem with the data stream
504  } else {
505  // Data error or output is small; increase output to disambiguate
506  return ROSLZ4_OUTPUT_SMALL;
507  }
508  } else {
509  int ret = XXH32_update(state->xxh32_state, str->output_next, decomp_size);
510  if (ret == XXH_ERROR) { return ROSLZ4_ERROR; }
511  advanceOutput(str, decomp_size);
512  state->block_size_read = 0;
513  state->buffer_offset = 0;
514  return ROSLZ4_OK;
515  }
516  }
517 }
518 
520  stream_state *state = str->state;
521  fillUInt32(str, &state->stream_checksum, &state->stream_checksum_read);
522  if (state->stream_checksum_read == 4) {
523  state->finished = 1;
524  state->stream_checksum = readUInt32((unsigned char*)&state->stream_checksum);
525  uint32_t checksum = XXH32_digest(state->xxh32_state);
526  state->xxh32_state = NULL;
527  if (checksum == state->stream_checksum) {
528  return ROSLZ4_STREAM_END;
529  } else {
530  return ROSLZ4_DATA_ERROR;
531  }
532  }
533  return ROSLZ4_OK;
534 }
535 
537  stream_state *state = str->state;
538  if (state->finished) {
539  return ROSLZ4_ERROR; // Already reached end of stream
540  }
541 
542  // Return if header isn't present or error was encountered
543  int ret = processHeader(str);
544  if (ret <= 0) {
545  return ret;
546  }
547 
548  // Read in blocks and decompress them as long as there's data to be processed
549  while (str->input_left > 0) {
550  ret = readBlockSize(str);
551  if (ret == 0) { return ROSLZ4_OK; }
552 
553  if (state->block_size == kEndOfStream) {
554  return readChecksum(str);
555  }
556 
557  ret = readBlock(str);
558  if (ret == 0) { return ROSLZ4_OK; }
559  else if (ret < 0) { return ret; }
560 
561  ret = decompressBlock(str);
562  if (ret < 0) { return ret; }
563  }
564  return ROSLZ4_OK;
565 }
566 
568  streamStateFree(str);
569 }
570 
571 /*=================== Oneshot compression / decompression ===================*/
572 
573 int roslz4_buffToBuffCompress(char *input, unsigned int input_size,
574  char *output, unsigned int *output_size,
575  int block_size_id) {
576  roslz4_stream stream;
577  stream.input_next = input;
578  stream.input_left = input_size;
579  stream.output_next = output;
580  stream.output_left = *output_size;
581 
582  int ret;
583  ret = roslz4_compressStart(&stream, block_size_id);
584  if (ret != ROSLZ4_OK) {
585  roslz4_compressEnd(&stream);
586  return ret;
587  }
588 
589  while (stream.input_left > 0 && ret != ROSLZ4_STREAM_END) {
590  ret = roslz4_compress(&stream, ROSLZ4_FINISH);
591  if (ret == ROSLZ4_ERROR || ret == ROSLZ4_OUTPUT_SMALL) {
592  roslz4_compressEnd(&stream);
593  return ret;
594  }
595  }
596 
597  *output_size = *output_size - stream.output_left;
598  roslz4_compressEnd(&stream);
599 
600  if (stream.input_left == 0 && ret == ROSLZ4_STREAM_END) {
601  return ROSLZ4_OK; // Success
602  } else {
603  return ROSLZ4_ERROR; // User did not provide exact buffer
604  }
605 }
606 
607 int roslz4_buffToBuffDecompress(char *input, unsigned int input_size,
608  char *output, unsigned int *output_size) {
609  roslz4_stream stream;
610  stream.input_next = input;
611  stream.input_left = input_size;
612  stream.output_next = output;
613  stream.output_left = *output_size;
614 
615  int ret;
616  ret = roslz4_decompressStart(&stream);
617  if (ret != ROSLZ4_OK) { return ret; }
618 
619  while (stream.input_left > 0 && ret != ROSLZ4_STREAM_END) {
620  ret = roslz4_decompress(&stream);
621  if (ret < 0) {
622  roslz4_decompressEnd(&stream);
623  return ret;
624  }
625  }
626 
627  *output_size = *output_size - stream.output_left;
628  roslz4_decompressEnd(&stream);
629 
630  if (stream.input_left == 0 && ret == ROSLZ4_STREAM_END) {
631  return ROSLZ4_OK; // Success
632  } else {
633  return ROSLZ4_ERROR; // User did not provide exact buffer
634  }
635 }
const int ROSLZ4_MEMORY_ERROR
Definition: lz4s.h:45
U32 XXH32(const void *input, int len, U32 seed)
Definition: xxhash.c:265
void * xxh32_state
Definition: lz4s.c:90
int buffer_offset
Definition: lz4s.c:86
U32 XXH32_digest(void *state_in)
Definition: xxhash.c:471
const uint8_t k1Bits
Definition: lz4s.c:55
int writeEOS(roslz4_stream *str)
Definition: lz4s.c:149
void advanceOutput(roslz4_stream *str, int nbytes)
Definition: lz4s.c:110
void * XXH32_init(U32 seed)
Definition: xxhash.c:331
void advanceInput(roslz4_stream *str, int nbytes)
Definition: lz4s.c:104
int writeHeader(roslz4_stream *str)
Definition: lz4s.c:124
int stream_checksum_read
Definition: lz4s.c:101
int total_out
Definition: lz4s.h:65
int block_size_id
Definition: lz4s.h:67
uint32_t readUInt32(unsigned char *buffer)
Definition: lz4s.c:61
const int ROSLZ4_OUTPUT_SMALL
Definition: lz4s.h:48
void roslz4_decompressEnd(roslz4_stream *str)
Definition: lz4s.c:567
int block_independence_flag
Definition: lz4s.c:80
void streamStateFree(roslz4_stream *str)
Definition: lz4s.c:293
int finished
Definition: lz4s.c:88
int total_in
Definition: lz4s.h:64
const uint8_t k2Bits
Definition: lz4s.c:56
int roslz4_compress(roslz4_stream *str, int action)
Definition: lz4s.c:317
void roslz4_compressEnd(roslz4_stream *str)
Definition: lz4s.c:353
int processHeader(roslz4_stream *str)
Definition: lz4s.c:366
char * buffer
Definition: lz4s.c:84
const int ROSLZ4_STREAM_END
Definition: lz4s.h:51
int roslz4_buffToBuffCompress(char *input, unsigned int input_size, char *output, unsigned int *output_size, int block_size_id)
Definition: lz4s.c:573
int input_left
Definition: lz4s.h:59
int readBlockSize(roslz4_stream *str)
Definition: lz4s.c:441
int block_size_read
Definition: lz4s.c:98
const uint8_t k8Bits
Definition: lz4s.c:59
int streamStateAlloc(roslz4_stream *str)
Definition: lz4s.c:235
void fillUInt32(roslz4_stream *str, uint32_t *dest_val, int *offset)
Definition: lz4s.c:116
const uint8_t k3Bits
Definition: lz4s.c:57
const int ROSLZ4_PARAM_ERROR
Definition: lz4s.h:46
char * output_next
Definition: lz4s.h:61
void * state
Definition: lz4s.h:70
int readBlock(roslz4_stream *str)
Definition: lz4s.c:461
int roslz4_decompressStart(roslz4_stream *str)
Definition: lz4s.c:359
char * input_next
Definition: lz4s.h:58
int bufferToOutput(roslz4_stream *str)
Definition: lz4s.c:170
int buffer_size
Definition: lz4s.c:85
void writeUInt32(unsigned char *buffer, uint32_t val)
Definition: lz4s.c:66
const int ROSLZ4_DATA_ERROR
Definition: lz4s.h:47
const int ROSLZ4_OK
Definition: lz4s.h:50
int block_checksum_flag
Definition: lz4s.c:81
uint32_t block_size
Definition: lz4s.c:97
XXH_errorcode XXH32_update(void *state_in, const void *input, int len)
Definition: xxhash.c:406
const uint32_t kEndOfStream
Definition: lz4s.c:52
int decompressBlock(roslz4_stream *str)
Definition: lz4s.c:477
const int ROSLZ4_FINISH
Definition: lz4s.h:55
int block_uncompressed
Definition: lz4s.c:99
const uint32_t kMagicNumber
Definition: lz4s.c:51
const int ROSLZ4_ERROR
Definition: lz4s.h:49
int min(int a, int b)
Definition: lz4s.c:73
int readChecksum(roslz4_stream *str)
Definition: lz4s.c:519
int streamResizeBuffer(roslz4_stream *str, int block_size_id)
Definition: lz4s.c:277
int inputToBuffer(roslz4_stream *str)
Definition: lz4s.c:214
int wrote_header
Definition: lz4s.c:93
int roslz4_decompress(roslz4_stream *str)
Definition: lz4s.c:536
#define DEBUG(...)
Definition: lz4s.c:47
const int ROSLZ4_RUN
Definition: lz4s.h:54
int stream_checksum_flag
Definition: lz4s.c:82
int output_left
Definition: lz4s.h:62
int roslz4_compressStart(roslz4_stream *str, int block_size_id)
Definition: lz4s.c:311
char header[10]
Definition: lz4s.c:96
int roslz4_blockSizeFromIndex(int block_id)
Definition: lz4s.c:307
const uint8_t k4Bits
Definition: lz4s.c:58
int roslz4_buffToBuffDecompress(char *input, unsigned int input_size, char *output, unsigned int *output_size)
Definition: lz4s.c:607
uint32_t stream_checksum
Definition: lz4s.c:100


roslz4
Author(s): Ben Charrow
autogenerated on Mon Nov 2 2020 03:52:18