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


roslz4
Author(s): Ben Charrow
autogenerated on Mon Feb 28 2022 23:33:18