aboutsummaryrefslogtreecommitdiff
path: root/src/liblzma/common/stream_encoder_multi.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/liblzma/common/stream_encoder_multi.c445
1 files changed, 0 insertions, 445 deletions
diff --git a/src/liblzma/common/stream_encoder_multi.c b/src/liblzma/common/stream_encoder_multi.c
deleted file mode 100644
index 403980cf..00000000
--- a/src/liblzma/common/stream_encoder_multi.c
+++ /dev/null
@@ -1,445 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-//
-/// \file stream_encoder_multi.c
-/// \brief Encodes Multi-Block .lzma files
-//
-// Copyright (C) 2007 Lasse Collin
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#include "stream_common.h"
-#include "stream_encoder_multi.h"
-#include "block_encoder.h"
-#include "metadata_encoder.h"
-
-
-struct lzma_coder_s {
- enum {
- SEQ_STREAM_HEADER_COPY,
- SEQ_HEADER_METADATA_INIT,
- SEQ_HEADER_METADATA_COPY,
- SEQ_HEADER_METADATA_CODE,
- SEQ_DATA_INIT,
- SEQ_DATA_COPY,
- SEQ_DATA_CODE,
- SEQ_FOOTER_METADATA_INIT,
- SEQ_FOOTER_METADATA_COPY,
- SEQ_FOOTER_METADATA_CODE,
- SEQ_STREAM_FOOTER_INIT,
- SEQ_STREAM_FOOTER_COPY,
- } sequence;
-
- /// Block or Metadata encoder
- lzma_next_coder next;
-
- /// Options for the Block encoder
- lzma_options_block block_options;
-
- /// Information about the Stream
- lzma_info *info;
-
- /// Information about the current Data Block
- lzma_info_iter iter;
-
- /// Pointer to user-supplied options structure. We don't write to
- /// it, only read instructions from the application, thus this is
- /// const even though the user-supplied pointer from
- /// lzma_options_filter structure isn't.
- const lzma_options_stream *stream_options;
-
- /// Stream Header or Stream Footer in encoded form
- uint8_t *header;
- size_t header_pos;
- size_t header_size;
-};
-
-
-typedef enum {
- BLOCK_HEADER_METADATA,
- BLOCK_DATA,
- BLOCK_FOOTER_METADATA,
-} block_type;
-
-
-static lzma_ret
-block_header_encode(lzma_coder *coder, lzma_allocator *allocator,
- lzma_vli uncompressed_size, block_type type)
-{
- assert(coder->header == NULL);
-
- coder->block_options = (lzma_options_block){
- .check = coder->stream_options->check,
- .has_crc32 = coder->stream_options->has_crc32,
- .has_eopm = uncompressed_size == LZMA_VLI_VALUE_UNKNOWN,
- .is_metadata = type != BLOCK_DATA,
- .has_uncompressed_size_in_footer = false,
- .has_backward_size = type == BLOCK_FOOTER_METADATA,
- .handle_padding = false,
- .total_size = LZMA_VLI_VALUE_UNKNOWN,
- .compressed_size = LZMA_VLI_VALUE_UNKNOWN,
- .uncompressed_size = uncompressed_size,
- .compressed_reserve = 0,
- .uncompressed_reserve = 0,
- .total_limit = LZMA_VLI_VALUE_UNKNOWN,
- .uncompressed_limit = LZMA_VLI_VALUE_UNKNOWN,
- .padding = LZMA_BLOCK_HEADER_PADDING_AUTO,
- };
-
- if (type == BLOCK_DATA) {
- memcpy(coder->block_options.filters,
- coder->stream_options->filters,
- sizeof(coder->stream_options->filters));
- coder->block_options.alignment = coder->iter.stream_offset;
- } else {
- memcpy(coder->block_options.filters,
- coder->stream_options->metadata_filters,
- sizeof(coder->stream_options->filters));
- coder->block_options.alignment
- = lzma_info_metadata_alignment_get(
- coder->info, type == BLOCK_HEADER_METADATA);
- }
-
- return_if_error(lzma_block_header_size(&coder->block_options));
-
- coder->header_size = coder->block_options.header_size;
- coder->header = lzma_alloc(coder->header_size, allocator);
- if (coder->header == NULL)
- return LZMA_MEM_ERROR;
-
- return_if_error(lzma_block_header_encode(
- coder->header, &coder->block_options));
-
- coder->header_pos = 0;
- return LZMA_OK;
-}
-
-
-static lzma_ret
-metadata_encoder_init(lzma_coder *coder, lzma_allocator *allocator,
- lzma_metadata *metadata, block_type type)
-{
- return_if_error(lzma_info_metadata_set(coder->info, allocator,
- metadata, type == BLOCK_HEADER_METADATA, false));
-
- const lzma_vli metadata_size = lzma_metadata_size(metadata);
- if (metadata_size == 0)
- return LZMA_PROG_ERROR;
-
- return_if_error(block_header_encode(
- coder, allocator, metadata_size, type));
-
- return lzma_metadata_encoder_init(&coder->next, allocator,
- &coder->block_options, metadata);
-}
-
-
-static lzma_ret
-data_encoder_init(lzma_coder *coder, lzma_allocator *allocator)
-{
- return_if_error(lzma_info_iter_next(&coder->iter, allocator));
-
- return_if_error(block_header_encode(coder, allocator,
- LZMA_VLI_VALUE_UNKNOWN, BLOCK_DATA));
-
- return lzma_block_encoder_init(&coder->next, allocator,
- &coder->block_options);
-}
-
-
-static lzma_ret
-stream_encode(lzma_coder *coder, lzma_allocator *allocator,
- const uint8_t *restrict in, size_t *restrict in_pos,
- size_t in_size, uint8_t *restrict out,
- size_t *restrict out_pos, size_t out_size, lzma_action action)
-{
- // Main loop
- while (*out_pos < out_size)
- switch (coder->sequence) {
- case SEQ_STREAM_HEADER_COPY:
- case SEQ_HEADER_METADATA_COPY:
- case SEQ_DATA_COPY:
- case SEQ_FOOTER_METADATA_COPY:
- case SEQ_STREAM_FOOTER_COPY:
- bufcpy(coder->header, &coder->header_pos, coder->header_size,
- out, out_pos, out_size);
- if (coder->header_pos < coder->header_size)
- return LZMA_OK;
-
- lzma_free(coder->header, allocator);
- coder->header = NULL;
-
- switch (coder->sequence) {
- case SEQ_STREAM_HEADER_COPY:
- // Write Header Metadata Block if we have Extra for it
- // or known Uncompressed Size.
- if (coder->stream_options->header != NULL
- || coder->stream_options
- ->uncompressed_size
- != LZMA_VLI_VALUE_UNKNOWN) {
- coder->sequence = SEQ_HEADER_METADATA_INIT;
- } else {
- // Mark that Header Metadata Block doesn't
- // exist.
- if (lzma_info_size_set(coder->info,
- LZMA_INFO_HEADER_METADATA, 0)
- != LZMA_OK)
- return LZMA_PROG_ERROR;
-
- coder->sequence = SEQ_DATA_INIT;
- }
- break;
-
- case SEQ_HEADER_METADATA_COPY:
- case SEQ_DATA_COPY:
- case SEQ_FOOTER_METADATA_COPY:
- ++coder->sequence;
- break;
-
- case SEQ_STREAM_FOOTER_COPY:
- return LZMA_STREAM_END;
-
- default:
- assert(0);
- }
-
- break;
-
- case SEQ_HEADER_METADATA_INIT: {
- lzma_metadata metadata = {
- .header_metadata_size = LZMA_VLI_VALUE_UNKNOWN,
- .total_size = LZMA_VLI_VALUE_UNKNOWN,
- .uncompressed_size = coder->stream_options
- ->uncompressed_size,
- .index = NULL,
- // Metadata encoder doesn't modify this, but since
- // the lzma_extra structure is used also when decoding
- // Metadata, the pointer is not const, and we need
- // to cast the constness away in the encoder.
- .extra = (lzma_extra *)(coder->stream_options->header),
- };
-
- return_if_error(metadata_encoder_init(coder, allocator,
- &metadata, BLOCK_HEADER_METADATA));
-
- coder->sequence = SEQ_HEADER_METADATA_COPY;
- break;
- }
-
- case SEQ_FOOTER_METADATA_INIT: {
- lzma_metadata metadata = {
- .header_metadata_size
- = lzma_info_size_get(coder->info,
- LZMA_INFO_HEADER_METADATA),
- .total_size = LZMA_VLI_VALUE_UNKNOWN,
- .uncompressed_size = LZMA_VLI_VALUE_UNKNOWN,
- .index = lzma_info_index_get(coder->info, false),
- .extra = (lzma_extra *)(coder->stream_options->footer),
- };
-
- return_if_error(metadata_encoder_init(coder, allocator,
- &metadata, BLOCK_FOOTER_METADATA));
-
- coder->sequence = SEQ_FOOTER_METADATA_COPY;
- break;
- }
-
- case SEQ_HEADER_METADATA_CODE:
- case SEQ_FOOTER_METADATA_CODE: {
- size_t dummy = 0;
- const lzma_ret ret = coder->next.code(coder->next.coder,
- allocator, NULL, &dummy, 0,
- out, out_pos, out_size, LZMA_RUN);
- if (ret != LZMA_STREAM_END)
- return ret;
-
- return_if_error(lzma_info_size_set(coder->info,
- coder->sequence == SEQ_HEADER_METADATA_CODE
- ? LZMA_INFO_HEADER_METADATA
- : LZMA_INFO_FOOTER_METADATA,
- coder->block_options.total_size));
-
- ++coder->sequence;
- break;
- }
-
- case SEQ_DATA_INIT: {
- // Don't create an empty Block unless it would be
- // the only Data Block.
- if (*in_pos == in_size) {
- // If we are LZMA_SYNC_FLUSHing or LZMA_FULL_FLUSHing,
- // return LZMA_STREAM_END since there's nothing to
- // flush.
- if (action != LZMA_FINISH)
- return action == LZMA_RUN
- ? LZMA_OK : LZMA_STREAM_END;
-
- if (lzma_info_index_count_get(coder->info) != 0) {
- if (lzma_info_index_finish(coder->info))
- return LZMA_DATA_ERROR;
-
- coder->sequence = SEQ_FOOTER_METADATA_INIT;
- break;
- }
- }
-
- return_if_error(data_encoder_init(coder, allocator));
-
- coder->sequence = SEQ_DATA_COPY;
- break;
- }
-
- case SEQ_DATA_CODE: {
- static const lzma_action convert[4] = {
- LZMA_RUN,
- LZMA_SYNC_FLUSH,
- LZMA_FINISH,
- LZMA_FINISH,
- };
-
- const lzma_ret ret = coder->next.code(coder->next.coder,
- allocator, in, in_pos, in_size,
- out, out_pos, out_size, convert[action]);
- if (ret != LZMA_STREAM_END || action == LZMA_SYNC_FLUSH)
- return ret;
-
- return_if_error(lzma_info_iter_set(&coder->iter,
- coder->block_options.total_size,
- coder->block_options.uncompressed_size));
-
- coder->sequence = SEQ_DATA_INIT;
- break;
- }
-
- case SEQ_STREAM_FOOTER_INIT: {
- assert(coder->header == NULL);
-
- lzma_stream_flags flags = {
- .check = coder->stream_options->check,
- .has_crc32 = coder->stream_options->has_crc32,
- .is_multi = true,
- };
-
- coder->header = lzma_alloc(LZMA_STREAM_TAIL_SIZE, allocator);
- if (coder->header == NULL)
- return LZMA_MEM_ERROR;
-
- return_if_error(lzma_stream_tail_encode(
- coder->header, &flags));
-
- coder->header_size = LZMA_STREAM_TAIL_SIZE;
- coder->header_pos = 0;
-
- coder->sequence = SEQ_STREAM_FOOTER_COPY;
- break;
- }
-
- default:
- return LZMA_PROG_ERROR;
- }
-
- return LZMA_OK;
-}
-
-
-static void
-stream_encoder_end(lzma_coder *coder, lzma_allocator *allocator)
-{
- lzma_next_coder_end(&coder->next, allocator);
- lzma_info_free(coder->info, allocator);
- lzma_free(coder->header, allocator);
- lzma_free(coder, allocator);
- return;
-}
-
-
-static lzma_ret
-stream_encoder_init(lzma_next_coder *next,
- lzma_allocator *allocator, const lzma_options_stream *options)
-{
- if (options == NULL)
- return LZMA_PROG_ERROR;
-
- if (next->coder == NULL) {
- next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
- if (next->coder == NULL)
- return LZMA_MEM_ERROR;
-
- next->code = &stream_encode;
- next->end = &stream_encoder_end;
-
- next->coder->next = LZMA_NEXT_CODER_INIT;
- next->coder->info = NULL;
- } else {
- lzma_free(next->coder->header, allocator);
- }
-
- next->coder->header = NULL;
-
- next->coder->info = lzma_info_init(next->coder->info, allocator);
- if (next->coder->info == NULL)
- return LZMA_MEM_ERROR;
-
- next->coder->sequence = SEQ_STREAM_HEADER_COPY;
- next->coder->stream_options = options;
-
- // Encode Stream Flags
- {
- lzma_stream_flags flags = {
- .check = options->check,
- .has_crc32 = options->has_crc32,
- .is_multi = true,
- };
-
- next->coder->header = lzma_alloc(LZMA_STREAM_HEADER_SIZE,
- allocator);
- if (next->coder->header == NULL)
- return LZMA_MEM_ERROR;
-
- return_if_error(lzma_stream_header_encode(
- next->coder->header, &flags));
-
- next->coder->header_pos = 0;
- next->coder->header_size = LZMA_STREAM_HEADER_SIZE;
- }
-
- if (lzma_info_size_set(next->coder->info, LZMA_INFO_STREAM_START,
- options->alignment) != LZMA_OK)
- return LZMA_PROG_ERROR;
-
- lzma_info_iter_begin(next->coder->info, &next->coder->iter);
-
- return LZMA_OK;
-}
-
-
-extern lzma_ret
-lzma_stream_encoder_multi_init(lzma_next_coder *next,
- lzma_allocator *allocator, const lzma_options_stream *options)
-{
- lzma_next_coder_init(stream_encoder_init, next, allocator, options);
-}
-
-
-extern LZMA_API lzma_ret
-lzma_stream_encoder_multi(
- lzma_stream *strm, const lzma_options_stream *options)
-{
- lzma_next_strm_init(strm, stream_encoder_init, options);
-
- strm->internal->supported_actions[LZMA_RUN] = true;
- strm->internal->supported_actions[LZMA_SYNC_FLUSH] = true;
- strm->internal->supported_actions[LZMA_FULL_FLUSH] = true;
- strm->internal->supported_actions[LZMA_FINISH] = true;
-
- return LZMA_OK;
-}