コード例 #1
0
ファイル: squash-lz4f.c プロジェクト: szabadka/squash
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 (SQUASH_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_codec_get_option_int_index (codec, options, SQUASH_LZ4F_OPT_BLOCK_SIZE),
        blockLinked,
        squash_codec_get_option_bool_index (codec, options, SQUASH_LZ4F_OPT_CHECKSUM) ?
          contentChecksumEnabled :
          noContentChecksum,
      },
      squash_codec_get_option_int_index (codec, options, SQUASH_LZ4F_OPT_LEVEL)
    };
  } else {
    ec = LZ4F_createDecompressionContext(&(stream->data.decomp.ctx), LZ4F_VERSION);
  }

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

  return stream;
}
コード例 #2
0
ファイル: squash-bzip2.c プロジェクト: Bulat-Ziganshin/squash
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);
}
コード例 #3
0
ファイル: squash-lz4f.c プロジェクト: eevans/squash-deb
static void
squash_lz4f_stream_init (SquashLZ4FStream* stream,
                         SquashCodec* codec,
                         SquashStreamType stream_type,
                         SquashOptions* options,
                         SquashDestroyNotify destroy_notify) {
  LZ4F_errorCode_t ec;
  squash_stream_init ((SquashStream*) stream, codec, stream_type, (SquashOptions*) options, destroy_notify);

  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_length = 0;

    stream->data.comp.input_buffer_length = 0;

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

  assert (!LZ4F_isError (ec));
}
コード例 #4
0
ファイル: squash-density.c プロジェクト: jibsen/squash
static SquashStatus
squash_density_process_stream (SquashStream* stream, SquashOperation operation) {
  SquashDensityStream* s = (SquashDensityStream*) stream;

  if (s->buffer_size > 0) {
    squash_density_flush_internal_buffer (stream);
    return SQUASH_PROCESSING;
  }

  if (s->next == SQUASH_DENSITY_ACTION_INIT) {
    s->active_input_size = (stream->stream_type == SQUASH_STREAM_COMPRESS) ? ((stream->avail_in / SQUASH_DENSITY_INPUT_MULTIPLE) * SQUASH_DENSITY_INPUT_MULTIPLE) : stream->avail_in;
    if (stream->avail_out < DENSITY_MINIMUM_OUTPUT_BUFFER_SIZE) {
      s->buffer_active = true;
      s->state = density_stream_prepare (s->stream, (uint8_t*) stream->next_in, s->active_input_size, s->buffer, DENSITY_MINIMUM_OUTPUT_BUFFER_SIZE);
    } else {
      s->buffer_active = false;
      s->state = density_stream_prepare (s->stream, (uint8_t*) stream->next_in, s->active_input_size, stream->next_out, stream->avail_out);
    }
    if (SQUASH_UNLIKELY(s->state != DENSITY_STREAM_STATE_READY))
      return squash_error (SQUASH_FAILED);
  }

  switch (s->state) {
    case DENSITY_STREAM_STATE_STALL_ON_INPUT:
      if (s->input_buffer_size != 0 ||
          (stream->avail_in < SQUASH_DENSITY_INPUT_MULTIPLE && stream->stream_type == SQUASH_STREAM_COMPRESS && operation == SQUASH_OPERATION_PROCESS)) {
        const size_t remaining = SQUASH_DENSITY_INPUT_MULTIPLE - s->input_buffer_size;
        const size_t cp_size = remaining < stream->avail_in ? remaining : stream->avail_in;
        if (cp_size != 0) {
          memcpy (s->input_buffer + s->input_buffer_size, stream->next_in, cp_size);
          s->input_buffer_size += cp_size;
          stream->next_in += cp_size;
          stream->avail_in -= cp_size;
          assert (cp_size != 0);
        }
      }

      if (s->input_buffer_size != 0) {
        if (s->input_buffer_size == SQUASH_DENSITY_INPUT_MULTIPLE || operation != SQUASH_OPERATION_PROCESS) {
          s->active_input_size = s->input_buffer_size;
          s->input_buffer_active = true;
          density_stream_update_input (s->stream, s->input_buffer, s->input_buffer_size);
          s->state = DENSITY_STREAM_STATE_READY;
        } else {
          assert (stream->avail_in == 0);
          return SQUASH_OK;
        }
      } else {
        s->active_input_size = (stream->stream_type == SQUASH_STREAM_COMPRESS) ? ((stream->avail_in / SQUASH_DENSITY_INPUT_MULTIPLE) * SQUASH_DENSITY_INPUT_MULTIPLE) : stream->avail_in;
        density_stream_update_input (s->stream, stream->next_in, s->active_input_size);
        s->state = DENSITY_STREAM_STATE_READY;
      }
      break;
    case DENSITY_STREAM_STATE_STALL_ON_OUTPUT:
      {
        if (!s->output_invalid) {
          const size_t written = density_stream_output_available_for_use (s->stream);
          total_bytes_written += written;

          if (s->buffer_active) {
            s->buffer_size = written;
            s->buffer_pos = 0;

            const size_t cp_size = s->buffer_size < stream->avail_out ? s->buffer_size : stream->avail_out;
            memcpy (stream->next_out, s->buffer, cp_size);
            stream->next_out += cp_size;
            stream->avail_out -= cp_size;
            s->buffer_pos += cp_size;
            if (s->buffer_pos == s->buffer_size) {
              s->buffer_pos = 0;
              s->buffer_size = 0;
            }
          } else {
            assert (written <= stream->avail_out);
            stream->next_out += written;
            stream->avail_out -= written;
          }

          s->output_invalid = true;
          return SQUASH_PROCESSING;
        } else {
          if (stream->avail_out < DENSITY_MINIMUM_OUTPUT_BUFFER_SIZE) {
            s->buffer_active = true;
            density_stream_update_output (s->stream, s->buffer, DENSITY_MINIMUM_OUTPUT_BUFFER_SIZE);
          } else {
            s->buffer_active = false;
            density_stream_update_output (s->stream, stream->next_out, stream->avail_out);
          }
          s->output_invalid = false;
          s->state = DENSITY_STREAM_STATE_READY;
        }
      }
      break;
    case DENSITY_STREAM_STATE_READY:
      break;
    case DENSITY_STREAM_STATE_ERROR_OUTPUT_BUFFER_TOO_SMALL:
    case DENSITY_STREAM_STATE_ERROR_INVALID_INTERNAL_STATE:
    case DENSITY_STREAM_STATE_ERROR_INTEGRITY_CHECK_FAIL:
      return squash_error (SQUASH_FAILED);
  }

  assert (s->output_invalid == false);

  while (s->state == DENSITY_STREAM_STATE_READY && s->next != SQUASH_DENSITY_ACTION_FINISHED) {
    switch (s->next) {
      case SQUASH_DENSITY_ACTION_INIT:
        if (stream->stream_type == SQUASH_STREAM_COMPRESS) {
          DENSITY_COMPRESSION_MODE compression_mode =
            squash_density_level_to_mode (squash_codec_get_option_int_index (stream->codec, stream->options, SQUASH_DENSITY_OPT_LEVEL));
          DENSITY_BLOCK_TYPE block_type =
            squash_codec_get_option_bool_index (stream->codec, stream->options, SQUASH_DENSITY_OPT_CHECKSUM) ?
              DENSITY_BLOCK_TYPE_WITH_HASHSUM_INTEGRITY_CHECK :
              DENSITY_BLOCK_TYPE_DEFAULT;

          s->state = density_stream_compress_init (s->stream, compression_mode, block_type);
        } else {
          s->state = density_stream_decompress_init (s->stream, NULL);
        }
        if (SQUASH_UNLIKELY(s->state != DENSITY_STREAM_STATE_READY))
          return squash_error (SQUASH_FAILED);
        s->next = SQUASH_DENSITY_ACTION_CONTINUE;
        break;
      case SQUASH_DENSITY_ACTION_CONTINUE_OR_FINISH:
        s->next = (operation == SQUASH_OPERATION_PROCESS) ? SQUASH_DENSITY_ACTION_CONTINUE : SQUASH_DENSITY_ACTION_FINISH;
        break;
      case SQUASH_DENSITY_ACTION_CONTINUE:
        if (stream->stream_type == SQUASH_STREAM_COMPRESS) {
          s->state = density_stream_compress_continue (s->stream);
        } else {
          s->state = density_stream_decompress_continue (s->stream);
        }

        if (s->state == DENSITY_STREAM_STATE_STALL_ON_INPUT)
          s->next = SQUASH_DENSITY_ACTION_CONTINUE_OR_FINISH;

        break;
      case SQUASH_DENSITY_ACTION_FINISH:
        if (stream->stream_type == SQUASH_STREAM_COMPRESS) {
          s->state = density_stream_compress_finish (s->stream);
        } else {
          s->state = density_stream_decompress_finish (s->stream);
        }
        if (s->state == DENSITY_STREAM_STATE_READY) {
          s->state = DENSITY_STREAM_STATE_STALL_ON_OUTPUT;
          s->output_invalid = false;
          s->next = SQUASH_DENSITY_ACTION_FINISHED;
        }
        break;
      case SQUASH_DENSITY_ACTION_FINISHED:
      default:
        squash_assert_unreachable();
        break;
    }
  }

  if (s->state == DENSITY_STREAM_STATE_STALL_ON_INPUT) {
    if (s->input_buffer_active) {
      assert (s->active_input_size == s->input_buffer_size);
      s->input_buffer_active = false;
      s->input_buffer_size = 0;
    } else {
      assert (s->active_input_size <= stream->avail_in);
      stream->next_in += s->active_input_size;
      stream->avail_in -= s->active_input_size;
    }
    s->active_input_size = 0;
  } else if (s->state == DENSITY_STREAM_STATE_STALL_ON_OUTPUT) {
    {
      if (!s->output_invalid) {
        const size_t written = density_stream_output_available_for_use (s->stream);
        total_bytes_written += written;

        if (s->buffer_active) {
          s->buffer_size = written;
          s->buffer_pos = 0;

          const size_t cp_size = s->buffer_size < stream->avail_out ? s->buffer_size : stream->avail_out;
          memcpy (stream->next_out, s->buffer, cp_size);
          stream->next_out += cp_size;
          stream->avail_out -= cp_size;
          s->buffer_pos += cp_size;
          if (s->buffer_pos == s->buffer_size) {
            s->buffer_pos = 0;
            s->buffer_size = 0;
          }
        } else {
          assert (written <= stream->avail_out);
          stream->next_out += written;
          stream->avail_out -= written;
        }

        s->output_invalid = true;
        return SQUASH_PROCESSING;
      } else {
        squash_assert_unreachable();
      }
    }
  }

  if (operation == SQUASH_OPERATION_FINISH)
    total_bytes_written = 0;

  if (stream->avail_in == 0) {
    return SQUASH_OK;
  } else {
    return SQUASH_PROCESSING;
  }
}