"""
/**************************************************************
 LZSS.C -- A Data Compression Program
***************************************************************
    4/6/1989 Haruhiko Okumura
    Use, distribute, and modify this program freely.
    Please send me your improved versions.
        PC-VAN      SCIENCE
        NIFTY-Serve PAF01022
        CompuServe  74050,1022

**************************************************************/
/*
 *  lzss.c - Package for decompressing lzss compressed objects
 *
 *  Copyright (c) 2003 Apple Computer, Inc.
 *
 *  DRI: Josh de Cesare
 */
"""
from array import array
import struct

N = 4096
F = 18
THRESHOLD = 2
NIL = N

def decompress_lzss(str):
    if str[:8] !="complzss":
        print "decompress_lzss: complzss magic missing"
        return
    decompsize = struct.unpack(">L", str[12:16])[0]
    text_buf = array("B", " "*(N + F - 1))
    src = array("B", str[0x180:])
    srclen = len(src)
    dst = array("B", " "*decompsize)
    r = N - F
    srcidx, dstidx, flags, c = 0, 0, 0, 0

    while True:
        flags >>= 1
        if ((flags & 0x100) == 0):
            if (srcidx >= srclen):
                break
            c = src[srcidx]; srcidx += 1
            flags = c | 0xFF00;

        if (flags & 1):
            if (srcidx >= srclen):
                break
            c = src[srcidx]; srcidx += 1
            dst[dstidx] = c; dstidx += 1
            text_buf[r] = c; r += 1
            r &= (N - 1);
        else:
            if (srcidx >= srclen):
                break
            i = src[srcidx]; srcidx += 1
            if (srcidx >= srclen):
                break
            j = src[srcidx]; srcidx += 1
            i |= ((j & 0xF0) << 4)
            j  =  (j & 0x0F) + THRESHOLD
            for k in xrange(j+1):
                c = text_buf[(i + k) & (N - 1)]
                dst[dstidx] = c; dstidx += 1
                text_buf[r] = c; r += 1
                r &= (N - 1)
    return dst.tostring()

