static SquashStatus squash_yalz77_compress_buffer (SquashCodec* codec, size_t* compressed_length, uint8_t compressed[SQUASH_ARRAY_PARAM(*compressed_length)], size_t uncompressed_length, const uint8_t uncompressed[SQUASH_ARRAY_PARAM(uncompressed_length)], SquashOptions* options) { const size_t searchlen = squash_codec_get_option_size_index (codec, options, SQUASH_YALZ77_OPT_SEARCH_LENGTH); const size_t blocksize = squash_codec_get_option_size_index (codec, options, SQUASH_YALZ77_OPT_BLOCK_SIZE); try { lz77::compress_t compress(searchlen, blocksize); std::string res = compress.feed(uncompressed, uncompressed + uncompressed_length); if (res.size() > *compressed_length) return SQUASH_FAILED; memcpy(compressed, res.c_str(), res.size()); *compressed_length = res.size(); return SQUASH_OK; } catch (const std::bad_alloc& e) { return SQUASH_MEMORY; } catch (...) { return SQUASH_FAILED; } }
static SquashStatus squash_brotli_decompress_buffer (SquashCodec* codec, size_t* decompressed_size, uint8_t decompressed[SQUASH_ARRAY_PARAM(*decompressed_size)], size_t compressed_size, const uint8_t compressed[SQUASH_ARRAY_PARAM(compressed_size)], SquashOptions* options) { BrotliResult res; size_t total_out = 0; size_t available_in = compressed_size; const uint8_t* next_in = compressed; size_t available_out = *decompressed_size; uint8_t* next_out = decompressed; BrotliState* s = BrotliCreateState(squash_brotli_malloc, squash_brotli_free, squash_codec_get_context (codec)); try { res = BrotliDecompressStream (&available_in, &next_in, &available_out, &next_out, &total_out, s); } catch (const std::bad_alloc& e) { (void) e; BrotliDestroyState(s); return squash_error (SQUASH_MEMORY); } catch (...) { BrotliDestroyState(s); return squash_error (SQUASH_FAILED); } BrotliDestroyState(s); *decompressed_size = total_out; return squash_brotli_status_to_squash_status (res); }
static SquashStatus squash_yalz77_decompress_buffer (SquashCodec* codec, size_t* decompressed_length, uint8_t decompressed[SQUASH_ARRAY_PARAM(*decompressed_length)], size_t compressed_length, const uint8_t compressed[SQUASH_ARRAY_PARAM(compressed_length)], SquashOptions* options) { try { lz77::decompress_t decompress; std::string remaining; bool done = decompress.feed(compressed, compressed + compressed_length, remaining); const std::string& res = decompress.result(); if (res.size() > *decompressed_length) return SQUASH_FAILED; memcpy(decompressed, res.c_str(), res.size()); *decompressed_length = res.size(); return (done && remaining.empty()) ? SQUASH_OK : SQUASH_FAILED; } catch (const std::bad_alloc& e) { return SQUASH_MEMORY; } catch (...) { return SQUASH_FAILED; } }
static SquashStatus squash_gipfeli_compress_buffer_unsafe (SquashCodec* codec, size_t* compressed_length, uint8_t compressed[SQUASH_ARRAY_PARAM(*compressed_length)], size_t uncompressed_length, const uint8_t uncompressed[SQUASH_ARRAY_PARAM(uncompressed_length)], SquashOptions* options) { util::compression::Compressor* compressor = util::compression::NewGipfeliCompressor(); util::compression::UncheckedByteArraySink sink((char*) compressed); util::compression::ByteArraySource source((const char*) uncompressed, uncompressed_length); SquashStatus res; try { *compressed_length = compressor->CompressStream (&source, &sink); res = SQUASH_OK; } catch (const std::bad_alloc& e) { res = squash_error (SQUASH_MEMORY); } catch (const std::overflow_error& e) { res = squash_error (SQUASH_BUFFER_FULL); } catch (...) { res = squash_error (SQUASH_FAILED); } delete compressor; if (res == SQUASH_OK && *compressed_length == 0) res = squash_error (SQUASH_FAILED); return res; }
static SquashStatus squash_fari_decompress_buffer (SquashCodec* codec, size_t* decompressed_length, uint8_t decompressed[SQUASH_ARRAY_PARAM(*decompressed_length)], size_t compressed_length, const uint8_t compressed[SQUASH_ARRAY_PARAM(compressed_length)], SquashOptions* options) { int fari_e = (size_t) fa_decompress ((const unsigned char*) compressed, (unsigned char*) decompressed, compressed_length, decompressed_length); switch (fari_e) { case 0: return SQUASH_OK; break; case 1: return SQUASH_MEMORY; break; case 2: return SQUASH_BUFFER_FULL; break; default: return SQUASH_FAILED; break; } }
static SquashStatus squash_lz4_decompress_buffer (SquashCodec* codec, size_t* decompressed_size, uint8_t decompressed[SQUASH_ARRAY_PARAM(*decompressed_size)], size_t compressed_size, const uint8_t compressed[SQUASH_ARRAY_PARAM(compressed_size)], SquashOptions* options) { #if INT_MAX < SIZE_MAX if (SQUASH_UNLIKELY(INT_MAX < compressed_size) || SQUASH_UNLIKELY(INT_MAX < *decompressed_size)) return squash_error (SQUASH_RANGE); #endif int lz4_e = LZ4_decompress_safe ((char*) compressed, (char*) decompressed, (int) compressed_size, (int) *decompressed_size); if (lz4_e < 0) { return SQUASH_FAILED; } else { #if SIZE_MAX < INT_MAX if (SQUASH_UNLIKELY(SIZE_MAX < lz4_e)) return squash_error (SQUASH_RANGE); #endif *decompressed_size = (size_t) lz4_e; return SQUASH_OK; } }
/** * @brief Decompress a buffer with an existing @ref SquashOptions * * @param codec The codec to use * @param[out] decompressed Location to store the decompressed data * @param[in,out] decompressed_length Location storing the size of the * @a decompressed buffer on input, replaced with the actual size of * the decompressed data * @param compressed The compressed data * @param compressed_length Length of the compressed data (in bytes) * @param options Compression options * @return A status code */ SquashStatus squash_codec_decompress_with_options (SquashCodec* codec, size_t* decompressed_length, uint8_t decompressed[SQUASH_ARRAY_PARAM(*decompressed_length)], size_t compressed_length, const uint8_t compressed[SQUASH_ARRAY_PARAM(compressed_length)], SquashOptions* options) { SquashCodecImpl* impl = NULL; assert (codec != NULL); impl = squash_codec_get_impl (codec); if (impl == NULL) return squash_error (SQUASH_UNABLE_TO_LOAD); if (decompressed == compressed) return squash_error (SQUASH_INVALID_BUFFER); if (impl->decompress_buffer != NULL) { SquashStatus res; res = impl->decompress_buffer (codec, decompressed_length, decompressed, compressed_length, compressed, squash_object_ref (options)); squash_object_unref (options); return res; } else { SquashStatus status; SquashStream* stream; stream = squash_codec_create_stream_with_options (codec, SQUASH_STREAM_DECOMPRESS, options); stream->next_in = compressed; stream->avail_in = compressed_length; stream->next_out = decompressed; stream->avail_out = *decompressed_length; do { status = squash_stream_process (stream); } while (status == SQUASH_PROCESSING); if (status == SQUASH_END_OF_STREAM) { status = SQUASH_OK; *decompressed_length = stream->total_out; } else if (status == SQUASH_OK) { do { status = squash_stream_finish (stream); } while (status == SQUASH_PROCESSING); if (status == SQUASH_OK) { *decompressed_length = stream->total_out; } } assert (stream->stream_type == SQUASH_STREAM_DECOMPRESS); squash_object_unref (stream); return status; } }
static SquashStatus squash_brotli_decompress_buffer (SquashCodec* codec, size_t* decompressed_size, uint8_t decompressed[SQUASH_ARRAY_PARAM(*decompressed_size)], size_t compressed_size, const uint8_t compressed[SQUASH_ARRAY_PARAM(compressed_size)], SquashOptions* options) { const BrotliResult res = BrotliDecompressBuffer(compressed_size, compressed, decompressed_size, decompressed); return SQUASH_LIKELY(res == BROTLI_RESULT_SUCCESS) ? SQUASH_OK : squash_error (SQUASH_BUFFER_FULL); }
static SquashStatus squash_ms_decompress_buffer (SquashCodec* codec, size_t* decompressed_length, uint8_t decompressed[SQUASH_ARRAY_PARAM(*decompressed_length)], size_t compressed_length, const uint8_t compressed[SQUASH_ARRAY_PARAM(compressed_length)], SquashOptions* options) { MSCompStatus status = ms_decompress (squash_ms_format_from_codec (codec), compressed, compressed_length, decompressed, decompressed_length); return squash_ms_status_to_squash_status (status); }
static SquashStatus squash_pithy_compress_buffer (SquashCodec* codec, size_t* compressed_size, uint8_t compressed[SQUASH_ARRAY_PARAM(*compressed_size)], size_t uncompressed_size, const uint8_t uncompressed[SQUASH_ARRAY_PARAM(uncompressed_size)], SquashOptions* options) { const int level = squash_options_get_int_at (options, codec, SQUASH_PITHY_OPT_LEVEL); *compressed_size = pithy_Compress ((const char*) uncompressed, uncompressed_size, (char*) compressed, *compressed_size, level); return (*compressed_size != 0) ? SQUASH_OK : SQUASH_FAILED; }
static SquashStatus squash_ms_compress_buffer (SquashCodec* codec, size_t* compressed_size, uint8_t compressed[SQUASH_ARRAY_PARAM(*compressed_size)], size_t uncompressed_size, const uint8_t uncompressed[SQUASH_ARRAY_PARAM(uncompressed_size)], SquashOptions* options) { MSCompStatus status = ms_compress (squash_ms_format_from_codec (codec), uncompressed, uncompressed_size, compressed, compressed_size); return squash_ms_status_to_squash_status (status); }
static SquashStatus squash_fari_compress_buffer (SquashCodec* codec, size_t* compressed_length, uint8_t compressed[SQUASH_ARRAY_PARAM(*compressed_length)], size_t uncompressed_length, const uint8_t uncompressed[SQUASH_ARRAY_PARAM(uncompressed_length)], SquashOptions* options) { int fari_e = fa_compress ((const unsigned char*) uncompressed, (unsigned char*) compressed, uncompressed_length, compressed_length); return fari_e == 0 ? SQUASH_OK : SQUASH_FAILED; }
static SquashStatus squash_wflz_compress_buffer (SquashCodec* codec, size_t* compressed_size, uint8_t compressed[SQUASH_ARRAY_PARAM(*compressed_size)], size_t uncompressed_size, const uint8_t uncompressed[SQUASH_ARRAY_PARAM(uncompressed_size)], SquashOptions* options) { const char* codec_name = squash_codec_get_name (codec); const uint32_t swap = ((uint32_t) squash_options_get_int_at (options, codec, SQUASH_WFLZ_OPT_ENDIANNESS) != SQUASH_WFLZ_HOST_ORDER); const int level = squash_options_get_int_at (options, codec, SQUASH_WFLZ_OPT_LEVEL); #if UINT32_MAX < SIZE_MAX if (SQUASH_UNLIKELY(UINT32_MAX < uncompressed_size)) return squash_error (SQUASH_RANGE); #endif if (*compressed_size < wfLZ_GetMaxCompressedSize ((uint32_t) uncompressed_size)) { return squash_error (SQUASH_BUFFER_FULL); } uint8_t* work_mem = (uint8_t*) malloc (wfLZ_GetWorkMemSize ()); uint32_t wres; if (codec_name[4] == '\0') { if (level == 1) { wres = wfLZ_CompressFast (uncompressed, (uint32_t) uncompressed_size, compressed, work_mem, swap); } else { wres = wfLZ_Compress (uncompressed, (uint32_t) uncompressed_size, compressed, work_mem, swap); } } else { wres = wfLZ_ChunkCompress ((uint8_t*) uncompressed, (uint32_t) uncompressed_size, squash_options_get_size_at (options, codec, SQUASH_WFLZ_OPT_CHUNK_SIZE), compressed, work_mem, swap, level == 1 ? 1 : 0); } #if SIZE_MAX < UINT32_MAX if (SQUASH_UNLIKELY(SIZE_MAX < wres)) { free (work_mem); return squash_error (SQUASH_RANGE); } #endif *compressed_size = (size_t) wres; free (work_mem); return SQUASH_LIKELY(*compressed_size > 0) ? SQUASH_OK : squash_error (SQUASH_FAILED); }
static SquashStatus squash_brieflz_compress_buffer (SquashCodec* codec, size_t* compressed_size, uint8_t compressed[SQUASH_ARRAY_PARAM(*compressed_size)], size_t uncompressed_size, const uint8_t uncompressed[SQUASH_ARRAY_PARAM(uncompressed_size)], SquashOptions* options) { uint8_t *dst = compressed; void *workmem = NULL; size_t size; #if ULONG_MAX < SIZE_MAX if (SQUASH_UNLIKELY(ULONG_MAX < uncompressed_size) || SQUASH_UNLIKELY(ULONG_MAX < *compressed_size)) return squash_error (SQUASH_RANGE); #endif if (SQUASH_UNLIKELY((unsigned long) *compressed_size < squash_brieflz_get_max_compressed_size (codec, uncompressed_size))) { return squash_error (SQUASH_BUFFER_FULL); } size = write_varuint64 (dst, *compressed_size, uncompressed_size); if (SQUASH_UNLIKELY(size == 0)) { return squash_error (SQUASH_BUFFER_FULL); } dst += size; workmem = malloc (blz_workmem_size ((unsigned long) uncompressed_size)); if (SQUASH_UNLIKELY(workmem == NULL)) { return squash_error (SQUASH_MEMORY); } size += blz_pack (uncompressed, dst, (unsigned long) uncompressed_size, workmem); free(workmem); #if SIZE_MAX < ULONG_MAX if (SQUASH_UNLIKELY(SIZE_MAX < size)) return squash_error (SQUASH_RANGE); #endif *compressed_size = size; return SQUASH_OK; }
static SquashStatus squash_snappy_compress_buffer (SquashCodec* codec, size_t* compressed_length, uint8_t compressed[SQUASH_ARRAY_PARAM(*compressed_length)], size_t uncompressed_length, const uint8_t uncompressed[SQUASH_ARRAY_PARAM(uncompressed_length)], SquashOptions* options) { snappy_status e; e = snappy_compress ((char*) uncompressed, uncompressed_length, (char*) compressed, compressed_length); return squash_snappy_status (e); }
static SquashStatus squash_fastlz_compress_buffer (SquashCodec* codec, size_t* compressed_length, uint8_t compressed[SQUASH_ARRAY_PARAM(*compressed_length)], size_t uncompressed_length, const uint8_t uncompressed[SQUASH_ARRAY_PARAM(uncompressed_length)], SquashOptions* options) { *compressed_length = fastlz_compress_level (squash_codec_get_option_int_index (codec, options, SQUASH_FASTLZ_OPT_LEVEL), (const void*) uncompressed, (int) uncompressed_length, (void*) compressed); return (*compressed_length == 0) ? squash_error (SQUASH_FAILED) : SQUASH_OK; }
static SquashStatus squash_copy_decompress_buffer (SquashCodec* codec, size_t* decompressed_size, uint8_t decompressed[SQUASH_ARRAY_PARAM(*decompressed_size)], size_t compressed_size, const uint8_t compressed[SQUASH_ARRAY_PARAM(compressed_size)], SquashOptions* options) { if (SQUASH_UNLIKELY(*decompressed_size < compressed_size)) return squash_error (SQUASH_BUFFER_FULL); memcpy (decompressed, compressed, compressed_size); *decompressed_size = compressed_size; return SQUASH_OK; }
static SquashStatus squash_wflz_decompress_buffer (SquashCodec* codec, size_t* decompressed_size, uint8_t decompressed[SQUASH_ARRAY_PARAM(*decompressed_size)], size_t compressed_size, const uint8_t compressed[SQUASH_ARRAY_PARAM(compressed_size)], SquashOptions* options) { const char* codec_name = squash_codec_get_name (codec); uint32_t decompressed_s; if (SQUASH_UNLIKELY(compressed_size < 12)) return squash_error (SQUASH_BUFFER_EMPTY); decompressed_s = wfLZ_GetDecompressedSize (compressed); #if SIZE_MAX < UINT32_MAX if (SQUASH_UNLIKELY(SIZE_MAX < decompressed_s)) return squash_error (SQUASH_RANGE); #endif if (SQUASH_UNLIKELY(decompressed_s == 0)) return squash_error (SQUASH_INVALID_BUFFER); if (SQUASH_UNLIKELY(decompressed_s > *decompressed_size)) return squash_error (SQUASH_BUFFER_FULL); if (codec_name[4] == '\0') { wfLZ_Decompress (compressed, decompressed); } else { uint8_t* dest = decompressed; uint32_t* chunk = NULL; uint8_t* compressed_block; while ( (compressed_block = wfLZ_ChunkDecompressLoop ((uint8_t*) compressed, &chunk)) != NULL ) { const uint32_t chunk_size = wfLZ_GetDecompressedSize (compressed_block); if (SQUASH_UNLIKELY((dest + chunk_size) > (decompressed + *decompressed_size))) return squash_error (SQUASH_BUFFER_FULL); wfLZ_Decompress (compressed_block, dest); dest += chunk_size; } } *decompressed_size = decompressed_s; return SQUASH_OK; }
static SquashStatus squash_brotli_compress_buffer (SquashCodec* codec, size_t* compressed_size, uint8_t compressed[SQUASH_ARRAY_PARAM(*compressed_size)], size_t uncompressed_size, const uint8_t uncompressed[SQUASH_ARRAY_PARAM(uncompressed_size)], SquashOptions* options) { const int quality = squash_options_get_int_at (options, codec, SQUASH_BROTLI_OPT_LEVEL); const int lgwin = squash_options_get_int_at (options, codec, SQUASH_BROTLI_OPT_WINDOW_SIZE); const BrotliEncoderMode mode = (BrotliEncoderMode) squash_options_get_int_at (options, codec, SQUASH_BROTLI_OPT_MODE); const int res = BrotliEncoderCompress (quality, lgwin, mode, uncompressed_size, uncompressed, compressed_size, compressed); return SQUASH_LIKELY(res == 1) ? SQUASH_OK : squash_error (SQUASH_BUFFER_FULL); }
/** * @brief Decompress a buffer * * @param codec The name of the codec to use * @param[out] decompressed Location to store the decompressed data * @param[in,out] decompressed_length Location storing the size of the * @a decompressed buffer on input, replaced with the actual size of * the decompressed data * @param compressed The compressed data * @param compressed_length Length of the compressed data (in bytes) * @param options Decompression options, or *NULL* to use the defaults * @return A status code */ SquashStatus squash_decompress_with_options (const char* codec, size_t* decompressed_length, uint8_t decompressed[SQUASH_ARRAY_PARAM(*decompressed_length)], size_t compressed_length, const uint8_t compressed[SQUASH_ARRAY_PARAM(compressed_length)], SquashOptions* options) { SquashCodec* codec_real = squash_get_codec (codec); if (codec_real == NULL) return squash_error (SQUASH_NOT_FOUND); return squash_codec_decompress_with_options (codec_real, decompressed_length, decompressed, compressed_length, compressed, options); }
static SquashStatus squash_lz4_compress_buffer (SquashCodec* codec, size_t* compressed_size, uint8_t compressed[SQUASH_ARRAY_PARAM(*compressed_size)], size_t uncompressed_size, const uint8_t uncompressed[SQUASH_ARRAY_PARAM(uncompressed_size)], SquashOptions* options) { int level = squash_codec_get_option_int_index (codec, options, SQUASH_LZ4_OPT_LEVEL); #if INT_MAX < SIZE_MAX if (SQUASH_UNLIKELY(INT_MAX < uncompressed_size) || SQUASH_UNLIKELY(INT_MAX < *compressed_size)) return squash_error (SQUASH_RANGE); #endif int lz4_r; if (level == 7) { lz4_r = LZ4_compress_limitedOutput ((char*) uncompressed, (char*) compressed, (int) uncompressed_size, (int) *compressed_size); } else if (level < 7) { lz4_r = LZ4_compress_fast ((const char*) uncompressed, (char*) compressed, (int) uncompressed_size, (int) *compressed_size, squash_lz4_level_to_fast_mode (level)); } else if (level < 17) { lz4_r = LZ4_compressHC2_limitedOutput ((char*) uncompressed, (char*) compressed, (int) uncompressed_size, (int) *compressed_size, squash_lz4_level_to_hc_level (level)); } else { squash_assert_unreachable(); } #if SIZE_MAX < INT_MAX if (SQUASH_UNLIKELY(SIZE_MAX < lz4_r)) return squash_error (SQUASH_RANGE); #endif *compressed_size = lz4_r; return SQUASH_UNLIKELY(lz4_r == 0) ? squash_error (SQUASH_BUFFER_FULL) : SQUASH_OK; }
static SquashStatus squash_brotli_decompress_buffer (SquashCodec* codec, size_t* decompressed_length, uint8_t decompressed[SQUASH_ARRAY_PARAM(*decompressed_length)], size_t compressed_length, const uint8_t compressed[SQUASH_ARRAY_PARAM(compressed_length)], SquashOptions* options) { try { int res = BrotliDecompressBuffer (compressed_length, compressed, decompressed_length, decompressed); return (res == 1) ? SQUASH_OK : SQUASH_FAILED; } catch (const std::bad_alloc& e) { return SQUASH_MEMORY; } catch (...) { return SQUASH_FAILED; } }
static size_t squash_brieflz_get_uncompressed_size (SquashCodec* codec, size_t compressed_size, const uint8_t compressed[SQUASH_ARRAY_PARAM(compressed_size)]) { uint64_t v; return read_varuint64 (compressed, compressed_size, &v) == 0 ? 0 : v; }
static SquashStatus squash_brieflz_decompress_buffer (SquashCodec* codec, size_t* decompressed_size, uint8_t decompressed[SQUASH_ARRAY_PARAM(*decompressed_size)], size_t compressed_size, const uint8_t compressed[SQUASH_ARRAY_PARAM(compressed_size)], SquashOptions* options) { const uint8_t *src = compressed; uint64_t original_size; size_t size; size = read_varuint64 (src, compressed_size, &original_size); if (SQUASH_UNLIKELY(size == 0)) { return squash_error (SQUASH_FAILED); } src += size; compressed_size -= size; if (SQUASH_UNLIKELY(original_size > *decompressed_size)) { return squash_error (SQUASH_BUFFER_FULL); } #if ULONG_MAX < SIZE_MAX if (SQUASH_UNLIKELY(ULONG_MAX < compressed_size) || SQUASH_UNLIKELY(ULONG_MAX < original_size)) return squash_error (SQUASH_RANGE); #endif size = blz_depack_safe (src, (unsigned long) compressed_size, decompressed, (unsigned long) original_size); if (SQUASH_UNLIKELY(size != original_size)) { return squash_error (SQUASH_FAILED); } #if SIZE_MAX < ULONG_MAX if (SQUASH_UNLIKELY(SIZE_MAX < size)) return squash_error (SQUASH_RANGE); #endif *decompressed_size = size; return SQUASH_OK; }
static SquashStatus squash_pithy_decompress_buffer (SquashCodec* codec, size_t* decompressed_size, uint8_t decompressed[SQUASH_ARRAY_PARAM(*decompressed_size)], size_t compressed_size, const uint8_t compressed[SQUASH_ARRAY_PARAM(compressed_size)], SquashOptions* options) { size_t outlen = squash_pithy_get_uncompressed_size(codec, compressed_size, compressed); if (SQUASH_UNLIKELY(*decompressed_size < outlen)) return squash_error (SQUASH_BUFFER_FULL); if (SQUASH_LIKELY(pithy_Decompress ((const char*) compressed, compressed_size, (char*) decompressed, outlen))) { *decompressed_size = outlen; return SQUASH_OK; } else { return squash_error (SQUASH_FAILED); } }
static size_t squash_snappy_get_uncompressed_size (SquashCodec* codec, size_t compressed_length, const uint8_t compressed[SQUASH_ARRAY_PARAM(compressed_length)]) { size_t uncompressed_size = 0; snappy_uncompressed_length ((const char*) compressed, compressed_length, &uncompressed_size); return uncompressed_size; }
/** * @brief Write data to a compressed file * * Attempt to write the compressed equivalent of @a uncompressed to a * file. The number of bytes of compressed data written to the output * file may be **significantly** more, or less, than the @a * uncompressed_size. * * @note It is likely the compressed data will actually be buffered, * not immediately written to the file. For codecs which support * flushing you can use @ref squash_file_flush to flush the data, * otherwise the data may not be written until @ref squash_file_close * or @ref squash_file_free is called. * * @param file file to write to * @param uncompressed_size number of bytes of uncompressed data in * @a uncompressed to attempt to write * @param uncompressed data to write * @return result of the operation */ SquashStatus squash_file_write (SquashFile* file, size_t uncompressed_size, const uint8_t uncompressed[SQUASH_ARRAY_PARAM(uncompressed_size)]) { squash_file_lock (file); SquashStatus res = squash_file_write_unlocked (file, uncompressed_size, uncompressed); squash_file_unlock (file); return res; }
static size_t squash_pithy_get_uncompressed_size (SquashCodec* codec, size_t compressed_size, const uint8_t compressed[SQUASH_ARRAY_PARAM(compressed_size)]) { size_t uncompressed_size = 0; int r = pithy_GetDecompressedLength ((const char*) compressed, compressed_size, &uncompressed_size); return SQUASH_LIKELY(r > 0) ? uncompressed_size : 0; }
static SquashStatus squash_bz2_decompress_buffer (SquashCodec* codec, size_t* decompressed_length, uint8_t decompressed[SQUASH_ARRAY_PARAM(*decompressed_length)], size_t compressed_length, const uint8_t compressed[SQUASH_ARRAY_PARAM(compressed_length)], SquashOptions* options) { int small = squash_codec_get_option_bool_index (codec, options, SQUASH_BZ2_OPT_SMALL) ? 1 : 0; unsigned int decompressed_length_ui = (unsigned int) *decompressed_length; int bz2_res; bz2_res = BZ2_bzBuffToBuffDecompress ((char*) decompressed, &decompressed_length_ui, (char*) compressed, (unsigned int) compressed_length, small, 0); if (bz2_res == BZ_OK) { *decompressed_length = decompressed_length_ui; } return squash_bz2_status_to_squash_status (bz2_res); }
/** * @brief Compress a buffer * * @param codec The codec to use * @param[out] compressed Location to store the compressed data * @param[in,out] compressed_length Location storing the size of the * @a compressed buffer on input, replaced with the actual size of * the compressed data * @param uncompressed The uncompressed data * @param uncompressed_length Length of the uncompressed data (in bytes) * @param ... A variadic list of key/value option pairs, followed by * *NULL* * @return A status code */ SquashStatus squash_codec_compress (SquashCodec* codec, size_t* compressed_length, uint8_t compressed[SQUASH_ARRAY_PARAM(*compressed_length)], size_t uncompressed_length, const uint8_t uncompressed[SQUASH_ARRAY_PARAM(uncompressed_length)], ...) { SquashOptions* options; va_list ap; assert (codec != NULL); va_start (ap, uncompressed); options = squash_options_newv (codec, ap); va_end (ap); return squash_codec_compress_with_options (codec, compressed_length, compressed, uncompressed_length, uncompressed, options); }