///////////////////////////////////////////////////////////////////////////////
//
/// \file       subblock_encoder.c
/// \brief      Encoder of the Subblock filter
//
//  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 "subblock_encoder.h"
#include "raw_encoder.h"


#define REPEAT_COUNT_MAX (1U << 28)

/// Number of bytes the data chunk being repeated must be before we care
/// about alignment. This is somewhat arbitrary. It just doesn't make sense
/// to waste bytes for alignment when the data chunk is very small.
///
/// TODO Rename and use this also for Subblock Data?
#define RLE_MIN_SIZE_FOR_ALIGN 3

#define write_byte(b) \
do { \
	out[*out_pos] = b; \
	++*out_pos; \
	++coder->alignment.out_pos; \
} while (0)


struct lzma_coder_s {
	lzma_next_coder next;
	bool next_finished;

	enum {
		SEQ_FILL,
		SEQ_FLUSH,
		SEQ_RLE_COUNT_0,
		SEQ_RLE_COUNT_1,
		SEQ_RLE_COUNT_2,
		SEQ_RLE_COUNT_3,
		SEQ_RLE_SIZE,
		SEQ_RLE_DATA,
		SEQ_DATA_SIZE_0,
		SEQ_DATA_SIZE_1,
		SEQ_DATA_SIZE_2,
		SEQ_DATA_SIZE_3,
		SEQ_DATA,
		SEQ_SUBFILTER_INIT,
		SEQ_SUBFILTER_FLAGS,
	} sequence;

	lzma_options_subblock *options;

	lzma_vli uncompressed_size;

	size_t pos;
	uint32_t tmp;

	struct {
		uint32_t multiple;
		uint32_t in_pending;
		uint32_t in_pos;
		uint32_t out_pos;
	} alignment;

	struct {
		uint8_t *data;
		size_t size;
		size_t limit;
	} subblock;

	struct {
		uint8_t buffer[LZMA_SUBBLOCK_RLE_MAX];
		size_t size;
		lzma_vli count;
	} rle;

	struct {
		enum {
			SUB_NONE,
			SUB_SET,
			SUB_RUN,
			SUB_FINISH,
			SUB_END_MARKER,
		} mode;

		bool got_input;

		uint8_t *flags;
		size_t flags_size;

		lzma_next_coder subcoder;

	} subfilter;

	struct {
		size_t pos;
		size_t size;
		uint8_t buffer[LZMA_BUFFER_SIZE];
	} temp;
};


/// \brief      Aligns the output buffer
///
/// Aligns the output buffer so that after skew bytes the output position is
/// a multiple of coder->alignment.multiple.
static bool
subblock_align(lzma_coder *coder, uint8_t *restrict out,
		size_t *restrict out_pos, size_t out_size, uint32_t skew)
{
	assert(*out_pos < out_size);

	const uint32_t target = coder->alignment.in_pos
			% coder->alignment.multiple;

	while ((coder->alignment.out_pos + skew)
			% coder->alignment.multiple != target) {
		// Zero indicates padding.
		write_byte(0x00);

		// Check if output buffer got full and indicate it to
		// the caller.
		if (*out_pos == out_size)
			return true;
	}

	coder->alignment.in_pos += coder->alignment.in_pending;
	coder->alignment.in_pending = 0;

	// Output buffer is not full.
	return false;
}


/// \brief      Checks if buffer contains repeated data
///
/// \param      needle      Buffer containing a single repeat chunk
/// \param      needle_size Size of needle in bytes
/// \param      buf         Buffer to search for repeated needles
/// \param      buf_chunks  Buffer size is buf_chunks * needle_size.
///
/// \return     True if the whole buf is filled with repeated needles.
///
static bool
is_repeating(const uint8_t *restrict needle, size_t needle_size,
		const uint8_t *restrict buf, size_t buf_chunks)
{
	while (buf_chunks-- != 0) {
		if (memcmp(buf, needle, needle_size) != 0)
			return false;

		buf += needle_size;
	}

	return true;
}


