dctx.state = UNCOMP_DATA;
if (dctx.uncomplen == 0) dctx.state = OUTSIDEBLK;	 else dctx.state = UNCOMP_DATA;
int zlib_decompress_block(unsigned char *block, int len,			  unsigned char **outblock, int *outlen){    const coderecord *rec;    int code, blktype, rep, dist, nlen;    static const unsigned char lenlenmap[] = {	16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15    };    dctx.outblk = NULL;    dctx.outsize = dctx.outlen = 0;    while (len > 0 || dctx.nbits > 0) {	while (dctx.nbits < 24 && len > 0) {	    dctx.bits |= (*block++) << dctx.nbits;	    dctx.nbits += 8;	    len--;	}	switch (dctx.state) {	  case START:	    /* Expect 16-bit zlib header, which we'll dishonourably ignore. */	    if (dctx.nbits < 16)		goto finished;	       /* done all we can */	    EATBITS(16);	    dctx.state = OUTSIDEBLK;	    break;	  case OUTSIDEBLK:	    /* Expect 3-bit block header. */	    if (dctx.nbits < 3)		goto finished;	       /* done all we can */	    EATBITS(1);	    blktype = dctx.bits & 3;	    EATBITS(2);	    if (blktype == 0) {		int to_eat = dctx.nbits & 7;		dctx.state = UNCOMP_LEN;		EATBITS(to_eat);       /* align to byte boundary */	    } else if (blktype == 1) {		dctx.currlentable = dctx.staticlentable;		dctx.currdisttable = dctx.staticdisttable;		dctx.state = INBLK;	    } else if (blktype == 2) {		dctx.state = TREES_HDR;	    }	    break;	  case TREES_HDR:	    /*	     * Dynamic block header. Five bits of HLIT, five of	     * HDIST, four of HCLEN.	     */	    if (dctx.nbits < 5 + 5 + 4)		goto finished;	       /* done all we can */	    dctx.hlit = 257 + (dctx.bits & 31);	    EATBITS(5);	    dctx.hdist = 1 + (dctx.bits & 31);	    EATBITS(5);	    dctx.hclen = 4 + (dctx.bits & 15);	    EATBITS(4);	    dctx.lenptr = 0;	    dctx.state = TREES_LENLEN;	    memset(dctx.lenlen, 0, sizeof(dctx.lenlen));	    break;	  case TREES_LENLEN:	    if (dctx.nbits < 3)		goto finished;	    while (dctx.lenptr < dctx.hclen && dctx.nbits >= 3) {		dctx.lenlen[lenlenmap[dctx.lenptr++]] =		    (unsigned char) (dctx.bits & 7);		EATBITS(3);	    }	    if (dctx.lenptr == dctx.hclen) {		dctx.lenlentable = zlib_mktable(dctx.lenlen, 19);		dctx.state = TREES_LEN;		dctx.lenptr = 0;	    }	    break;	  case TREES_LEN:	    if (dctx.lenptr >= dctx.hlit + dctx.hdist) {		dctx.currlentable = zlib_mktable(dctx.lengths, dctx.hlit);		dctx.currdisttable = zlib_mktable(dctx.lengths + dctx.hlit,						  dctx.hdist);		zlib_freetable(&dctx.lenlentable);		dctx.state = INBLK;		break;	    }	    code =		zlib_huflookup(&dctx.bits, &dctx.nbits, dctx.lenlentable);	    if (code == -1)		goto finished;	    if (code < 16)		dctx.lengths[dctx.lenptr++] = code;	    else {		dctx.lenextrabits = (code == 16 ? 2 : code == 17 ? 3 : 7);		dctx.lenaddon = (code == 18 ? 11 : 3);		dctx.lenrep = (code == 16 && dctx.lenptr > 0 ?			       dctx.lengths[dctx.lenptr - 1] : 0);		dctx.state = TREES_LENREP;	    }	    break;	  case TREES_LENREP:	    if (dctx.nbits < dctx.lenextrabits)		goto finished;	    rep =		dctx.lenaddon +		(dctx.bits & ((1 << dctx.lenextrabits) - 1));	    EATBITS(dctx.lenextrabits);	    while (rep > 0 && dctx.lenptr < dctx.hlit + dctx.hdist) {		dctx.lengths[dctx.lenptr] = dctx.lenrep;		dctx.lenptr++;		rep--;	    }	    dctx.state = TREES_LEN;	    break;	  case INBLK:	    code =		zlib_huflookup(&dctx.bits, &dctx.nbits, dctx.currlentable);	    if (code == -1)		goto finished;	    if (code < 256)		zlib_emit_char(code);	    else if (code == 256) {		dctx.state = OUTSIDEBLK;		if (dctx.currlentable != dctx.staticlentable)		    zlib_freetable(&dctx.currlentable);		if (dctx.currdisttable != dctx.staticdisttable)		    zlib_freetable(&dctx.currdisttable);	    } else if (code < 286) {   /* static tree can give >285; ignore */		dctx.state = GOTLENSYM;		dctx.sym = code;	    }	    break;	  case GOTLENSYM:	    rec = &lencodes[dctx.sym - 257];	    if (dctx.nbits < rec->extrabits)		goto finished;	    dctx.len =		rec->min + (dctx.bits & ((1 << rec->extrabits) - 1));	    EATBITS(rec->extrabits);	    dctx.state = GOTLEN;	    break;	  case GOTLEN:	    code =		zlib_huflookup(&dctx.bits, &dctx.nbits,			       dctx.currdisttable);	    if (code == -1)		goto finished;	    dctx.state = GOTDISTSYM;	    dctx.sym = code;	    break;	  case GOTDISTSYM:	    rec = &distcodes[dctx.sym];	    if (dctx.nbits < rec->extrabits)		goto finished;	    dist = rec->min + (dctx.bits & ((1 << rec->extrabits) - 1));	    EATBITS(rec->extrabits);	    dctx.state = INBLK;	    while (dctx.len--)		zlib_emit_char(dctx.window[(dctx.winpos - dist) &					   (WINSIZE - 1)]);	    break;	  case UNCOMP_LEN:	    /*	     * Uncompressed block. We expect to see a 16-bit LEN.	     */	    if (dctx.nbits < 16)		goto finished;	    dctx.uncomplen = dctx.bits & 0xFFFF;	    EATBITS(16);	    dctx.state = UNCOMP_NLEN;	    break;	  case UNCOMP_NLEN:	    /*	     * Uncompressed block. We expect to see a 16-bit NLEN,	     * which should be the one's complement of the previous	     * LEN.	     */	    if (dctx.nbits < 16)		goto finished;	    nlen = dctx.bits & 0xFFFF;	    EATBITS(16);	    dctx.state = UNCOMP_DATA;	    break;	  case UNCOMP_DATA:	    if (dctx.nbits < 8)		goto finished;	    zlib_emit_char(dctx.bits & 0xFF);	    EATBITS(8);	    if (--dctx.uncomplen == 0)		dctx.state = OUTSIDEBLK;	/* end of uncompressed block */	    break;	}    }  finished:    *outblock = dctx.outblk;    *outlen = dctx.outlen;    return 1;}