Пример #1
0
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;
}
Пример #2
0
//-
static
ERL_NIF_TERM
nif_decompress(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    ErlNifBinary input;

    if(!enif_inspect_iolist_as_binary(env, argv[0], &input)) 
    {
        return(enif_make_badarg(env));
    }

    ErlNifBinary bin;

    // [rad] Get decompressed size.
    uint32_t decompressed_bytes = wfLZ_GetDecompressedSize((const uint8_t* const) input.data);

    if(!decompressed_bytes)
    {
        return(erlang_produce_error(env, "not_compressed"));
    }

    // [rad] Create binary stream to hold decompressed data.
    if(!enif_alloc_binary(decompressed_bytes, &bin))
    {
        return(erlang_produce_error(env, "not_enough_memory"));
    } 

    // [rad] Perform decompression.
    wfLZ_Decompress((const uint8_t* const) input.data, bin.data);

    return(enif_make_binary(env, &bin));
}
Пример #3
0
static size_t
squash_wflz_get_uncompressed_size (SquashCodec* codec,
                                   size_t compressed_size,
                                   const uint8_t compressed[SQUASH_ARRAY_PARAM(compressed_size)]) {
  if (compressed_size < 12)
    return 0;

  const uint32_t res = wfLZ_GetDecompressedSize (compressed);

#if SIZE_MAX < UINT32_MAX
  if (SQUASH_UNLIKELY(SIZE_MAX < res))
    return (squash_error (SQUASH_RANGE), 0);
#endif

  return (size_t) res;
}