/// \brief      Optimizes the repeating style and updates coder->sequence
static void
subblock_rle_flush(lzma_coder *coder)
{
	// The Subblock decoder can use memset() when the size of the data
	// being repeated is one byte, so we check if the RLE buffer is
	// filled with a single repeating byte.
	if (coder->rle.size > 1) {
		const uint8_t b = coder->rle.buffer[0];
		size_t i = 0;
		while (true) {
			if (coder->rle.buffer[i] != b)
				break;

			if (++i == coder->rle.size) {
				// TODO Integer overflow check maybe,
				// although this needs at least 2**63 bytes
				// of input until it gets triggered...
				coder->rle.count *= coder->rle.size;
				coder->rle.size = 1;
				break;
			}
		}
	}

	if (coder->rle.count > REPEAT_COUNT_MAX)
		coder->tmp = REPEAT_COUNT_MAX - 1;
	else
		coder->tmp = coder->rle.count - 1;

	coder->sequence = SEQ_RLE_COUNT_0;

	return;
}


/// \brief      Resizes coder->subblock.data for a new size limit
static lzma_ret
subblock_data_size(lzma_coder *coder, lzma_allocator *allocator,
		size_t new_limit)
{
	// Verify that the new limit is valid.
	if (new_limit < LZMA_SUBBLOCK_DATA_SIZE_MIN
			|| new_limit > LZMA_SUBBLOCK_DATA_SIZE_MAX)
		return LZMA_HEADER_ERROR;

	// Ff the new limit is different than the previous one, we need
	// to reallocate the data buffer.
	if (new_limit != coder->subblock.limit) {
		lzma_free(coder->subblock.data, allocator);
		coder->subblock.data = lzma_alloc(new_limit, allocator);
		if (coder->subblock.data == NULL)
			return LZMA_MEM_ERROR;
	}

	coder->subblock.limit = new_limit;

	return LZMA_OK;
}


