delta_common.c revision 207753
123599Smarkm///////////////////////////////////////////////////////////////////////////////
251694Sroger//
351694Sroger/// \file       delta_common.c
448781Sroger/// \brief      Common stuff for Delta encoder and decoder
548781Sroger//
623599Smarkm//  Author:     Lasse Collin
723599Smarkm//
823599Smarkm//  This file has been put into the public domain.
923599Smarkm//  You can do whatever you want with this file.
1023599Smarkm//
1123599Smarkm///////////////////////////////////////////////////////////////////////////////
1223599Smarkm
1323599Smarkm#include "delta_common.h"
1423599Smarkm#include "delta_private.h"
1523599Smarkm
1623599Smarkm
1723599Smarkmstatic void
1823599Smarkmdelta_coder_end(lzma_coder *coder, lzma_allocator *allocator)
1923599Smarkm{
2023599Smarkm	lzma_next_end(&coder->next, allocator);
2123599Smarkm	lzma_free(coder, allocator);
2223599Smarkm	return;
2323599Smarkm}
2423599Smarkm
2523599Smarkm
2623599Smarkmextern lzma_ret
2723599Smarkmlzma_delta_coder_init(lzma_next_coder *next, lzma_allocator *allocator,
2823599Smarkm		const lzma_filter_info *filters)
2923599Smarkm{
3023599Smarkm	// Allocate memory for the decoder if needed.
3123599Smarkm	if (next->coder == NULL) {
3223599Smarkm		next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
3323599Smarkm		if (next->coder == NULL)
3439838Ssos			return LZMA_MEM_ERROR;
3523599Smarkm
3651694Sroger		// End function is the same for encoder and decoder.
3751694Sroger		next->end = &delta_coder_end;
3859014Sroger		next->coder->next = LZMA_NEXT_CODER_INIT;
3959014Sroger	}
4059014Sroger
4159014Sroger	// Validate the options.
4259014Sroger	if (lzma_delta_coder_memusage(filters[0].options) == UINT64_MAX)
4359014Sroger		return LZMA_OPTIONS_ERROR;
4451694Sroger
4559014Sroger	// Set the delta distance.
4651694Sroger	const lzma_options_delta *opt = filters[0].options;
4759014Sroger	next->coder->distance = opt->dist;
4859014Sroger
4959014Sroger	// Initialize the rest of the variables.
5059014Sroger	next->coder->pos = 0;
5159014Sroger	memzero(next->coder->history, LZMA_DELTA_DIST_MAX);
5262112Sroger
5362112Sroger	// Initialize the next decoder in the chain, if any.
5462112Sroger	return lzma_next_filter_init(&next->coder->next,
5562112Sroger			allocator, filters + 1);
5662112Sroger}
5751694Sroger
5851694Sroger
5962112Srogerextern uint64_t
6062112Srogerlzma_delta_coder_memusage(const void *options)
6162112Sroger{
6262112Sroger	const lzma_options_delta *opt = options;
6362112Sroger
6462112Sroger	if (opt == NULL || opt->type != LZMA_DELTA_TYPE_BYTE
6562112Sroger			|| opt->dist < LZMA_DELTA_DIST_MIN
6662112Sroger			|| opt->dist > LZMA_DELTA_DIST_MAX)
6762112Sroger		return UINT64_MAX;
6862112Sroger
6962112Sroger	return sizeof(lzma_coder);
7062112Sroger}
7162112Sroger