Home | History | Annotate | Line # | Download | only in gzip
      1 /*	$NetBSD: unlz.c,v 1.10 2024/05/04 13:18:06 christos Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2018 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Christos Zoulas.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  * POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 /*  Lzd - Educational decompressor for the lzip format
     33     Copyright (C) 2013-2018 Antonio Diaz Diaz.
     34 
     35     This program is free software. Redistribution and use in source and
     36     binary forms, with or without modification, are permitted provided
     37     that the following conditions are met:
     38 
     39     1. Redistributions of source code must retain the above copyright
     40     notice, this list of conditions and the following disclaimer.
     41 
     42     2. Redistributions in binary form must reproduce the above copyright
     43     notice, this list of conditions and the following disclaimer in the
     44     documentation and/or other materials provided with the distribution.
     45 
     46     This program is distributed in the hope that it will be useful,
     47     but WITHOUT ANY WARRANTY; without even the implied warranty of
     48     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
     49 */
     50 
     51 #include <sys/param.h>
     52 #include <stdio.h>
     53 #include <string.h>
     54 #include <stdlib.h>
     55 #include <stdint.h>
     56 #include <stdbool.h>
     57 #include <errno.h>
     58 #include <unistd.h>
     59 
     60 #define LZ_STATES		12
     61 
     62 #define LITERAL_CONTEXT_BITS	3
     63 #define POS_STATE_BITS		2
     64 #define POS_STATES		(1 << POS_STATE_BITS)
     65 #define POS_STATE_MASK 		(POS_STATES - 1)
     66 
     67 #define STATES			4
     68 #define DIS_SLOT_BITS		6
     69 
     70 #define DIS_MODEL_START		4
     71 #define DIS_MODEL_END		14
     72 
     73 #define MODELED_DISTANCES	(1 << (DIS_MODEL_END / 2))
     74 #define DIS_ALIGN_BITS		4
     75 #define DIS_ALIGN_SIZE		(1 << DIS_ALIGN_BITS)
     76 
     77 #define LOW_BITS		3
     78 #define MID_BITS		3
     79 #define HIGH_BITS		8
     80 
     81 #define LOW_SYMBOLS		(1 << LOW_BITS)
     82 #define MID_SYMBOLS		(1 << MID_BITS)
     83 #define HIGH_SYMBOLS		(1 << HIGH_BITS)
     84 
     85 #define MAX_SYMBOLS 		(LOW_SYMBOLS + MID_SYMBOLS + HIGH_SYMBOLS)
     86 
     87 #define MIN_MATCH_LEN		2
     88 
     89 #define BIT_MODEL_MOVE_BITS	5
     90 #define BIT_MODEL_TOTAL_BITS 	11
     91 #define BIT_MODEL_TOTAL 	(1 << BIT_MODEL_TOTAL_BITS)
     92 #define BIT_MODEL_INIT		(BIT_MODEL_TOTAL / 2)
     93 
     94 static const int lz_st_next[] = {
     95 	0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5,
     96 };
     97 
     98 static bool
     99 lz_st_is_char(int st) {
    100 	return st < 7;
    101 }
    102 
    103 static int
    104 lz_st_get_char(int st) {
    105 	return lz_st_next[st];
    106 }
    107 
    108 static int
    109 lz_st_get_match(int st) {
    110 	return st < 7 ? 7 : 10;
    111 }
    112 
    113 static int
    114 lz_st_get_rep(int st) {
    115 	return st < 7 ? 8 : 11;
    116 }
    117 
    118 static int
    119 lz_st_get_short_rep(int st) {
    120 	return st < 7 ? 9 : 11;
    121 }
    122 
    123 struct lz_len_model {
    124 	int choice1;
    125 	int choice2;
    126 	int bm_low[POS_STATES][LOW_SYMBOLS];
    127 	int bm_mid[POS_STATES][MID_SYMBOLS];
    128 	int bm_high[HIGH_SYMBOLS];
    129 };
    130 
    131 static uint32_t lz_crc[256];
    132 
    133 static void
    134 lz_crc_init(void)
    135 {
    136 	for (unsigned i = 0; i < __arraycount(lz_crc); i++) {
    137 		unsigned c = i;
    138 		for (unsigned j = 0; j < 8; j++) {
    139 			if (c & 1)
    140 				c = 0xEDB88320U ^ (c >> 1);
    141 			else
    142 				c >>= 1;
    143 		}
    144 		lz_crc[i] = c;
    145       }
    146 }
    147 
    148 static void
    149 lz_crc_update(uint32_t *crc, const uint8_t *buf, size_t len)
    150 {
    151 	for (size_t i = 0; i < len; i++)
    152 		*crc = lz_crc[(*crc ^ buf[i]) & 0xFF] ^ (*crc >> 8);
    153 }
    154 
    155 struct lz_range_decoder {
    156 	FILE *fp;
    157 	uint32_t code;
    158 	uint32_t range;
    159 };
    160 
    161 static int
    162 lz_rd_create(struct lz_range_decoder *rd, FILE *fp)
    163 {
    164 	rd->fp = fp;
    165 	rd->code = 0;
    166 	rd->range = ~0;
    167 	for (int i = 0; i < 5; i++)
    168 		rd->code = (rd->code << 8) | (uint8_t)getc(rd->fp);
    169 	return ferror(rd->fp) ? -1 : 0;
    170 }
    171 
    172 static unsigned
    173 lz_rd_decode(struct lz_range_decoder *rd, int num_bits)
    174 {
    175 	unsigned symbol = 0;
    176 
    177 	for (int i = num_bits; i > 0; i--) {
    178 		rd->range >>= 1;
    179 		symbol <<= 1;
    180 		if (rd->code >= rd->range) {
    181 			rd->code -= rd->range;
    182 			symbol |= 1;
    183 		}
    184 		if (rd->range <= 0x00FFFFFFU) {
    185 			rd->range <<= 8;
    186 			rd->code = (rd->code << 8) | (uint8_t)getc(rd->fp);
    187 		}
    188 	}
    189 
    190 	return symbol;
    191 }
    192 
    193 static unsigned
    194 lz_rd_decode_bit(struct lz_range_decoder *rd, int *bm)
    195 {
    196 	unsigned symbol;
    197 	const uint32_t bound = (rd->range >> BIT_MODEL_TOTAL_BITS) * *bm;
    198 
    199 	if(rd->code < bound) {
    200 		rd->range = bound;
    201 		*bm += (BIT_MODEL_TOTAL - *bm) >> BIT_MODEL_MOVE_BITS;
    202 		symbol = 0;
    203 	}
    204 	else {
    205 		rd->range -= bound;
    206 		rd->code -= bound;
    207 		*bm -= *bm >> BIT_MODEL_MOVE_BITS;
    208 		symbol = 1;
    209 	}
    210 
    211 	if (rd->range <= 0x00FFFFFFU) {
    212 		rd->range <<= 8;
    213 		rd->code = (rd->code << 8) | (uint8_t)getc(rd->fp);
    214 	}
    215 	return symbol;
    216 }
    217 
    218 static unsigned
    219 lz_rd_decode_tree(struct lz_range_decoder *rd, int *bm, int num_bits)
    220 {
    221 	unsigned symbol = 1;
    222 
    223 	for (int i = 0; i < num_bits; i++)
    224 		symbol = (symbol << 1) | lz_rd_decode_bit(rd, &bm[symbol]);
    225 
    226 	return symbol - (1 << num_bits);
    227 }
    228 
    229 static unsigned
    230 lz_rd_decode_tree_reversed(struct lz_range_decoder *rd, int *bm, int num_bits)
    231 {
    232 	unsigned symbol = lz_rd_decode_tree(rd, bm, num_bits);
    233 	unsigned reversed_symbol = 0;
    234 
    235 	for (int i = 0; i < num_bits; i++) {
    236 		reversed_symbol = (reversed_symbol << 1) | (symbol & 1);
    237 		symbol >>= 1;
    238 	}
    239 
    240 	return reversed_symbol;
    241 }
    242 
    243 static unsigned
    244 lz_rd_decode_matched(struct lz_range_decoder *rd, int *bm, int match_byte)
    245 {
    246 	unsigned symbol = 1;
    247 
    248 	for (int i = 7; i >= 0; i--) {
    249 		const unsigned match_bit = (match_byte >> i) & 1;
    250 		const unsigned bit = lz_rd_decode_bit(rd,
    251 		    &bm[symbol + (match_bit << 8) + 0x100]);
    252 		symbol = (symbol << 1) | bit;
    253 		if (match_bit != bit) {
    254 			while (symbol < 0x100) {
    255 				symbol = (symbol << 1) |
    256 				    lz_rd_decode_bit(rd, &bm[symbol]);
    257 			}
    258 			break;
    259 		}
    260 	}
    261 	return symbol & 0xFF;
    262 }
    263 
    264 static unsigned
    265 lz_rd_decode_len(struct lz_range_decoder *rd, struct lz_len_model *lm,
    266     int pos_state)
    267 {
    268 	if (lz_rd_decode_bit(rd, &lm->choice1) == 0)
    269 		return lz_rd_decode_tree(rd, lm->bm_low[pos_state], LOW_BITS);
    270 
    271 	if (lz_rd_decode_bit(rd, &lm->choice2) == 0) {
    272 		return LOW_SYMBOLS +
    273 		    lz_rd_decode_tree(rd, lm->bm_mid[pos_state], MID_BITS);
    274 	}
    275 
    276 	return LOW_SYMBOLS + MID_SYMBOLS +
    277            lz_rd_decode_tree(rd, lm->bm_high, HIGH_BITS);
    278 }
    279 
    280 struct lz_decoder {
    281 	FILE *fin, *fout;
    282 	off_t pos, ppos, spos, dict_size;
    283 	bool wrapped;
    284 	uint32_t crc;
    285 	uint8_t *obuf;
    286 	struct lz_range_decoder rdec;
    287 };
    288 
    289 static int
    290 lz_flush(struct lz_decoder *lz)
    291 {
    292 	off_t offs = lz->pos - lz->spos;
    293 	if (offs <= 0)
    294 		return -1;
    295 
    296 	size_t size = (size_t)offs;
    297 	lz_crc_update(&lz->crc, lz->obuf + lz->spos, size);
    298 	if (!tflag && fwrite(lz->obuf + lz->spos, 1, size, lz->fout) != size)
    299 		return -1;
    300 
    301 	lz->wrapped = lz->pos >= lz->dict_size;
    302 	if (lz->wrapped) {
    303 		lz->ppos += lz->pos;
    304 		lz->pos = 0;
    305 	}
    306 	lz->spos = lz->pos;
    307 	return 0;
    308 }
    309 
    310 static void
    311 lz_destroy(struct lz_decoder *lz)
    312 {
    313 	if (lz->fin)
    314 		fclose(lz->fin);
    315 	if (lz->fout)
    316 		fclose(lz->fout);
    317 	free(lz->obuf);
    318 }
    319 
    320 static int
    321 lz_create(struct lz_decoder *lz, int fin, int fdout, int dict_size)
    322 {
    323 	memset(lz, 0, sizeof(*lz));
    324 
    325 	lz->fin = fdopen(dup(fin), "r");
    326 	if (lz->fin == NULL)
    327 		goto out;
    328 
    329 	lz->fout = fdopen(dup(fdout), "w");
    330 	if (lz->fout == NULL)
    331 		goto out;
    332 
    333 	lz->pos = lz->ppos = lz->spos = 0;
    334 	lz->crc = ~0;
    335 	lz->dict_size = dict_size;
    336 	lz->wrapped = false;
    337 
    338 	lz->obuf = malloc(dict_size);
    339 	if (lz->obuf == NULL)
    340 		goto out;
    341 
    342 	if (lz_rd_create(&lz->rdec, lz->fin) == -1)
    343 		goto out;
    344 	return 0;
    345 out:
    346 	lz_destroy(lz);
    347 	return -1;
    348 }
    349 
    350 static uint8_t
    351 lz_peek(const struct lz_decoder *lz, unsigned ahead)
    352 {
    353 	off_t diff = lz->pos - ahead - 1;
    354 
    355 	if (diff >= 0)
    356 		return lz->obuf[diff];
    357 
    358 	if (lz->wrapped)
    359 		return lz->obuf[lz->dict_size + diff];
    360 
    361 	return 0;
    362 }
    363 
    364 static void
    365 lz_put(struct lz_decoder *lz, uint8_t b)
    366 {
    367 	lz->obuf[lz->pos++] = b;
    368 	if (lz->dict_size == lz->pos)
    369 		lz_flush(lz);
    370 }
    371 
    372 static off_t
    373 lz_get_data_position(const struct lz_decoder *lz)
    374 {
    375 	return lz->ppos + lz->pos;
    376 }
    377 
    378 static unsigned
    379 lz_get_crc(const struct lz_decoder *lz)
    380 {
    381 	return lz->crc ^ 0xffffffffU;
    382 }
    383 
    384 static void
    385 lz_bm_init(int *a, size_t l)
    386 {
    387 	for (size_t i = 0; i < l; i++)
    388 		a[i] = BIT_MODEL_INIT;
    389 }
    390 
    391 #define LZ_BM_INIT(a)	lz_bm_init(a, __arraycount(a))
    392 #define LZ_BM_INIT2(a)	do { \
    393 	size_t l = __arraycount(a[0]); \
    394 	for (size_t i = 0; i < __arraycount(a); i++) \
    395 		lz_bm_init(a[i], l); \
    396 } while (0)
    397 
    398 #define LZ_MODEL_INIT(a) do { \
    399 	a.choice1 = BIT_MODEL_INIT; \
    400 	a.choice2 = BIT_MODEL_INIT; \
    401 	LZ_BM_INIT2(a.bm_low); \
    402 	LZ_BM_INIT2(a.bm_mid); \
    403 	LZ_BM_INIT(a.bm_high); \
    404 } while (0)
    405 
    406 static bool
    407 lz_decode_member(struct lz_decoder *lz)
    408 {
    409 	int bm_literal[1 << LITERAL_CONTEXT_BITS][0x300];
    410 	int bm_match[LZ_STATES][POS_STATES];
    411 	int bm_rep[4][LZ_STATES];
    412 	int bm_len[LZ_STATES][POS_STATES];
    413 	int bm_dis_slot[LZ_STATES][1 << DIS_SLOT_BITS];
    414 	int bm_dis[MODELED_DISTANCES - DIS_MODEL_END + 1];
    415 	int bm_align[DIS_ALIGN_SIZE];
    416 
    417 	LZ_BM_INIT2(bm_literal);
    418 	LZ_BM_INIT2(bm_match);
    419 	LZ_BM_INIT2(bm_rep);
    420 	LZ_BM_INIT2(bm_len);
    421 	LZ_BM_INIT2(bm_dis_slot);
    422 	LZ_BM_INIT(bm_dis);
    423 	LZ_BM_INIT(bm_align);
    424 
    425 	struct lz_len_model match_len_model;
    426 	struct lz_len_model rep_len_model;
    427 
    428 	LZ_MODEL_INIT(match_len_model);
    429 	LZ_MODEL_INIT(rep_len_model);
    430 
    431 	struct lz_range_decoder *rd = &lz->rdec;
    432 	unsigned rep[4] = { 0 };
    433 
    434 
    435 	int state = 0;
    436 
    437 	while (!feof(lz->fin) && !ferror(lz->fin)) {
    438 		const int pos_state = lz_get_data_position(lz) & POS_STATE_MASK;
    439 		// bit 1
    440 		if (lz_rd_decode_bit(rd, &bm_match[state][pos_state]) == 0) {
    441 			const uint8_t prev_byte = lz_peek(lz, 0);
    442 			const int literal_state =
    443 			    prev_byte >> (8 - LITERAL_CONTEXT_BITS);
    444 			int *bm = bm_literal[literal_state];
    445 			if (lz_st_is_char(state))
    446 				lz_put(lz, lz_rd_decode_tree(rd, bm, 8));
    447 			else {
    448 				int peek = lz_peek(lz, rep[0]);
    449 				lz_put(lz, lz_rd_decode_matched(rd, bm, peek));
    450 			}
    451 			state = lz_st_get_char(state);
    452 			continue;
    453 		}
    454 		int len;
    455 		// bit 2
    456 		if (lz_rd_decode_bit(rd, &bm_rep[0][state]) != 0) {
    457 			// bit 3
    458 			if (lz_rd_decode_bit(rd, &bm_rep[1][state]) == 0) {
    459 				// bit 4
    460 				if (lz_rd_decode_bit(rd,
    461 				    &bm_len[state][pos_state]) == 0)
    462 				{
    463 					state = lz_st_get_short_rep(state);
    464 					lz_put(lz, lz_peek(lz, rep[0]));
    465 					continue;
    466 				}
    467 			} else {
    468 				unsigned distance;
    469 				// bit 4
    470 				if (lz_rd_decode_bit(rd, &bm_rep[2][state])
    471 				    == 0)
    472 					distance = rep[1];
    473 				else {
    474 					// bit 5
    475 					if (lz_rd_decode_bit(rd,
    476 					    &bm_rep[3][state]) == 0)
    477 						distance = rep[2];
    478 					else {
    479 						distance = rep[3];
    480 						rep[3] = rep[2];
    481 					}
    482 					rep[2] = rep[1];
    483 				}
    484 				rep[1] = rep[0];
    485 				rep[0] = distance;
    486 			}
    487 			state = lz_st_get_rep(state);
    488 			len = MIN_MATCH_LEN +
    489 			    lz_rd_decode_len(rd, &rep_len_model, pos_state);
    490 		} else {
    491 			rep[3] = rep[2]; rep[2] = rep[1]; rep[1] = rep[0];
    492 			len = MIN_MATCH_LEN +
    493 			    lz_rd_decode_len(rd, &match_len_model, pos_state);
    494 			const int len_state =
    495 			    MIN(len - MIN_MATCH_LEN, STATES - 1);
    496 			rep[0] = lz_rd_decode_tree(rd, bm_dis_slot[len_state],
    497 			    DIS_SLOT_BITS);
    498 			if (rep[0] >= DIS_MODEL_START) {
    499 				const unsigned dis_slot = rep[0];
    500 				const int direct_bits = (dis_slot >> 1) - 1;
    501 			        rep[0] = (2 | (dis_slot & 1)) << direct_bits;
    502 				if (dis_slot < DIS_MODEL_END)
    503 					rep[0] += lz_rd_decode_tree_reversed(rd,
    504 					    &bm_dis[rep[0] - dis_slot],
    505                                             direct_bits);
    506 				else {
    507 					rep[0] += lz_rd_decode(rd, direct_bits
    508 					    - DIS_ALIGN_BITS) << DIS_ALIGN_BITS;
    509 					rep[0] += lz_rd_decode_tree_reversed(rd,
    510 					    bm_align, DIS_ALIGN_BITS);
    511 					if (rep[0] == 0xFFFFFFFFU) {
    512 						lz_flush(lz);
    513 						return len == MIN_MATCH_LEN;
    514 					}
    515 				}
    516 			}
    517 			state = lz_st_get_match(state);
    518 			if (rep[0] >= lz->dict_size ||
    519 			    (rep[0] >= lz->pos && !lz->wrapped)) {
    520 				lz_flush(lz);
    521 				return false;
    522 			}
    523 		}
    524 		for (int i = 0; i < len; i++)
    525 			lz_put(lz, lz_peek(lz, rep[0]));
    526     	}
    527 	lz_flush(lz);
    528 	return false;
    529 }
    530 
    531 /*
    532  * 0-3	CRC32 of the uncompressed data
    533  * 4-11 size of the uncompressed data
    534  * 12-19 member size including header and trailer
    535  */
    536 #define TRAILER_SIZE 20
    537 
    538 
    539 static off_t
    540 lz_decode(int fin, int fdout, unsigned dict_size, off_t *insize)
    541 {
    542 	struct lz_decoder lz;
    543 	off_t rv = -1;
    544 
    545 	if (lz_create(&lz, fin, fdout, dict_size) == -1)
    546 		return -1;
    547 
    548 	if (!lz_decode_member(&lz))
    549 		goto out;
    550 
    551 	uint8_t trailer[TRAILER_SIZE];
    552 
    553 	for(size_t i = 0; i < __arraycount(trailer); i++)
    554 		trailer[i] = (uint8_t)getc(lz.fin);
    555 
    556 	unsigned crc = 0;
    557 	for (int i = 3; i >= 0; --i) {
    558 		crc <<= 8;
    559 		crc += trailer[i];
    560 	}
    561 
    562 	int64_t data_size = 0;
    563 	for (int i = 11; i >= 4; --i) {
    564 		data_size <<= 8;
    565 		data_size += trailer[i];
    566 	}
    567 
    568 	if (crc != lz_get_crc(&lz) || data_size != lz_get_data_position(&lz))
    569 		goto out;
    570 
    571 	rv = 0;
    572 	for (int i = 19; i >= 12; --i) {
    573 		rv <<= 8;
    574 		rv += trailer[i];
    575 	}
    576 	if (insize)
    577 		*insize = rv;
    578 #if 0
    579 	/* Does not work with pipes */
    580 	rv = ftello(lz.fout);
    581 #else
    582 	rv = data_size;
    583 #endif
    584 out:
    585 	lz_destroy(&lz);
    586 	return rv;
    587 }
    588 
    589 
    590 /*
    591  * 0-3 magic
    592  * 4 version
    593  * 5 coded dict_size
    594  */
    595 #define HDR_SIZE 6
    596 #define MIN_DICTIONARY_SIZE (1 << 12)
    597 #define MAX_DICTIONARY_SIZE (1 << 29)
    598 
    599 static const char hdrmagic[] = { 'L', 'Z', 'I', 'P', 1 };
    600 
    601 static unsigned
    602 lz_get_dict_size(unsigned char c)
    603 {
    604 	unsigned dict_size = 1 << (c & 0x1f);
    605 	dict_size -= (dict_size >> 4) * ( (c >> 5) & 0x7);
    606 	if (dict_size < MIN_DICTIONARY_SIZE || dict_size > MAX_DICTIONARY_SIZE)
    607 		return 0;
    608 	return dict_size;
    609 }
    610 
    611 static off_t
    612 unlz(int fin, int fout, char *pre, size_t prelen, off_t *bytes_in)
    613 {
    614 	if (lz_crc[0] == 0)
    615 		lz_crc_init();
    616 
    617 	char header[HDR_SIZE];
    618 
    619 	if (pre && prelen)
    620 		memcpy(header, pre, prelen);
    621 
    622 	ssize_t nr = read(fin, header + prelen, sizeof(header) - prelen);
    623 	switch (nr) {
    624 	case -1:
    625 		return -1;
    626 	case 0:
    627 		return prelen ? -1 : 0;
    628 	default:
    629 		if ((size_t)nr != sizeof(header) - prelen)
    630 			return -1;
    631 		break;
    632 	}
    633 
    634 	if (memcmp(header, hdrmagic, sizeof(hdrmagic)) != 0)
    635 		return -1;
    636 
    637 	unsigned dict_size = lz_get_dict_size(header[5]);
    638 	if (dict_size == 0)
    639 		return -1;
    640 
    641 	return lz_decode(fin, fout, dict_size, bytes_in);
    642 }
    643