11ba4a712SPawel Jakub Dawidek /* 21ba4a712SPawel Jakub Dawidek * CDDL HEADER START 31ba4a712SPawel Jakub Dawidek * 41ba4a712SPawel Jakub Dawidek * The contents of this file are subject to the terms of the 51ba4a712SPawel Jakub Dawidek * Common Development and Distribution License (the "License"). 61ba4a712SPawel Jakub Dawidek * You may not use this file except in compliance with the License. 71ba4a712SPawel Jakub Dawidek * 81ba4a712SPawel Jakub Dawidek * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 91ba4a712SPawel Jakub Dawidek * or http://www.opensolaris.org/os/licensing. 101ba4a712SPawel Jakub Dawidek * See the License for the specific language governing permissions 111ba4a712SPawel Jakub Dawidek * and limitations under the License. 121ba4a712SPawel Jakub Dawidek * 131ba4a712SPawel Jakub Dawidek * When distributing Covered Code, include this CDDL HEADER in each 141ba4a712SPawel Jakub Dawidek * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 151ba4a712SPawel Jakub Dawidek * If applicable, add the following below this CDDL HEADER, with the 161ba4a712SPawel Jakub Dawidek * fields enclosed by brackets "[]" replaced with your own identifying 171ba4a712SPawel Jakub Dawidek * information: Portions Copyright [yyyy] [name of copyright owner] 181ba4a712SPawel Jakub Dawidek * 191ba4a712SPawel Jakub Dawidek * CDDL HEADER END 201ba4a712SPawel Jakub Dawidek */ 211ba4a712SPawel Jakub Dawidek 221ba4a712SPawel Jakub Dawidek /* 231ba4a712SPawel Jakub Dawidek * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 241ba4a712SPawel Jakub Dawidek * Use is subject to license terms. 251ba4a712SPawel Jakub Dawidek */ 261ba4a712SPawel Jakub Dawidek 271ba4a712SPawel Jakub Dawidek /*#pragma ident "%Z%%M% %I% %E% SMI"*/ 281ba4a712SPawel Jakub Dawidek 291ba4a712SPawel Jakub Dawidek /* 301ba4a712SPawel Jakub Dawidek * We keep our own copy of this algorithm for 2 main reasons: 311ba4a712SPawel Jakub Dawidek * 1. If we didn't, anyone modifying common/os/compress.c would 321ba4a712SPawel Jakub Dawidek * directly break our on disk format 331ba4a712SPawel Jakub Dawidek * 2. Our version of lzjb does not have a number of checks that the 341ba4a712SPawel Jakub Dawidek * common/os version needs and uses 351ba4a712SPawel Jakub Dawidek * In particular, we are adding the "feature" that compress() can 361ba4a712SPawel Jakub Dawidek * take a destination buffer size and return -1 if the data will not 371ba4a712SPawel Jakub Dawidek * compress to d_len or less. 381ba4a712SPawel Jakub Dawidek */ 391ba4a712SPawel Jakub Dawidek 401ba4a712SPawel Jakub Dawidek #define MATCH_BITS 6 411ba4a712SPawel Jakub Dawidek #define MATCH_MIN 3 421ba4a712SPawel Jakub Dawidek #define MATCH_MAX ((1 << MATCH_BITS) + (MATCH_MIN - 1)) 431ba4a712SPawel Jakub Dawidek #define OFFSET_MASK ((1 << (16 - MATCH_BITS)) - 1) 441ba4a712SPawel Jakub Dawidek #define LEMPEL_SIZE 256 451ba4a712SPawel Jakub Dawidek 461ba4a712SPawel Jakub Dawidek /*ARGSUSED*/ 471ba4a712SPawel Jakub Dawidek static int 481ba4a712SPawel Jakub Dawidek lzjb_decompress(void *s_start, void *d_start, size_t s_len, size_t d_len, int n) 491ba4a712SPawel Jakub Dawidek { 501ba4a712SPawel Jakub Dawidek unsigned char *src = s_start; 511ba4a712SPawel Jakub Dawidek unsigned char *dst = d_start; 521ba4a712SPawel Jakub Dawidek unsigned char *d_end = (unsigned char *)d_start + d_len; 531ba4a712SPawel Jakub Dawidek unsigned char *cpy, copymap = 0; 541ba4a712SPawel Jakub Dawidek int copymask = 1 << (NBBY - 1); 551ba4a712SPawel Jakub Dawidek 561ba4a712SPawel Jakub Dawidek while (dst < d_end) { 571ba4a712SPawel Jakub Dawidek if ((copymask <<= 1) == (1 << NBBY)) { 581ba4a712SPawel Jakub Dawidek copymask = 1; 591ba4a712SPawel Jakub Dawidek copymap = *src++; 601ba4a712SPawel Jakub Dawidek } 611ba4a712SPawel Jakub Dawidek if (copymap & copymask) { 621ba4a712SPawel Jakub Dawidek int mlen = (src[0] >> (NBBY - MATCH_BITS)) + MATCH_MIN; 631ba4a712SPawel Jakub Dawidek int offset = ((src[0] << NBBY) | src[1]) & OFFSET_MASK; 641ba4a712SPawel Jakub Dawidek src += 2; 651ba4a712SPawel Jakub Dawidek if ((cpy = dst - offset) < (unsigned char *)d_start) 661ba4a712SPawel Jakub Dawidek return (-1); 671ba4a712SPawel Jakub Dawidek while (--mlen >= 0 && dst < d_end) 681ba4a712SPawel Jakub Dawidek *dst++ = *cpy++; 691ba4a712SPawel Jakub Dawidek } else { 701ba4a712SPawel Jakub Dawidek *dst++ = *src++; 711ba4a712SPawel Jakub Dawidek } 721ba4a712SPawel Jakub Dawidek } 731ba4a712SPawel Jakub Dawidek return (0); 741ba4a712SPawel Jakub Dawidek } 75