* ========== Copyright Header Begin ==========================================
* Hypervisor Software File: decomp.c
* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
* - Do no alter or remove copyright notices
* - Redistribution and use of this software in source and binary forms, with
* or without modification, are permitted provided that the following
* - Redistribution of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistribution in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of Sun Microsystems, Inc. or the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* This software is provided "AS IS," without a warranty of any kind.
* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
* MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
* ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN
* OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR
* FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
* DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
* ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
* SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* You acknowledge that this software is not designed, licensed or
* intended for use in the design, construction, operation or maintenance of
* ========== Copyright Header End ============================================
* @(#)decomp.c 1.6 03/04/01
* Copyright 2000, 2003 Sun Microsystems, Inc. All Rights Reserved
* Use is subject to license terms.
* New simplified getcode() routine, adaptive block compress.
/* marker for needed scope management of symbols in this file */
typedef unsigned char uchar_t
;
#define HSIZE 18013 /* 91% occupancy */
#define INIT_BITS 9 /* initial number of bits/code */
PRIVATE
unsigned char *output
;
PRIVATE
unsigned char *input
;
#define putbyte(c) *output++ = (c)
#define putbyte(c) putchar((c))
#define init_output(op) output = (op)
#define init_input(ip, size) input = (ip), data_count = (size)
* Start of Uninitialized globals
typedef unsigned char char_type
;
PRIVATE char_type tab_suffix
[HSIZE
];
PRIVATE
unsigned short tab_prefix
[HSIZE
];
PRIVATE char_type de_stack
[8000];
* End of uninitialized globals
PRIVATE code_int
getcode();
#define maxmaxcode ((code_int)1 << BITS) /* should NEVER generate this code */
#define MAXCODE(n_bits) ((1 << (n_bits)) - 1)
* block compression parameters -- after all codes are used up,
* and compression rate changes, start over.
* These codes should not be changed lightly, as they must not
* lie within the contiguous general code space.
* The END marker is used because some file transfer programs are
* prone to adding garbage bytes to the end of the file.
#define FIRST 258 /* first free entry */
#define END 257 /* End of file marker */
#define CLEAR 256 /* table clear output code */
static char_type magic_header
[] = { "\037\236" }; /* 1F 9E */
* Don't initialize these explicitly because we want them in the
* BSS segment for ROM/RAM systems. It would probably be a good
* idea to initialize them to 0 at run time (when decompress()
static int getcode_offset
;
static int getcode_oldcode
;
* Decompress stdin to stdout. This routine adapts to the codes in the
* file building the "string" table on-the-fly; requiring no table to
* be stored in the compressed file. The tables used herein are shared
* with those of the compress() routine. See the definitions above.
decompress(ip
, insize
, op
)
register char_type
*stackp
;
register int n_bits
; /* number of bits/code */
code_int maxcode
; /* max code, given n_bits */
code_int free_ent
; /* first unused entry */
/* Check the magic number */
if ((getbyte() != (magic_header
[0] & 0xFF)) ||
(getbyte() != (magic_header
[1] & 0xFF))) {
#if defined(DEBUG) && ! defined(STANDALONE)
fprintf(stderr
, "Bad MAGIC number\n");
#if defined(DEBUG) && ! defined(STANDALONE)
fprintf(stderr
, "Bad #bits\n");
* As above, initialize the first 256 entries in the table.
maxcode
= MAXCODE(n_bits
= INIT_BITS
);
for (code
= 255; code
>= 0; code
--) {
tab_suffix
[code
] = (char_type
)code
;
finchar
= oldcode
= getcode(n_bits
);
if (oldcode
== -1 || oldcode
== END
) /* EOF already? */
putbyte((char)finchar
); /* first code must be 8 bits = char */
while ((code
= getcode(n_bits
)) > (code_int
)-1 && code
!= END
) {
for (code
= 255; code
>= 0; code
--)
maxcode
= MAXCODE(n_bits
= INIT_BITS
);
if ((code
= getcode(n_bits
)) == -1) /* EOF */
* Special case for KwKwK string.
* Generate output characters in reverse order
*stackp
++ = tab_suffix
[code
];
*stackp
++ = finchar
= tab_suffix
[code
];
* And put them out in forward order
while (stackp
> de_stack
);
* Generate the new entry.
if ((code
= free_ent
) < (code_int
)maxmaxcode
) {
tab_prefix
[code
] = (unsigned short)oldcode
;
tab_suffix
[code
] = finchar
;
* Remember previous code.
* If the next entry will be too big for the current code
* size, then we must increase the size.
if (free_ent
> maxcode
) {
/* won't get any bigger now */
maxcode
= MAXCODE(n_bits
);
* Read one code from the standard input. If EOF, return -1.
PRIVATE code_int rmask
[] = {
0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f,
0x007f, 0x00ff, 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff,
0x3fff, 0x7fff, (code_int
)0xffff
register int r_off
= getcode_offset
;
register int code
= getcode_oldcode
;
if ((c
= getbyte()) == -1)
getcode_oldcode
= code
>> bits
;
getcode_offset
= r_off
- bits
;
#if defined(DEBUG) && ! defined(STANDALONE)
fprintf(stderr
, "[%x]\n", code
& rmask
[bits
]);
return (code
& rmask
[bits
]);
fprintf(stderr
, "%2x ", c
);
decomp(uchar_t
*src
, int size
, uchar_t
*dest
)
decompress(src
, size
, dest
);