static lzma_ret
subblock_buffer(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)
{
	// Verify that there is a sane amount of input.
	if (coder->uncompressed_size != LZMA_VLI_VALUE_UNKNOWN) {
		const lzma_vli in_avail = in_size - *in_pos;
		if (action == LZMA_FINISH) {
			if (in_avail != coder->uncompressed_size)
				return LZMA_DATA_ERROR;
		} else {
			if (in_avail > coder->uncompressed_size)
				return LZMA_DATA_ERROR;
		}
	}

	// Check if we need to do something special with the Subfilter.
	if (coder->options != NULL && coder->options->allow_subfilters) {
		switch (coder->options->subfilter_mode) {
		case LZMA_SUBFILTER_NONE:
			if (coder->subfilter.mode != SUB_NONE)
				return LZMA_PROG_ERROR;
			break;

		case LZMA_SUBFILTER_SET:
			if (coder->subfilter.mode != SUB_NONE)
				return LZMA_HEADER_ERROR;

			coder->subfilter.mode = SUB_SET;
			coder->subfilter.got_input = false;

			if (coder->sequence == SEQ_FILL)
				coder->sequence = SEQ_FLUSH;

			break;

		case LZMA_SUBFILTER_RUN:
			if (coder->subfilter.mode != SUB_RUN)
				return LZMA_PROG_ERROR;
			break;

		case LZMA_SUBFILTER_FINISH:
			if (coder->subfilter.mode == SUB_RUN)
				coder->subfilter.mode = SUB_FINISH;
			else if (coder->subfilter.mode != SUB_FINISH)
				return LZMA_PROG_ERROR;

			if (!coder->subfilter.got_input)
				return LZMA_PROG_ERROR;

			break;

		default:
			return LZMA_HEADER_ERROR;
		}
	}

	// Main loop
	while (*out_pos < out_size)
	switch (coder->sequence) {
	case SEQ_FILL: {
		// Grab the new Subblock Data Size and reallocate the buffer.
		if (coder->subblock.size == 0 && coder->options != NULL
				&& coder->options->subblock_data_size
					!= coder->subblock.limit)
			return_if_error(subblock_data_size(coder,
					allocator, coder->options
						->subblock_data_size));

		if (coder->subfilter.mode == SUB_NONE) {
			assert(coder->subfilter.subcoder.code == NULL);

			// No Subfilter is enabled, just copy the data as is.
			// NOTE: uncompressed_size cannot overflow because we
			// have checked/ it in the beginning of this function.
			const size_t in_used = bufcpy(in, in_pos, in_size,
					coder->subblock.data,
					&coder->subblock.size,
					coder->subblock.limit);

			if (coder->uncompressed_size != LZMA_VLI_VALUE_UNKNOWN)
				coder->uncompressed_size -= in_used;

			coder->alignment.in_pending += in_used;

		} else {
			const size_t in_start = *in_pos;
			lzma_ret ret;

			if (coder->subfilter.mode == SUB_FINISH) {
				// Let the Subfilter write out pending data,
				// but don't give it any new input anymore.
				size_t dummy = 0;
				ret = coder->subfilter.subcoder.code(coder
						->subfilter.subcoder.coder,
						allocator, NULL, &dummy, 0,
						coder->subblock.data,
						&coder->subblock.size,
						coder->subblock.limit,
						LZMA_FINISH);
			} else {
				// Give our input data to the Subfilter. Note
				// that action can be LZMA_FINISH. In that
				// case, we filter everything until the end
				// of the input. The application isn't required
				// to separately set LZMA_SUBBLOCK_FINISH.
				ret = coder->subfilter.subcoder.code(coder
						->subfilter.subcoder.coder,
						allocator, in, in_pos, in_size,
						coder->subblock.data,
						&coder->subblock.size,
						coder->subblock.limit,
						action);
			}

			const size_t in_used = *in_pos - in_start;

			if (in_used > 0)
				coder->subfilter.got_input = true;

			// NOTE: uncompressed_size cannot overflow because we
			// have checked it in the beginning of this function.
			if (coder->uncompressed_size != LZMA_VLI_VALUE_UNKNOWN)
				coder->uncompressed_size -= *in_pos - in_start;

			coder->alignment.in_pending += in_used;

			if (ret == LZMA_STREAM_END) {
				// We don't strictly need to do this, but
				// doing it sounds like a good idea, because
				// otherwise the Subfilter's memory could be
				// left allocated for long time, and would
				// just waste memory.
				lzma_next_coder_end(&coder->subfilter.subcoder,
						allocator);

				assert(coder->options != NULL);
				coder->options->subfilter_mode
						= LZMA_SUBFILTER_NONE;

				assert(coder->subfilter.mode == SUB_FINISH
						|| action == LZMA_FINISH);
				coder->subfilter.mode = SUB_END_MARKER;

				// Flush now. Even if coder->subblock.size
				// happens to be zero, we still need to go
				// to SEQ_FLUSH to write the Subfilter Unset
				// indicator.
				coder->sequence = SEQ_FLUSH;
				break;
			}

			// Return if an error occurred.
			if (ret != LZMA_OK)
				return ret;
		}

		// If we ran out of input before the whole buffer
		// was filled, return to application.
		if (coder->subblock.size < coder->subblock.limit
				&& action != LZMA_FINISH)
			return LZMA_OK;

		coder->sequence = SEQ_FLUSH;
	}

	// Fall through

	case SEQ_FLUSH:
		if (coder->options != NULL) {
			// Update the alignment variable.
			coder->alignment.multiple = coder->options->alignment;
			if (coder->alignment.multiple
					< LZMA_SUBBLOCK_ALIGNMENT_MIN
					|| coder->alignment.multiple
					> LZMA_SUBBLOCK_ALIGNMENT_MAX)
				return LZMA_HEADER_ERROR;

			// Run-length encoder
			//
			// First check if there is some data pending and we
			// have an obvious need to flush it immediatelly.
			if (coder->rle.count > 0
					&& (coder->rle.size
							!= coder->options->rle
						|| coder->subblock.size
							% coder->rle.size)) {
				subblock_rle_flush(coder);
				break;
			}

			// Grab the (possibly new) RLE chunk size and
			// validate it.
			coder->rle.size = coder->options->rle;
			if (coder->rle.size > LZMA_SUBBLOCK_RLE_MAX)
				return LZMA_HEADER_ERROR;

			if (coder->subblock.size != 0
					&& coder->rle.size
						!= LZMA_SUBBLOCK_RLE_OFF
					&& coder->subblock.size
						% coder->rle.size == 0) {

				// Initialize coder->rle.buffer if we don't
				// have RLE already running.
				if (coder->rle.count == 0)
					memcpy(coder->rle.buffer,
							coder->subblock.data,
							coder->rle.size);

				// Test if coder->subblock.data is repeating.
				const size_t count = coder->subblock.size
						/ coder->rle.size;
				if (is_repeating(coder->rle.buffer,
						coder->rle.size,
						coder->subblock.data, count)) {
					if (LZMA_VLI_VALUE_MAX - count
							< coder->rle.count)
						return LZMA_PROG_ERROR;

					coder->rle.count += count;
					coder->subblock.size = 0;

				} else if (coder->rle.count > 0) {
					// It's not repeating or at least not
					// with the same byte sequence as the
					// earlier Subblock Data buffers. We
					// have some data pending in the RLE
					// buffer already, so do a flush.
					// Once flushed, we will check again
					// if the Subblock Data happens to
					// contain a different repeating
					// sequence.
					subblock_rle_flush(coder);
					break;
				}
			}
		}

		// If we now have some data left in coder->subblock, the RLE
		// buffer is empty and we must write a regular Subblock Data.
		if (coder->subblock.size > 0) {
			assert(coder->rle.count == 0);
			coder->tmp = coder->subblock.size - 1;
			coder->sequence = SEQ_DATA_SIZE_0;
			break;
		}

		// Check if we should enable Subfilter.
		if (coder->subfilter.mode == SUB_SET) {
			if (coder->rle.count > 0)
				subblock_rle_flush(coder);
			else
				coder->sequence = SEQ_SUBFILTER_INIT;
			break;
		}

		// Check if we have just finished Subfiltering.
		if (coder->subfilter.mode == SUB_END_MARKER) {
			if (coder->rle.count > 0) {
				subblock_rle_flush(coder);
				break;
			}

			write_byte(0x50);
			coder->subfilter.mode = SUB_NONE;
			if (*out_pos == out_size)
				return LZMA_OK;
		}

		// Check if we have already written everything.
		if (action == LZMA_FINISH && *in_pos == in_size
				&& coder->subfilter.mode == SUB_NONE) {
			if (coder->rle.count > 0) {
				subblock_rle_flush(coder);
				break;
			}

			if (coder->uncompressed_size
					== LZMA_VLI_VALUE_UNKNOWN) {
				// NOTE: No need to use write_byte() here
				// since we are finishing.
				out[*out_pos] = 0x10;
				++*out_pos;
			} else if (coder->uncompressed_size != 0) {
				return LZMA_DATA_ERROR;
			}

			return LZMA_STREAM_END;
		}

		// Otherwise we have more work to do.
		coder->sequence = SEQ_FILL;
		break;

	case SEQ_RLE_COUNT_0:
		// Make the Data field properly aligned, but only if the data
		// chunk to be repeated isn't extremely small. We have four
		// bytes for Count and one byte for Size, thus the number five.
		if (coder->rle.size >= RLE_MIN_SIZE_FOR_ALIGN
				&& subblock_align(
					coder, out, out_pos, out_size, 5))
			return LZMA_OK;

		assert(coder->rle.count > 0);

		write_byte(0x30 | (coder->tmp & 0x0F));

		coder->sequence = SEQ_RLE_COUNT_1;
		break;

	case SEQ_RLE_COUNT_1:
		write_byte(coder->tmp >> 4);
		coder->sequence = SEQ_RLE_COUNT_2;
		break;

	case SEQ_RLE_COUNT_2:
		write_byte(coder->tmp >> 12);
		coder->sequence = SEQ_RLE_COUNT_3;
		break;

	case SEQ_RLE_COUNT_3:
		write_byte(coder->tmp >> 20);

		if (coder->rle.count > REPEAT_COUNT_MAX)
			coder->rle.count -= REPEAT_COUNT_MAX;
		else
			coder->rle.count = 0;

		coder->sequence = SEQ_RLE_SIZE;
		break;

	case SEQ_RLE_SIZE:
		assert(coder->rle.size >= LZMA_SUBBLOCK_RLE_MIN);
		assert(coder->rle.size <= LZMA_SUBBLOCK_RLE_MAX);
		write_byte(coder->rle.size - 1);
		coder->sequence = SEQ_RLE_DATA;
		break;

	case SEQ_RLE_DATA:
		bufcpy(coder->rle.buffer, &coder->pos, coder->rle.size,
				out, out_pos, out_size);
		if (coder->pos < coder->rle.size)
			return LZMA_OK;

		coder->alignment.out_pos += coder->rle.size;

		coder->pos = 0;
		coder->sequence = SEQ_FLUSH;
		break;

	case SEQ_DATA_SIZE_0:
		// We need four bytes for the Size field.
		if (subblock_align(coder, out, out_pos, out_size, 4))
			return LZMA_OK;

		write_byte(0x20 | (coder->tmp & 0x0F));
		coder->sequence = SEQ_DATA_SIZE_1;
		break;

	case SEQ_DATA_SIZE_1:
		write_byte(coder->tmp >> 4);
		coder->sequence = SEQ_DATA_SIZE_2;
		break;

	case SEQ_DATA_SIZE_2:
		write_byte(coder->tmp >> 12);
		coder->sequence = SEQ_DATA_SIZE_3;
		break;

	case SEQ_DATA_SIZE_3:
		write_byte(coder->tmp >> 20);
		coder->sequence = SEQ_DATA;
		break;

	case SEQ_DATA:
		bufcpy(coder->subblock.data, &coder->pos,
				coder->subblock.size, out, out_pos, out_size);
		if (coder->pos < coder->subblock.size)
			return LZMA_OK;

		coder->alignment.out_pos += coder->subblock.size;

		coder->subblock.size = 0;
		coder->pos = 0;
		coder->sequence = SEQ_FLUSH;
		break;

	case SEQ_SUBFILTER_INIT: {
		assert(coder->subblock.size == 0);
		assert(coder->rle.count == 0);
		assert(coder->subfilter.mode == SUB_SET);
		assert(coder->options != NULL);

		// There must be a filter specified.
		if (coder->options->subfilter_options.id
				== LZMA_VLI_VALUE_UNKNOWN)
			return LZMA_HEADER_ERROR;

		// Initialize a raw encoder to work as a Subfilter.
		lzma_options_filter options[2];
		options[0] = coder->options->subfilter_options;
		options[1].id = LZMA_VLI_VALUE_UNKNOWN;

		return_if_error(lzma_raw_encoder_init(
				&coder->subfilter.subcoder, allocator,
				options, LZMA_VLI_VALUE_UNKNOWN, false));

		// Encode the Filter Flags field into a buffer. This should
		// never fail since we have already successfully initialized
		// the Subfilter itself. Check it still, and return
		// LZMA_PROG_ERROR instead of whatever the ret would say.
		lzma_ret ret = lzma_filter_flags_size(
				&coder->subfilter.flags_size, options);
		assert(ret == LZMA_OK);
		if (ret != LZMA_OK)
			return LZMA_PROG_ERROR;

		coder->subfilter.flags = lzma_alloc(
				coder->subfilter.flags_size, allocator);
		if (coder->subfilter.flags == NULL)
			return LZMA_MEM_ERROR;

		// Now we have a big-enough buffer. Encode the Filter Flags.
		// Like above, this should never fail.
		size_t dummy = 0;
		ret = lzma_filter_flags_encode(coder->subfilter.flags,
				&dummy, coder->subfilter.flags_size, options);
		assert(ret == LZMA_OK);
		assert(dummy == coder->subfilter.flags_size);
		if (ret != LZMA_OK || dummy != coder->subfilter.flags_size)
			return LZMA_PROG_ERROR;

		// Write a Subblock indicating a new Subfilter.
		write_byte(0x40);

		coder->options->subfilter_mode = LZMA_SUBFILTER_RUN;
		coder->subfilter.mode = SUB_RUN;
		coder->sequence = SEQ_SUBFILTER_FLAGS;
	}

	// Fall through

	case SEQ_SUBFILTER_FLAGS:
		// Copy the Filter Flags to the output stream.
		bufcpy(coder->subfilter.flags, &coder->pos,
				coder->subfilter.flags_size,
				out, out_pos, out_size);
		if (coder->pos < coder->subfilter.flags_size)
			return LZMA_OK;

		lzma_free(coder->subfilter.flags, allocator);
		coder->subfilter.flags = NULL;

		coder->pos = 0;
		coder->sequence = SEQ_FILL;
		break;

	default:
		return LZMA_PROG_ERROR;
	}

	return LZMA_OK;
}


