//---------- size_t Codec::getUncompressedSize(const string & compressed) const { IF_NOT_OK_RETURN(0); const auto compressedData = (uint8_t*) & compressed[0]; auto size = squash_codec_get_uncompressed_size(this->squashCodec, compressed.size(), compressedData); if (size == 0) { OFXSQUASH_WARNING << "Codec [" << this->getName() << "] doesn't support getUncompressedSize (sorry! you'll need to allocate 'enough' yourself)"; } return size; }
size_t squash_get_uncompressed_size (const char* codec, size_t compressed_length, const uint8_t compressed[SQUASH_ARRAY_PARAM(compressed_length)]) { assert (codec != NULL); assert (compressed_length > 0); assert (compressed != NULL); SquashCodec* codec_real = squash_get_codec (codec); if (codec_real == NULL) return 0; return squash_codec_get_uncompressed_size (codec_real, compressed_length, compressed); }
//---------- size_t Codec::getUncompressedSize(void * compressed, size_t compressedSize) const { IF_NOT_OK_RETURN(0); return squash_codec_get_uncompressed_size(this->squashCodec, compressedSize, (uint8_t*) compressed); }
static SquashStatus squash_codec_process_file_with_options (SquashCodec* codec, SquashStreamType stream_type, FILE* output, size_t output_length, FILE* input, SquashOptions* options) { SquashStatus res = SQUASH_FAILED; SquashStream* stream; if (codec->impl.process_stream == NULL) { /* Attempt to mmap the input and output. This short circuits the whole SquashBufferStream hack when possible, which can be a huge performance boost (50-100% for several codecs). */ SquashMappedFile* in_map; in_map = squash_mapped_file_new (input, false); if (in_map != NULL) { SquashMappedFile* out_map; size_t max_output_size; if (stream_type == SQUASH_STREAM_COMPRESS) { max_output_size = squash_codec_get_max_compressed_size (codec, in_map->data_length); } else if (codec->impl.get_uncompressed_size != NULL) { max_output_size = squash_codec_get_uncompressed_size (codec, in_map->data_length, in_map->data); } else if (output_length != 0) { max_output_size = output_length; } else { max_output_size = in_map->data_length - 1; max_output_size |= max_output_size >> 1; max_output_size |= max_output_size >> 2; max_output_size |= max_output_size >> 4; max_output_size |= max_output_size >> 8; max_output_size |= max_output_size >> 16; max_output_size++; max_output_size <<= 3; } out_map = squash_mapped_file_new_full(output, false, 0, max_output_size); if (out_map != NULL) { size_t output_size = out_map->data_length; if (stream_type == SQUASH_STREAM_COMPRESS) { output_size = out_map->data_length; res = squash_codec_compress_with_options (codec, &output_size, out_map->data, in_map->data_length, in_map->data, options); } else { do { output_size = max_output_size; res = squash_codec_decompress_with_options (codec, &output_size, out_map->data, in_map->data_length, in_map->data, options); max_output_size <<= 1; } while (SQUASH_UNLIKELY(res == SQUASH_BUFFER_FULL) && output_length == 0 && codec->impl.get_uncompressed_size == NULL); } squash_mapped_file_free (out_map); out_map = NULL; /* We know that the mmap was successful, so not checking fileno() should be safe. */ if (ftruncate (fileno (output), (off_t) output_size) == -1) res = SQUASH_FAILED; if (fseek (output, output_size, SEEK_SET) == -1) res = SQUASH_FAILED; } if (res != SQUASH_OK) { size_t ipos = in_map->data_offset; squash_mapped_file_free (in_map); fseek (input, ipos, SEEK_SET); } else { squash_mapped_file_free (in_map); } in_map = NULL; }