1185029Spjd/* 2185029Spjd * CDDL HEADER START 3185029Spjd * 4185029Spjd * The contents of this file are subject to the terms of the 5185029Spjd * Common Development and Distribution License (the "License"). 6185029Spjd * You may not use this file except in compliance with the License. 7185029Spjd * 8185029Spjd * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9185029Spjd * or http://www.opensolaris.org/os/licensing. 10185029Spjd * See the License for the specific language governing permissions 11185029Spjd * and limitations under the License. 12185029Spjd * 13185029Spjd * When distributing Covered Code, include this CDDL HEADER in each 14185029Spjd * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15185029Spjd * If applicable, add the following below this CDDL HEADER, with the 16185029Spjd * fields enclosed by brackets "[]" replaced with your own identifying 17185029Spjd * information: Portions Copyright [yyyy] [name of copyright owner] 18185029Spjd * 19185029Spjd * CDDL HEADER END 20185029Spjd */ 21185029Spjd 22185029Spjd/* 23185029Spjd * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 24185029Spjd * Use is subject to license terms. 25185029Spjd */ 26185029Spjd 27185029Spjd/*#pragma ident "%Z%%M% %I% %E% SMI"*/ 28185029Spjd 29185029Spjd/* 30185029Spjd * We keep our own copy of this algorithm for 2 main reasons: 31185029Spjd * 1. If we didn't, anyone modifying common/os/compress.c would 32185029Spjd * directly break our on disk format 33185029Spjd * 2. Our version of lzjb does not have a number of checks that the 34185029Spjd * common/os version needs and uses 35185029Spjd * In particular, we are adding the "feature" that compress() can 36185029Spjd * take a destination buffer size and return -1 if the data will not 37185029Spjd * compress to d_len or less. 38185029Spjd */ 39185029Spjd 40185029Spjd#define MATCH_BITS 6 41185029Spjd#define MATCH_MIN 3 42185029Spjd#define MATCH_MAX ((1 << MATCH_BITS) + (MATCH_MIN - 1)) 43185029Spjd#define OFFSET_MASK ((1 << (16 - MATCH_BITS)) - 1) 44185029Spjd#define LEMPEL_SIZE 256 45185029Spjd 46185029Spjd/*ARGSUSED*/ 47185029Spjdstatic int 48185029Spjdlzjb_decompress(void *s_start, void *d_start, size_t s_len, size_t d_len, int n) 49185029Spjd{ 50185029Spjd unsigned char *src = s_start; 51185029Spjd unsigned char *dst = d_start; 52185029Spjd unsigned char *d_end = (unsigned char *)d_start + d_len; 53185029Spjd unsigned char *cpy, copymap = 0; 54185029Spjd int copymask = 1 << (NBBY - 1); 55185029Spjd 56185029Spjd while (dst < d_end) { 57185029Spjd if ((copymask <<= 1) == (1 << NBBY)) { 58185029Spjd copymask = 1; 59185029Spjd copymap = *src++; 60185029Spjd } 61185029Spjd if (copymap & copymask) { 62185029Spjd int mlen = (src[0] >> (NBBY - MATCH_BITS)) + MATCH_MIN; 63185029Spjd int offset = ((src[0] << NBBY) | src[1]) & OFFSET_MASK; 64185029Spjd src += 2; 65185029Spjd if ((cpy = dst - offset) < (unsigned char *)d_start) 66185029Spjd return (-1); 67185029Spjd while (--mlen >= 0 && dst < d_end) 68185029Spjd *dst++ = *cpy++; 69185029Spjd } else { 70185029Spjd *dst++ = *src++; 71185029Spjd } 72185029Spjd } 73185029Spjd return (0); 74185029Spjd} 75