Skip to content

Commit

Permalink
Implemented compress/decompress output buffer safe sizes
Browse files Browse the repository at this point in the history
  • Loading branch information
g1mv committed Jun 29, 2015
1 parent f3c26d0 commit bf87ab2
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 13 deletions.
4 changes: 2 additions & 2 deletions benchmark/src/benchmark.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ int main(int argc, char *argv[]) {
if (fuzzer) {
srand((unsigned int) (time(NULL) * 14521937821257379531llu));
uncompressed_size = (uint_fast64_t) (((uint64_t) (rand() * 100000000llu)) / RAND_MAX);
memory_allocated = density_buffer_minimum_compressed_output_size(uncompressed_size);
memory_allocated = density_buffer_compress_safe_size(uncompressed_size);
in = malloc(memory_allocated * sizeof(uint8_t));
uint8_t value = (uint8_t) rand();
for (int count = 0; count < uncompressed_size; count++) {
Expand All @@ -145,7 +145,7 @@ int main(int argc, char *argv[]) {

// Allocate memory and copy file to memory
uncompressed_size = (uint_fast64_t) file_attributes.st_size;
memory_allocated = density_buffer_minimum_compressed_output_size(uncompressed_size);
memory_allocated = density_buffer_compress_safe_size(uncompressed_size);
in = malloc(memory_allocated * sizeof(uint8_t));
fread(in, sizeof(uint8_t), uncompressed_size, file);
fclose(file);
Expand Down
27 changes: 20 additions & 7 deletions src/buffers/buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@

#include "buffer.h"

DENSITY_WINDOWS_EXPORT uint_fast64_t density_buffer_minimum_compressed_output_size(const uint_fast64_t input_size) {
DENSITY_WINDOWS_EXPORT uint_fast64_t density_buffer_compress_safe_size(const uint_fast64_t input_size) {
uint_fast64_t longest_output_size = 0;

// Chameleon longest output
Expand Down Expand Up @@ -69,19 +69,36 @@ DENSITY_WINDOWS_EXPORT uint_fast64_t density_buffer_minimum_compressed_output_si
return longest_output_size;
}

DENSITY_WINDOWS_EXPORT uint_fast64_t density_buffer_minimum_decompressed_output_size(const uint_fast64_t input_size) {
DENSITY_WINDOWS_EXPORT uint_fast64_t density_buffer_decompress_safe_size(const uint_fast64_t input_size) {
uint_fast64_t longest_output_size = 0;

// Chameleon longest output
uint_fast64_t chameleon_longest_output_size = 0;
uint_fast64_t chameleon_structure_size = 0;
chameleon_structure_size += sizeof(density_header);
chameleon_structure_size += sizeof(density_chameleon_signature) * (1 + (input_size >> (4 + 3))); // Signature space (1 bit <=> 2 bytes)
chameleon_structure_size += sizeof(density_footer);
if (input_size >= chameleon_structure_size)
chameleon_longest_output_size += ((input_size - chameleon_structure_size) << 1); // Assuming everything was compressed
longest_output_size = chameleon_longest_output_size;

// Cheetah longest output
uint_fast64_t cheetah_longest_output_size = 0;
uint_fast64_t cheetah_structure_size = 0;
cheetah_structure_size += sizeof(density_header);
if (input_size >= cheetah_structure_size)
cheetah_longest_output_size += ((input_size - cheetah_structure_size) << 5); // All predictions, 1 bit <=> 4 bytes
if (cheetah_longest_output_size > longest_output_size)
longest_output_size = cheetah_longest_output_size;

// Lion longest output
uint_fast64_t lion_longest_output_size = 0;
uint_fast64_t lion_structure_size = 0;
lion_structure_size += sizeof(density_header);
if (input_size >= lion_structure_size)
lion_longest_output_size += ((input_size - lion_structure_size) << 5); // All predictions, 1 bit <=> 4 bytes
if (lion_longest_output_size > longest_output_size)
longest_output_size = lion_longest_output_size;

return longest_output_size;
}

Expand All @@ -94,9 +111,6 @@ DENSITY_FORCE_INLINE density_buffer_processing_result density_buffer_make_result
}

DENSITY_WINDOWS_EXPORT DENSITY_FORCE_INLINE density_buffer_processing_result density_buffer_compress(const uint8_t *restrict input_buffer, const uint_fast64_t input_size, uint8_t *restrict output_buffer, const uint_fast64_t output_size, const DENSITY_COMPRESSION_MODE compression_mode, const DENSITY_BLOCK_TYPE block_type, void *(*mem_alloc)(size_t), void (*mem_free)(void *)) {
if (output_size < density_buffer_minimum_compressed_output_size(input_size))
return density_buffer_make_result(DENSITY_BUFFER_STATE_ERROR_OUTPUT_BUFFER_TOO_SMALL, 0, 0);

// Variables setup
const uint8_t *in = input_buffer;
uint8_t *out = output_buffer;
Expand Down Expand Up @@ -144,7 +158,6 @@ DENSITY_WINDOWS_EXPORT DENSITY_FORCE_INLINE density_buffer_processing_result den
// Variables setup
const uint8_t *in = input_buffer;
uint8_t *out = output_buffer;
DENSITY_BUFFER_STATE state;

// Header
density_header main_header;
Expand Down
4 changes: 2 additions & 2 deletions src/buffers/buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@
#include "../core/lion/lion_encode.h"
#include "../core/lion/lion_decode.h"

DENSITY_WINDOWS_EXPORT uint_fast64_t density_buffer_minimum_compressed_output_size(const uint_fast64_t);
DENSITY_WINDOWS_EXPORT uint_fast64_t density_buffer_compress_safe_size(const uint_fast64_t);

DENSITY_WINDOWS_EXPORT uint_fast64_t density_buffer_minimum_decompressed_output_size(const uint_fast64_t);
DENSITY_WINDOWS_EXPORT uint_fast64_t density_buffer_decompress_safe_size(const uint_fast64_t);

DENSITY_WINDOWS_EXPORT density_buffer_processing_result density_buffer_compress(const uint8_t*, const uint_fast64_t, uint8_t*, const uint_fast64_t, const DENSITY_COMPRESSION_MODE, const DENSITY_BLOCK_TYPE, void *(*)(size_t), void (*)(void *));

Expand Down
14 changes: 12 additions & 2 deletions src/density_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,9 +154,19 @@ DENSITY_WINDOWS_EXPORT uint8_t density_version_revision(void);
* *
***********************************************************************************************************************/

DENSITY_WINDOWS_EXPORT uint_fast64_t density_buffer_minimum_compressed_output_size(const uint_fast64_t);
/*
* Return an output buffer byte size which guarantees enough space for encoding input_size bytes
*
* @param input_size the size of the input data which is about to be compressed
*/
DENSITY_WINDOWS_EXPORT uint_fast64_t density_buffer_compress_safe_size(const uint_fast64_t input_size);

DENSITY_WINDOWS_EXPORT uint_fast64_t density_buffer_minimum_decompressed_output_size(const uint_fast64_t);
/*
* Return an output buffer byte size which guarantees enough space for decoding input_size bytes
*
* @param input_size the size of the input data which is about to be decompressed
*/
DENSITY_WINDOWS_EXPORT uint_fast64_t density_buffer_decompress_safe_size(const uint_fast64_t input_size);

/*
* Compress an input_buffer of input_size bytes and store the result in output_buffer, using compression_mode and block_type.
Expand Down

0 comments on commit bf87ab2

Please sign in to comment.