static lzma_ret
subblock_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)
{
	if (coder->next.code == NULL)
		return subblock_buffer(coder, allocator, in, in_pos, in_size,
				out, out_pos, out_size, action);

	while (*out_pos < out_size
			&& (*in_pos < in_size || action == LZMA_FINISH)) {
		if (!coder->next_finished
				&& coder->temp.pos == coder->temp.size) {
			coder->temp.pos = 0;
			coder->temp.size = 0;

			const lzma_ret ret = coder->next.code(coder->next.coder,
					allocator, in, in_pos, in_size,
					coder->temp.buffer, &coder->temp.size,
					LZMA_BUFFER_SIZE, action);
			if (ret == LZMA_STREAM_END) {
				assert(action == LZMA_FINISH);
				coder->next_finished = true;
			} else if (coder->temp.size == 0 || ret != LZMA_OK) {
				return ret;
			}
		}

		const lzma_ret ret = subblock_buffer(coder, allocator,
				coder->temp.buffer, &coder->temp.pos,
				coder->temp.size, out, out_pos, out_size,
				coder->next_finished ? LZMA_FINISH : LZMA_RUN);
		if (ret == LZMA_STREAM_END) {
			assert(action == LZMA_FINISH);
			assert(coder->next_finished);
			return LZMA_STREAM_END;
		}

		if (ret != LZMA_OK)
			return ret;
	}

	return LZMA_OK;
}


