Beispiel #1
0
static void
squash_brotli_stream_init (SquashBrotliStream* s,
                           SquashCodec* codec,
                           SquashStreamType stream_type,
                           SquashOptions* options,
                           SquashDestroyNotify destroy_notify) {
  SquashStream* stream = (SquashStream*) s;
  squash_stream_init (stream, codec, stream_type, (SquashOptions*) options, destroy_notify);

  s->finished = false;
  if (stream_type == SQUASH_STREAM_COMPRESS) {
    brotli::BrotliParams params;
    params.quality = squash_options_get_int_at (stream->options, stream->codec, SQUASH_BROTLI_OPT_LEVEL);
    params.mode = (brotli::BrotliParams::Mode) squash_options_get_int_at (stream->options, stream->codec, SQUASH_BROTLI_OPT_MODE);
    s->compressor = new brotli::BrotliCompressor (params);
    s->remaining_block_in = s->compressor->input_block_size();
    s->remaining_out = 0;
    s->next_out = NULL;
    s->should_flush = false;
    s->should_seal = false;
  } else if (stream_type == SQUASH_STREAM_DECOMPRESS) {
    s->decompressor = BrotliCreateState(squash_brotli_malloc, squash_brotli_free, squash_codec_get_context (codec));
  } else {
    squash_assert_unreachable();
  }
}
Beispiel #2
0
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);
}
Beispiel #3
0
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);
}
Beispiel #4
0
static SquashStatus
squash_zling_splice (SquashCodec* codec,
                     SquashOptions* options,
                     SquashStreamType stream_type,
                     SquashReadFunc read_cb,
                     SquashWriteFunc write_cb,
                     void* user_data) {
  try {
    SquashZlingIO stream(user_data, read_cb, write_cb);
    int zres = 0;

    if (stream_type == SQUASH_STREAM_COMPRESS) {
      zres = baidu::zling::Encode(&stream, &stream, NULL, squash_options_get_int_at (options, codec, SQUASH_ZLING_OPT_LEVEL));
    } else {
      zres = baidu::zling::Decode(&stream, &stream, NULL);
    }

    if (zres == 0)
      return SQUASH_OK;
    else if (HEDLEY_LIKELY(stream.last_res < 0))
      return stream.last_res;
    else
      return squash_error (SQUASH_FAILED);
  } catch (const std::bad_alloc& e) {
    return squash_error (SQUASH_MEMORY);
  } catch (const SquashStatus e) {
    return e;
  } catch (...) {
    return squash_error (SQUASH_FAILED);
  }

  HEDLEY_UNREACHABLE ();
}
Beispiel #5
0
static SquashStatus
squash_fastlz_compress_buffer (SquashCodec* codec,
                               size_t* compressed_size,
                               uint8_t compressed[HEDLEY_ARRAY_PARAM(*compressed_size)],
                               size_t uncompressed_size,
                               const uint8_t uncompressed[HEDLEY_ARRAY_PARAM(uncompressed_size)],
                               SquashOptions* options) {
#if INT_MAX < SIZE_MAX
  if (HEDLEY_UNLIKELY(INT_MAX < uncompressed_size) ||
      HEDLEY_UNLIKELY(INT_MAX < *compressed_size))
    return squash_error (SQUASH_RANGE);
#endif

  const int fastlz_e =
    fastlz_compress_level (squash_options_get_int_at (options, codec, SQUASH_FASTLZ_OPT_LEVEL),
                           (const void*) uncompressed,
                           (int) uncompressed_size,
                           (void*) compressed);

#if SIZE_MAX < INT_MAX
  if (HEDLEY_UNLIKELY(SIZE_MAX < fastlz_e))
    return squash_error (SQUASH_RANGE);
#endif

  *compressed_size = (size_t) fastlz_e;

  return HEDLEY_UNLIKELY(fastlz_e == 0) ? squash_error (SQUASH_FAILED) : SQUASH_OK;
}
Beispiel #6
0
static SquashStatus
squash_zpaq_splice (SquashCodec* codec,
                    SquashOptions* options,
                    SquashStreamType stream_type,
                    SquashReadFunc read_cb,
                    SquashWriteFunc write_cb,
                    void* user_data) {
  try {
    SquashZpaqIO stream(user_data, read_cb, write_cb);
    if (stream_type == SQUASH_STREAM_COMPRESS) {
      char level_s[3] = { 0, };
      snprintf (level_s, sizeof(level_s), "%d", squash_options_get_int_at (options, codec, SQUASH_ZPAQ_OPT_LEVEL));

      compress (&stream, &stream, level_s);
    } else {
      decompress (&stream, &stream);
    }
  } catch (const std::bad_alloc& e) {
    (void) e;
    return squash_error (SQUASH_MEMORY);
  } catch (const SquashStatus e) {
    return e;
  } catch (...) {
    return SQUASH_FAILED;
  }

  return SQUASH_OK;
}
Beispiel #7
0
static SquashLZ4FStream*
squash_lz4f_stream_new (SquashCodec* codec, SquashStreamType stream_type, SquashOptions* options) {
  SquashLZ4FStream* stream;
  LZ4F_errorCode_t ec;

  assert (codec != NULL);

  stream = (SquashLZ4FStream*) squash_malloc (sizeof (SquashLZ4FStream));
  if (HEDLEY_UNLIKELY(stream == NULL))
    return (squash_error (SQUASH_MEMORY), NULL);

  squash_lz4f_stream_init (stream, codec, stream_type, options, squash_lz4f_stream_destroy);

  if (stream_type == SQUASH_STREAM_COMPRESS) {
    ec = LZ4F_createCompressionContext(&(stream->data.comp.ctx), LZ4F_VERSION);

    stream->data.comp.state = SQUASH_LZ4F_STATE_INIT;

    stream->data.comp.output_buffer = NULL;
    stream->data.comp.output_buffer_pos = 0;
    stream->data.comp.output_buffer_size = 0;

    stream->data.comp.input_buffer_size = 0;

    stream->data.comp.prefs = (LZ4F_preferences_t) {
      {
        (LZ4F_blockSizeID_t) squash_options_get_int_at (options, codec, SQUASH_LZ4F_OPT_BLOCK_SIZE),
        blockLinked,
        squash_options_get_bool_at (options, codec, SQUASH_LZ4F_OPT_CHECKSUM) ?
          contentChecksumEnabled :
          noContentChecksum,
      },
      squash_options_get_int_at (options, codec, SQUASH_LZ4F_OPT_LEVEL)
    };
  } else {
    ec = LZ4F_createDecompressionContext(&(stream->data.decomp.ctx), LZ4F_VERSION);
  }

  if (HEDLEY_UNLIKELY(LZ4F_isError (ec))) {
    squash_object_unref (stream);
    return (squash_error (SQUASH_FAILED), NULL);
  }

  return stream;
}
Beispiel #8
0
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;
}
Beispiel #9
0
static void
squash_brotli_stream_init (SquashBrotliStream* s,
                           SquashCodec* codec,
                           SquashStreamType stream_type,
                           SquashOptions* options,
                           SquashDestroyNotify destroy_notify) {
  SquashStream* stream = (SquashStream*) s;
  squash_stream_init (stream, codec, stream_type, (SquashOptions*) options, destroy_notify);

  if (stream_type == SQUASH_STREAM_COMPRESS) {
    s->ctx.encoder = BrotliEncoderCreateInstance(squash_brotli_malloc, squash_brotli_free, NULL);

    BrotliEncoderSetParameter(s->ctx.encoder, BROTLI_PARAM_QUALITY, squash_options_get_int_at (options, codec, SQUASH_BROTLI_OPT_LEVEL));
    BrotliEncoderSetParameter(s->ctx.encoder, BROTLI_PARAM_LGWIN, squash_options_get_int_at (options, codec, SQUASH_BROTLI_OPT_WINDOW_SIZE));
    BrotliEncoderSetParameter(s->ctx.encoder, BROTLI_PARAM_LGBLOCK, squash_options_get_int_at (options, codec, SQUASH_BROTLI_OPT_BLOCK_SIZE));
    BrotliEncoderSetParameter(s->ctx.encoder, BROTLI_PARAM_MODE, squash_options_get_int_at (options, codec, SQUASH_BROTLI_OPT_MODE));
  } else if (stream_type == SQUASH_STREAM_DECOMPRESS) {
    s->ctx.decoder = BrotliCreateState(squash_brotli_malloc, squash_brotli_free, NULL);
  } else {
    squash_assert_unreachable();
  }
}
Beispiel #10
0
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) {
  brotli::BrotliParams params;
  params.quality = squash_options_get_int_at (options, codec, SQUASH_BROTLI_OPT_LEVEL);
  params.mode = (brotli::BrotliParams::Mode) squash_options_get_int_at (options, codec, SQUASH_BROTLI_OPT_MODE);
  try {
    int res = brotli::BrotliCompressBuffer (params,
                                            uncompressed_size, uncompressed,
                                            compressed_size, compressed);
    return SQUASH_LIKELY(res == 1) ? SQUASH_OK : squash_error (SQUASH_FAILED);
  } catch (const std::bad_alloc& e) {
    (void) e;
    return squash_error (SQUASH_MEMORY);
  } catch (...) {
    return squash_error (SQUASH_FAILED);
  }
}
Beispiel #11
0
static SquashStatus
squash_libdeflate_compress_buffer (SquashCodec* codec,
                              size_t* compressed_size,
                              uint8_t compressed[HEDLEY_ARRAY_PARAM(*compressed_size)],
                              size_t uncompressed_size,
                              const uint8_t uncompressed[HEDLEY_ARRAY_PARAM(uncompressed_size)],
                              SquashOptions* options) {
  const int level = squash_options_get_int_at (options, codec, SQUASH_LIBDEFLATE_OPT_LEVEL);
  struct deflate_compressor *compressor = deflate_alloc_compressor(level);
  *compressed_size = deflate_compress(compressor, uncompressed, uncompressed_size, compressed, *compressed_size);
  deflate_free_compressor(compressor);
  return HEDLEY_LIKELY(*compressed_size != 0) ? SQUASH_OK : squash_error (SQUASH_BUFFER_FULL);
}
Beispiel #12
0
static SquashStatus
squash_bsc_compress_buffer_unsafe (SquashCodec* codec,
                                   size_t* compressed_size,
                                   uint8_t compressed[HEDLEY_ARRAY_PARAM(*compressed_size)],
                                   size_t uncompressed_size,
                                   const uint8_t uncompressed[HEDLEY_ARRAY_PARAM(uncompressed_size)],
                                   SquashOptions* options) {
  const int lzp_hash_size = squash_options_get_int_at (options, codec, SQUASH_BSC_OPT_LZP_HASH_SIZE);
  const int lzp_min_len = squash_options_get_int_at (options, codec, SQUASH_BSC_OPT_LZP_MIN_LEN);
  const int block_sorter = squash_options_get_int_at (options, codec, SQUASH_BSC_OPT_BLOCK_SORTER);
  const int coder = squash_options_get_int_at (options, codec, SQUASH_BSC_OPT_CODER);
  const int features = squash_bsc_options_get_features (codec, options);

#if INT_MAX < SIZE_MAX
  if (HEDLEY_UNLIKELY(INT_MAX < uncompressed_size))
    return squash_error (SQUASH_RANGE);
#endif

  if (HEDLEY_UNLIKELY(*compressed_size < (uncompressed_size + LIBBSC_HEADER_SIZE)))
    return squash_error (SQUASH_BUFFER_FULL);

  const int res = bsc_compress (uncompressed, compressed, (int) uncompressed_size,
                                lzp_hash_size, lzp_min_len, block_sorter, coder, features);

  if (HEDLEY_UNLIKELY(res < 0)) {
    return squash_error (SQUASH_FAILED);
  }

#if SIZE_MAX < INT_MAX
  if (HEDLEY_UNLIKELY(SIZE_MAX < res))
    return squash_error (SQUASH_RANGE);
#endif

  *compressed_size = (size_t) res;

  return SQUASH_OK;
}
Beispiel #13
0
static SquashStatus
squash_lzg_compress_buffer (SquashCodec* codec,
                            size_t* compressed_size,
                            uint8_t compressed[HEDLEY_ARRAY_PARAM(*compressed_size)],
                            size_t uncompressed_size,
                            const uint8_t uncompressed[HEDLEY_ARRAY_PARAM(uncompressed_size)],
                            SquashOptions* options) {
  lzg_encoder_config_t cfg = {
    squash_options_get_int_at (options, codec, SQUASH_LZG_OPT_LEVEL),
    squash_options_get_bool_at (options, codec, SQUASH_LZG_OPT_FAST),
    NULL,
    NULL
  };

#if UINT32_MAX < SIZE_MAX
  if (HEDLEY_UNLIKELY(UINT32_MAX < uncompressed_size) ||
      HEDLEY_UNLIKELY(UINT32_MAX < *compressed_size))
    return squash_error (SQUASH_RANGE);
#endif

  uint8_t* workmem = squash_calloc (LZG_WorkMemSize (&cfg), 1);
  if (HEDLEY_UNLIKELY(workmem == NULL))
    return squash_error (SQUASH_MEMORY);
  lzg_uint32_t res = LZG_EncodeFull ((const unsigned char*) uncompressed, (lzg_uint32_t) uncompressed_size,
                                     (unsigned char*) compressed, (lzg_uint32_t) *compressed_size,
                                     &cfg, workmem);
  squash_free (workmem);

  if (res == 0) {
    return squash_error (SQUASH_FAILED);
  } else {
#if SIZE_MAX < UINT32_MAX
    if (HEDLEY_UNLIKELY(SIZE_MAX < res))
      return squash_error (SQUASH_RANGE);
#endif
    *compressed_size = (size_t) res;
    return SQUASH_OK;
  }
}
Beispiel #14
0
static SquashStatus
squash_csc_splice (SquashCodec* codec,
                   SquashOptions* options,
                   SquashStreamType stream_type,
                   SquashReadFunc read_cb,
                   SquashWriteFunc write_cb,
                   void* user_data) {
  int csc_res;
  SquashStatus res = SQUASH_OK;
  const struct SquashCscInStream in_stream = {
    { squash_csc_reader },
    user_data,
    read_cb,
    write_cb
  };
  const struct SquashCscOutStream out_stream = {
    { squash_csc_writer },
    user_data,
    read_cb,
    write_cb
  };

  CSCProps props;
  unsigned char props_buf[CSC_PROP_SIZE];

  if (stream_type == SQUASH_STREAM_COMPRESS) {
    CSCEncProps_Init (&props,
                      squash_codec_get_option_size_index (codec, options, SQUASH_CSC_OPT_DICT_SIZE),
                      squash_options_get_int_at (options, codec, SQUASH_CSC_OPT_LEVEL));
    props.DLTFilter = squash_options_get_bool_at (options, codec, SQUASH_CSC_OPT_DELTA_FILTER);
    props.EXEFilter = squash_options_get_bool_at (options, codec, SQUASH_CSC_OPT_EXE_FILTER);
    props.TXTFilter = squash_options_get_bool_at (options, codec, SQUASH_CSC_OPT_TXT_FILTER);

    CSCEnc_WriteProperties (&props, props_buf, 0);
    size_t bytes_written = squash_csc_writer ((void*) &out_stream, props_buf, CSC_PROP_SIZE);
    if (SQUASH_UNLIKELY(bytes_written != CSC_PROP_SIZE))
      return squash_error (SQUASH_FAILED);

    CSCEncHandle comp = CSCEnc_Create (&props, (ISeqOutStream*) &out_stream, (ISzAlloc*) &squash_csc_allocator);
    csc_res = CSCEnc_Encode (comp, (ISeqInStream*) &in_stream, NULL);
    if (SQUASH_UNLIKELY(csc_res != 0)) {
      res = squash_error (SQUASH_FAILED);
    } else {
      csc_res = CSCEnc_Encode_Flush (comp);
      if (SQUASH_UNLIKELY(csc_res != 0)) {
        res = squash_error (SQUASH_FAILED);
      }
    }
    CSCEnc_Destroy (comp);
  } else {
    size_t prop_l = CSC_PROP_SIZE;
    squash_csc_reader ((void*) &in_stream, props_buf, &prop_l);
    if (SQUASH_UNLIKELY(prop_l != CSC_PROP_SIZE))
      return squash_error (SQUASH_FAILED);

    CSCDec_ReadProperties (&props, props_buf);

    CSCDecHandle decomp = CSCDec_Create (&props, (ISeqInStream*) &in_stream, (ISzAlloc*) &squash_csc_allocator);
    csc_res = CSCDec_Decode (decomp, (ISeqOutStream*) &out_stream, NULL);
    if (csc_res != 0) {
      res = squash_error (SQUASH_FAILED);
    }
    CSCDec_Destroy (decomp);
  }

  return res;
}
Beispiel #15
0
static size_t
squash_lz4f_get_input_buffer_size (SquashStream* stream) {
  return squash_lz4f_block_size_id_to_size ((LZ4F_blockSizeID_t) squash_options_get_int_at (stream->options, stream->codec, SQUASH_LZ4F_OPT_BLOCK_SIZE));
}