12940b44dSPeter Avalos ///////////////////////////////////////////////////////////////////////////////
22940b44dSPeter Avalos //
32940b44dSPeter Avalos /// \file       delta_common.c
42940b44dSPeter Avalos /// \brief      Common stuff for Delta encoder and decoder
52940b44dSPeter Avalos //
62940b44dSPeter Avalos //  Author:     Lasse Collin
72940b44dSPeter Avalos //
82940b44dSPeter Avalos //  This file has been put into the public domain.
92940b44dSPeter Avalos //  You can do whatever you want with this file.
102940b44dSPeter Avalos //
112940b44dSPeter Avalos ///////////////////////////////////////////////////////////////////////////////
122940b44dSPeter Avalos 
132940b44dSPeter Avalos #include "delta_common.h"
142940b44dSPeter Avalos #include "delta_private.h"
152940b44dSPeter Avalos 
162940b44dSPeter Avalos 
172940b44dSPeter Avalos static void
delta_coder_end(void * coder_ptr,const lzma_allocator * allocator)18*46a2189dSzrj delta_coder_end(void *coder_ptr, const lzma_allocator *allocator)
192940b44dSPeter Avalos {
20*46a2189dSzrj 	lzma_delta_coder *coder = coder_ptr;
212940b44dSPeter Avalos 	lzma_next_end(&coder->next, allocator);
222940b44dSPeter Avalos 	lzma_free(coder, allocator);
232940b44dSPeter Avalos 	return;
242940b44dSPeter Avalos }
252940b44dSPeter Avalos 
262940b44dSPeter Avalos 
272940b44dSPeter Avalos extern lzma_ret
lzma_delta_coder_init(lzma_next_coder * next,const lzma_allocator * allocator,const lzma_filter_info * filters)2815ab8c86SJohn Marino lzma_delta_coder_init(lzma_next_coder *next, const lzma_allocator *allocator,
292940b44dSPeter Avalos 		const lzma_filter_info *filters)
302940b44dSPeter Avalos {
312940b44dSPeter Avalos 	// Allocate memory for the decoder if needed.
32*46a2189dSzrj 	lzma_delta_coder *coder = next->coder;
33*46a2189dSzrj 	if (coder == NULL) {
34*46a2189dSzrj 		coder = lzma_alloc(sizeof(lzma_delta_coder), allocator);
35*46a2189dSzrj 		if (coder == NULL)
362940b44dSPeter Avalos 			return LZMA_MEM_ERROR;
372940b44dSPeter Avalos 
38*46a2189dSzrj 		next->coder = coder;
39*46a2189dSzrj 
402940b44dSPeter Avalos 		// End function is the same for encoder and decoder.
412940b44dSPeter Avalos 		next->end = &delta_coder_end;
42*46a2189dSzrj 		coder->next = LZMA_NEXT_CODER_INIT;
432940b44dSPeter Avalos 	}
442940b44dSPeter Avalos 
452940b44dSPeter Avalos 	// Validate the options.
462940b44dSPeter Avalos 	if (lzma_delta_coder_memusage(filters[0].options) == UINT64_MAX)
472940b44dSPeter Avalos 		return LZMA_OPTIONS_ERROR;
482940b44dSPeter Avalos 
492940b44dSPeter Avalos 	// Set the delta distance.
502940b44dSPeter Avalos 	const lzma_options_delta *opt = filters[0].options;
51*46a2189dSzrj 	coder->distance = opt->dist;
522940b44dSPeter Avalos 
532940b44dSPeter Avalos 	// Initialize the rest of the variables.
54*46a2189dSzrj 	coder->pos = 0;
55*46a2189dSzrj 	memzero(coder->history, LZMA_DELTA_DIST_MAX);
562940b44dSPeter Avalos 
572940b44dSPeter Avalos 	// Initialize the next decoder in the chain, if any.
58*46a2189dSzrj 	return lzma_next_filter_init(&coder->next, allocator, filters + 1);
592940b44dSPeter Avalos }
602940b44dSPeter Avalos 
612940b44dSPeter Avalos 
622940b44dSPeter Avalos extern uint64_t
lzma_delta_coder_memusage(const void * options)632940b44dSPeter Avalos lzma_delta_coder_memusage(const void *options)
642940b44dSPeter Avalos {
652940b44dSPeter Avalos 	const lzma_options_delta *opt = options;
662940b44dSPeter Avalos 
672940b44dSPeter Avalos 	if (opt == NULL || opt->type != LZMA_DELTA_TYPE_BYTE
682940b44dSPeter Avalos 			|| opt->dist < LZMA_DELTA_DIST_MIN
692940b44dSPeter Avalos 			|| opt->dist > LZMA_DELTA_DIST_MAX)
702940b44dSPeter Avalos 		return UINT64_MAX;
712940b44dSPeter Avalos 
72*46a2189dSzrj 	return sizeof(lzma_delta_coder);
732940b44dSPeter Avalos }
74