| /* |
| * CDDL HEADER START |
| * |
| * The contents of this file are subject to the terms of the |
| * Common Development and Distribution License (the "License"). |
| * You may not use this file except in compliance with the License. |
| * |
| * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE |
| * or http://www.opensolaris.org/os/licensing. |
| * See the License for the specific language governing permissions |
| * and limitations under the License. |
| * |
| * When distributing Covered Code, include this CDDL HEADER in each |
| * file and include the License file at usr/src/OPENSOLARIS.LICENSE. |
| * If applicable, add the following below this CDDL HEADER, with the |
| * fields enclosed by brackets "[]" replaced with your own identifying |
| * information: Portions Copyright [yyyy] [name of copyright owner] |
| * |
| * CDDL HEADER END |
| */ |
| |
| /* |
| * Copyright 2009 Sun Microsystems, Inc. All rights reserved. |
| * Use is subject to license terms. |
| */ |
| |
| /* |
| * Zero-length encoding. This is a fast and simple algorithm to eliminate |
| * runs of zeroes. Each chunk of compressed data begins with a length byte, b. |
| * If b < n (where n is the compression parameter) then the next b + 1 bytes |
| * are literal values. If b >= n then the next (256 - b + 1) bytes are zero. |
| */ |
| |
| static int |
| zle_decompress(void *s_start, void *d_start, size_t s_len, size_t d_len, int n) |
| { |
| unsigned char *src = s_start; |
| unsigned char *dst = d_start; |
| unsigned char *s_end = src + s_len; |
| unsigned char *d_end = dst + d_len; |
| |
| while (src < s_end && dst < d_end) { |
| int len = 1 + *src++; |
| if (len <= n) { |
| while (len-- != 0) |
| *dst++ = *src++; |
| } else { |
| len -= n; |
| while (len-- != 0) |
| *dst++ = 0; |
| } |
| } |
| return (dst == d_end ? 0 : -1); |
| } |