xref: /illumos-gate/usr/src/boot/sys/cddl/boot/zfs/lzjb.c (revision 8eef2ab6)
1199767f8SToomas Soome /*
2199767f8SToomas Soome  * CDDL HEADER START
3199767f8SToomas Soome  *
4199767f8SToomas Soome  * The contents of this file are subject to the terms of the
5199767f8SToomas Soome  * Common Development and Distribution License (the "License").
6199767f8SToomas Soome  * You may not use this file except in compliance with the License.
7199767f8SToomas Soome  *
8199767f8SToomas Soome  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9199767f8SToomas Soome  * or http://www.opensolaris.org/os/licensing.
10199767f8SToomas Soome  * See the License for the specific language governing permissions
11199767f8SToomas Soome  * and limitations under the License.
12199767f8SToomas Soome  *
13199767f8SToomas Soome  * When distributing Covered Code, include this CDDL HEADER in each
14199767f8SToomas Soome  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15199767f8SToomas Soome  * If applicable, add the following below this CDDL HEADER, with the
16199767f8SToomas Soome  * fields enclosed by brackets "[]" replaced with your own identifying
17199767f8SToomas Soome  * information: Portions Copyright [yyyy] [name of copyright owner]
18199767f8SToomas Soome  *
19199767f8SToomas Soome  * CDDL HEADER END
20199767f8SToomas Soome  */
21199767f8SToomas Soome 
22199767f8SToomas Soome /*
23199767f8SToomas Soome  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24199767f8SToomas Soome  * Use is subject to license terms.
25199767f8SToomas Soome  */
26199767f8SToomas Soome 
27199767f8SToomas Soome /*
28199767f8SToomas Soome  * We keep our own copy of this algorithm for 2 main reasons:
29199767f8SToomas Soome  * 	1. If we didn't, anyone modifying common/os/compress.c would
30199767f8SToomas Soome  *         directly break our on disk format
31199767f8SToomas Soome  * 	2. Our version of lzjb does not have a number of checks that the
32199767f8SToomas Soome  *         common/os version needs and uses
33199767f8SToomas Soome  * In particular, we are adding the "feature" that compress() can
34199767f8SToomas Soome  * take a destination buffer size and return -1 if the data will not
35199767f8SToomas Soome  * compress to d_len or less.
36199767f8SToomas Soome  */
37199767f8SToomas Soome 
38199767f8SToomas Soome #define	MATCH_BITS	6
39199767f8SToomas Soome #define	MATCH_MIN	3
40199767f8SToomas Soome #define	MATCH_MAX	((1 << MATCH_BITS) + (MATCH_MIN - 1))
41199767f8SToomas Soome #define	OFFSET_MASK	((1 << (16 - MATCH_BITS)) - 1)
42199767f8SToomas Soome #define	LEMPEL_SIZE	256
43199767f8SToomas Soome 
44199767f8SToomas Soome /*ARGSUSED*/
45199767f8SToomas Soome static int
lzjb_decompress(void * s_start,void * d_start,size_t s_len __unused,size_t d_len,int n __unused)46*8eef2ab6SToomas Soome lzjb_decompress(void *s_start, void *d_start, size_t s_len __unused,
47*8eef2ab6SToomas Soome     size_t d_len, int n __unused)
48199767f8SToomas Soome {
49199767f8SToomas Soome 	unsigned char *src = s_start;
50199767f8SToomas Soome 	unsigned char *dst = d_start;
51199767f8SToomas Soome 	unsigned char *d_end = (unsigned char *)d_start + d_len;
52199767f8SToomas Soome 	unsigned char *cpy, copymap = 0;
53199767f8SToomas Soome 	int copymask = 1 << (NBBY - 1);
54199767f8SToomas Soome 
55199767f8SToomas Soome 	while (dst < d_end) {
56199767f8SToomas Soome 		if ((copymask <<= 1) == (1 << NBBY)) {
57199767f8SToomas Soome 			copymask = 1;
58199767f8SToomas Soome 			copymap = *src++;
59199767f8SToomas Soome 		}
60199767f8SToomas Soome 		if (copymap & copymask) {
61199767f8SToomas Soome 			int mlen = (src[0] >> (NBBY - MATCH_BITS)) + MATCH_MIN;
62199767f8SToomas Soome 			int offset = ((src[0] << NBBY) | src[1]) & OFFSET_MASK;
63199767f8SToomas Soome 			src += 2;
64199767f8SToomas Soome 			if ((cpy = dst - offset) < (unsigned char *)d_start)
65199767f8SToomas Soome 				return (-1);
66199767f8SToomas Soome 			while (--mlen >= 0 && dst < d_end)
67199767f8SToomas Soome 				*dst++ = *cpy++;
68199767f8SToomas Soome 		} else {
69199767f8SToomas Soome 			*dst++ = *src++;
70199767f8SToomas Soome 		}
71199767f8SToomas Soome 	}
72199767f8SToomas Soome 	return (0);
73199767f8SToomas Soome }
74