static void
subblock_encoder_end(lzma_coder *coder, lzma_allocator *allocator)
{
	lzma_next_coder_end(&coder->next, allocator);
	lzma_next_coder_end(&coder->subfilter.subcoder, allocator);
	lzma_free(coder->subblock.data, allocator);
	lzma_free(coder->subfilter.flags, allocator);
	return;
}


extern lzma_ret
lzma_subblock_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
		const lzma_filter_info *filters)
{
	if (next->coder == NULL) {
		next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
		if (next->coder == NULL)
			return LZMA_MEM_ERROR;

		next->code = &subblock_encode;
		next->end = &subblock_encoder_end;

		next->coder->next = LZMA_NEXT_CODER_INIT;
		next->coder->subblock.data = NULL;
		next->coder->subblock.limit = 0;
		next->coder->subfilter.subcoder = LZMA_NEXT_CODER_INIT;
	} else {
		lzma_next_coder_end(&next->coder->subfilter.subcoder,
				allocator);
		lzma_free(next->coder->subfilter.flags, allocator);
	}

	next->coder->subfilter.flags = NULL;

	next->coder->next_finished = false;
	next->coder->sequence = SEQ_FILL;
	next->coder->options = filters[0].options;
	next->coder->uncompressed_size = filters[0].uncompressed_size;
	next->coder->pos = 0;

	next->coder->alignment.in_pending = 0;
	next->coder->alignment.in_pos = 0;
	next->coder->alignment.out_pos = 0;
	next->coder->subblock.size = 0;
	next->coder->rle.count = 0;
	next->coder->subfilter.mode = SUB_NONE;

	next->coder->temp.pos = 0;
	next->coder->temp.size = 0;

	// Grab some values from the options structure if it is available.
	size_t subblock_size_limit;
	if (next->coder->options != NULL) {
		if (next->coder->options->alignment
					< LZMA_SUBBLOCK_ALIGNMENT_MIN
				|| next->coder->options->alignment
					> LZMA_SUBBLOCK_ALIGNMENT_MAX) {
			subblock_encoder_end(next->coder, allocator);
			return LZMA_HEADER_ERROR;
		}
		next->coder->alignment.multiple
				= next->coder->options->alignment;
		subblock_size_limit = next->coder->options->subblock_data_size;
	} else {
		next->coder->alignment.multiple
				= LZMA_SUBBLOCK_ALIGNMENT_DEFAULT;
		subblock_size_limit = LZMA_SUBBLOCK_DATA_SIZE_DEFAULT;
	}

	return_if_error(subblock_data_size(next->coder, allocator,
				subblock_size_limit));

	return lzma_next_filter_init(
			&next->coder->next, allocator, filters + 1);
}
