コード例 #1
0
ファイル: compress_agent.c プロジェクト: levenkov/olver
static TACommandVerdict inflateSync_cmd(TAThread thread,TAInputStream stream)
{
    z_stream strm;
    int res, is_null;

    is_null = readZStream(&stream, &strm);

    START_TARGET_OPERATION(thread);

    if(!is_null)
        res = inflateSync(&strm);
    else
        res = inflateSync(0);

    END_TARGET_OPERATION(thread);

    // Response
    if(!is_null)
        writeZStream(thread, &strm);
    else
        writeZStream(thread, 0);

    writeInt(thread, res);

    sendResponse(thread);

    return taDefaultVerdict;
}
コード例 #2
0
ファイル: infcover.c プロジェクト: 007durgesh219/nomacs
/* cover all inflate() header and trailer cases and code after inflate() */
local void cover_wrap(void)
{
    int ret;
    z_stream strm, copy;
    unsigned char dict[257];

    ret = inflate(Z_NULL, 0);                   assert(ret == Z_STREAM_ERROR);
    ret = inflateEnd(Z_NULL);                   assert(ret == Z_STREAM_ERROR);
    ret = inflateCopy(Z_NULL, Z_NULL);          assert(ret == Z_STREAM_ERROR);
    fputs("inflate bad parameters\n", stderr);

    inf("1f 8b 0 0", "bad gzip method", 0, 31, 0, Z_DATA_ERROR);
    inf("1f 8b 8 80", "bad gzip flags", 0, 31, 0, Z_DATA_ERROR);
    inf("77 85", "bad zlib method", 0, 15, 0, Z_DATA_ERROR);
    inf("8 99", "set window size from header", 0, 0, 0, Z_OK);
    inf("78 9c", "bad zlib window size", 0, 8, 0, Z_DATA_ERROR);
    inf("78 9c 63 0 0 0 1 0 1", "check adler32", 0, 15, 1, Z_STREAM_END);
    inf("1f 8b 8 1e 0 0 0 0 0 0 1 0 0 0 0 0 0", "bad header crc", 0, 47, 1,
        Z_DATA_ERROR);
    inf("1f 8b 8 2 0 0 0 0 0 0 1d 26 3 0 0 0 0 0 0 0 0 0", "check gzip length",
        0, 47, 0, Z_STREAM_END);
    inf("78 90", "bad zlib header check", 0, 47, 0, Z_DATA_ERROR);
    inf("8 b8 0 0 0 1", "need dictionary", 0, 8, 0, Z_NEED_DICT);
    inf("78 9c 63 0", "compute adler32", 0, 15, 1, Z_OK);

    mem_setup(&strm);
    strm.avail_in = 0;
    strm.next_in = Z_NULL;
    ret = inflateInit2(&strm, -8);
    strm.avail_in = 2;
    strm.next_in = (void *)"\x63";
    strm.avail_out = 1;
    strm.next_out = (void *)&ret;
    mem_limit(&strm, 1);
    ret = inflate(&strm, Z_NO_FLUSH);           assert(ret == Z_MEM_ERROR);
    ret = inflate(&strm, Z_NO_FLUSH);           assert(ret == Z_MEM_ERROR);
    mem_limit(&strm, 0);
    memset(dict, 0, 257);
    ret = inflateSetDictionary(&strm, dict, 257);
                                                assert(ret == Z_OK);
    mem_limit(&strm, (sizeof(struct inflate_state) << 1) + 256);
    ret = inflatePrime(&strm, 16, 0);           assert(ret == Z_OK);
    strm.avail_in = 2;
    strm.next_in = (void *)"\x80";
    ret = inflateSync(&strm);                   assert(ret == Z_DATA_ERROR);
    ret = inflate(&strm, Z_NO_FLUSH);           assert(ret == Z_STREAM_ERROR);
    strm.avail_in = 4;
    strm.next_in = (void *)"\0\0\xff\xff";
    ret = inflateSync(&strm);                   assert(ret == Z_OK);
    (void)inflateSyncPoint(&strm);
    ret = inflateCopy(&copy, &strm);            assert(ret == Z_MEM_ERROR);
    mem_limit(&strm, 0);
    ret = inflateUndermine(&strm, 1);           assert(ret == Z_DATA_ERROR);
    (void)inflateMark(&strm);
    ret = inflateEnd(&strm);                    assert(ret == Z_OK);
    mem_done(&strm, "miscellaneous, force memory errors");
}
コード例 #3
0
ファイル: bytecode_api.c プロジェクト: badania/clamav-devel
int32_t cli_bcapi_inflate_process(struct cli_bc_ctx *ctx , int32_t id)
{
    int ret;
    unsigned avail_in_orig, avail_out_orig;
    struct bc_inflate *b = get_inflate(ctx, id);
    if (!b || b->from == -1 || b->to == -1)
	return -1;

    b->stream.avail_in = avail_in_orig =
	cli_bcapi_buffer_pipe_read_avail(ctx, b->from);

    b->stream.next_in = (void*)cli_bcapi_buffer_pipe_read_get(ctx, b->from,
						       b->stream.avail_in);

    b->stream.avail_out = avail_out_orig =
	cli_bcapi_buffer_pipe_write_avail(ctx, b->to);

    b->stream.next_out = cli_bcapi_buffer_pipe_write_get(ctx, b->to,
							 b->stream.avail_out);

    if (!b->stream.avail_in || !b->stream.avail_out || !b->stream.next_in || !b->stream.next_out)
	return -1;
    /* try hard to extract data, skipping over corrupted data */
    do {
	if (!b->needSync) {
	    ret = inflate(&b->stream, Z_NO_FLUSH);
	    if (ret == Z_DATA_ERROR) {
		cli_dbgmsg("bytecode api: inflate at %lu: %s, trying to recover\n", b->stream.total_in,
			   b->stream.msg);
		b->needSync = 1;
	    }
	}
	if (b->needSync) {
	    ret = inflateSync(&b->stream);
	    if (ret == Z_OK) {
		cli_dbgmsg("bytecode api: successfully recovered inflate stream\n");
		b->needSync = 0;
		continue;
	    }
	}
	break;
    } while (1);
    cli_bcapi_buffer_pipe_read_stopped(ctx, b->from, avail_in_orig - b->stream.avail_in);
    cli_bcapi_buffer_pipe_write_stopped(ctx, b->to, avail_out_orig - b->stream.avail_out);

    if (ret == Z_MEM_ERROR) {
	cli_dbgmsg("bytecode api: out of memory!\n");
	cli_bcapi_inflate_done(ctx, id);
	return ret;
    }
    if (ret == Z_STREAM_END) {
	cli_bcapi_inflate_done(ctx, id);
    }
    if (ret == Z_BUF_ERROR) {
	cli_dbgmsg("bytecode api: buffer error!\n");
    }

    return ret;
}
コード例 #4
0
ファイル: tif_zip.c プロジェクト: GrokImageCompression/grok
static int
ZIPDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
{
	static const char module[] = "ZIPDecode";
	ZIPState* sp = DecoderState(tif);

	(void) s;
	assert(sp != NULL);
	assert(sp->state == ZSTATE_INIT_DECODE);

        sp->stream.next_in = tif->tif_rawcp;
	sp->stream.avail_in = (uInt) tif->tif_rawcc;
        
	sp->stream.next_out = op;
	assert(sizeof(sp->stream.avail_out)==4);  /* if this assert gets raised,
	    we need to simplify this code to reflect a ZLib that is likely updated
	    to deal with 8byte memory sizes, though this code will respond
	    appropriately even before we simplify it */
	sp->stream.avail_out = (uInt) occ;
	if ((tmsize_t)sp->stream.avail_out != occ)
	{
		TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
		return (0);
	}
	do {
		int state = inflate(&sp->stream, Z_PARTIAL_FLUSH);
		if (state == Z_STREAM_END)
			break;
		if (state == Z_DATA_ERROR) {
			TIFFErrorExt(tif->tif_clientdata, module,
			    "Decoding error at scanline %lu, %s",
			     (unsigned long) tif->tif_row, SAFE_MSG(sp));
			if (inflateSync(&sp->stream) != Z_OK)
				return (0);
			continue;
		}
		if (state != Z_OK) {
			TIFFErrorExt(tif->tif_clientdata, module, 
				     "ZLib error: %s", SAFE_MSG(sp));
			return (0);
		}
	} while (sp->stream.avail_out > 0);
	if (sp->stream.avail_out != 0) {
		TIFFErrorExt(tif->tif_clientdata, module,
		    "Not enough data at scanline %lu (short " TIFF_UINT64_FORMAT " bytes)",
		    (unsigned long) tif->tif_row, (TIFF_UINT64_T) sp->stream.avail_out);
		return (0);
	}

        tif->tif_rawcp = sp->stream.next_in;
        tif->tif_rawcc = sp->stream.avail_in;

	return (1);
}
コード例 #5
0
int zlibProcessorRead(TProcessingModule *ProcMod, const char *InData, int InLen, char **OutData, int *OutLen, int Flush)
{
int wrote=0, result=0;
#ifdef HAVE_LIBZ
zlibData *ZData;

if (ProcMod->Flags & DPM_READ_FINAL) return(EOF);
ZData=(zlibData *) ProcMod->Data;


	ZData->z_in.avail_in=InLen;
	ZData->z_in.next_in=InData;
	ZData->z_in.avail_out=*OutLen;
	ZData->z_in.next_out=*OutData;

	while ((ZData->z_in.avail_in > 0) || Flush)
	{
		if (Flush) result=inflate(& ZData->z_in, Z_FINISH);
		else result=inflate(& ZData->z_in, Z_NO_FLUSH);

		wrote=(*OutLen)-ZData->z_in.avail_out;

		fprintf(stderr,"result=%d %d %d\n",result,InLen,Flush);

		switch (result)
		{
		case Z_DATA_ERROR: inflateSync(&ZData->z_in); break;
		case Z_ERRNO: if (Flush) ProcMod->Flags |= DPM_READ_FINAL; break;
		case Z_STREAM_ERROR:
		case Z_STREAM_END: ProcMod->Flags |= DPM_READ_FINAL; break;
		}

		if (ProcMod->Flags & DPM_READ_FINAL) break;
		if ((ZData->z_in.avail_in > 0) || Flush)
		{
			(*OutLen)+=BUFSIZ;
			*OutData=(char *) realloc(*OutData,*OutLen);
			ZData->z_in.next_out=(*OutData) + wrote;
			ZData->z_in.avail_out=(*OutLen) - wrote;
		}

	}


#endif
return(wrote);
}
コード例 #6
0
ファイル: example.c プロジェクト: tempbottle/AndroidEmu
/* ===========================================================================
 * Test inflateSync()
 */
void test_sync(
    Byte *compr,
    uLong comprLen,
    Byte *uncompr,
    uLong uncomprLen)
{
    int err;
    z_stream d_stream; /* decompression stream */

    strcpy((char*)uncompr, "garbage");

    d_stream.zalloc = (alloc_func)0;
    d_stream.zfree = (free_func)0;
    d_stream.opaque = (voidpf)0;

    d_stream.next_in  = compr;
    d_stream.avail_in = 2; /* just read the zlib header */

    err = inflateInit(&d_stream);
    CHECK_ERR(err, "inflateInit");

    d_stream.next_out = uncompr;
    d_stream.avail_out = (uInt)uncomprLen;

    inflate(&d_stream, Z_NO_FLUSH);
    CHECK_ERR(err, "inflate");

    d_stream.avail_in = (uInt)comprLen-2;   /* read all compressed data */
    err = inflateSync(&d_stream);           /* but skip the damaged part */
    CHECK_ERR(err, "inflateSync");

    err = inflate(&d_stream, Z_FINISH);
    if (err != Z_DATA_ERROR) {
        fprintf(stderr, "inflate should report DATA_ERROR\n");
        /* Because of incorrect adler32 */
        exit(1);
    }
    err = inflateEnd(&d_stream);
    CHECK_ERR(err, "inflateEnd");

    printf("after inflateSync(): hel%s\n", (char *)uncompr);
}
コード例 #7
0
ファイル: tif_zip.c プロジェクト: KelSolaar/FreeImage
static int
ZIPDecode(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s)
{
	ZIPState* sp = DecoderState(tif);
	static const char module[] = "ZIPDecode";

	(void) s;
	assert(sp != NULL);
        assert(sp->state == ZSTATE_INIT_DECODE);

	sp->stream.next_out = op;
	sp->stream.avail_out = occ;
	do {
		int state = inflate(&sp->stream, Z_PARTIAL_FLUSH);
		if (state == Z_STREAM_END)
			break;
		if (state == Z_DATA_ERROR) {
			TIFFErrorExt(tif->tif_clientdata, module,
			    "%s: Decoding error at scanline %d, %s",
			    tif->tif_name, tif->tif_row, sp->stream.msg);
			if (inflateSync(&sp->stream) != Z_OK)
				return (0);
			continue;
		}
		if (state != Z_OK) {
			TIFFErrorExt(tif->tif_clientdata, module, "%s: zlib error: %s",
			    tif->tif_name, sp->stream.msg);
			return (0);
		}
	} while (sp->stream.avail_out > 0);
	if (sp->stream.avail_out != 0) {
		TIFFErrorExt(tif->tif_clientdata, module,
		    "%s: Not enough data at scanline %d (short %d bytes)",
		    tif->tif_name, tif->tif_row, sp->stream.avail_out);
		return (0);
	}
	return (1);
}
コード例 #8
0
ファイル: flashsv.c プロジェクト: DanielGit/Intrisit201202
static int flashsv_decode_frame(AVCodecContext *avctx,
                                    void *data, int *data_size,
                                    uint8_t *buf, int buf_size)
{
    FlashSVContext *s = avctx->priv_data;
    int h_blocks, v_blocks, h_part, v_part, i, j;
    GetBitContext gb;

    /* no supplementary picture */
    if (buf_size == 0)
        return 0;

    if(s->frame.data[0])
            avctx->release_buffer(avctx, &s->frame);

    init_get_bits(&gb, buf, buf_size * 8);

    /* start to parse the bitstream */
    s->block_width = 16* (get_bits(&gb, 4)+1);
    s->image_width =     get_bits(&gb,12);
    s->block_height= 16* (get_bits(&gb, 4)+1);
    s->image_height=     get_bits(&gb,12);

    /* calculate amount of blocks and the size of the border blocks */
    h_blocks = s->image_width / s->block_width;
    h_part = s->image_width % s->block_width;
    v_blocks = s->image_height / s->block_height;
    v_part = s->image_height % s->block_height;

    /* the block size could change between frames, make sure the buffer
     * is large enough, if not, get a larger one */
    if(s->block_size < s->block_width*s->block_height) {
        if (s->tmpblock != NULL)
            av_free(s->tmpblock);
        if ((s->tmpblock = av_malloc(3*s->block_width*s->block_height)) == NULL) {
            av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n");
            return -1;
        }
    }
    s->block_size = s->block_width*s->block_height;

    /* init the image size once */
    if((avctx->width==0) && (avctx->height==0)){
        avctx->width = s->image_width;
        avctx->height = s->image_height;
    }

    /* check for changes of image width and image height */
    if ((avctx->width != s->image_width) || (avctx->height != s->image_height)) {
        av_log(avctx, AV_LOG_ERROR, "Frame width or height differs from first frames!\n");
        av_log(avctx, AV_LOG_ERROR, "fh = %d, fv %d  vs  ch = %d, cv = %d\n",avctx->height,
        avctx->width,s->image_height,s->image_width);
        return -1;
    }

    av_log(avctx, AV_LOG_DEBUG, "image: %dx%d block: %dx%d num: %dx%d part: %dx%d\n",
        s->image_width, s->image_height, s->block_width, s->block_height,
        h_blocks, v_blocks, h_part, v_part);

    s->frame.reference = 1;
    s->frame.buffer_hints = FF_BUFFER_HINTS_VALID;
    if (avctx->get_buffer(avctx, &s->frame) < 0) {
        av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
        return -1;
    }

    /* loop over all block columns */
    for (j = 0; j < v_blocks + (v_part?1:0); j++)
    {

        int hp = j*s->block_height; // horiz position in frame
        int hs = (j<v_blocks)?s->block_height:v_part; // size of block


        /* loop over all block rows */
        for (i = 0; i < h_blocks + (h_part?1:0); i++)
        {
            int wp = i*s->block_width; // vert position in frame
            int ws = (i<h_blocks)?s->block_width:h_part; // size of block

            /* get the size of the compressed zlib chunk */
            int size = get_bits(&gb, 16);

            if (size == 0) {
                /* no change, don't do anything */
            } else {
                /* decompress block */
                int ret = inflateReset(&(s->zstream));
                if (ret != Z_OK)
                {
                    av_log(avctx, AV_LOG_ERROR, "error in decompression (reset) of block %dx%d\n", i, j);
                    /* return -1; */
                }
                s->zstream.next_in = buf+(get_bits_count(&gb)/8);
                s->zstream.avail_in = size;
                s->zstream.next_out = s->tmpblock;
                s->zstream.avail_out = s->block_size*3;
                ret = inflate(&(s->zstream), Z_FINISH);
                if (ret == Z_DATA_ERROR)
                {
                    av_log(avctx, AV_LOG_ERROR, "Zlib resync occured\n");
                    inflateSync(&(s->zstream));
                    ret = inflate(&(s->zstream), Z_FINISH);
                }

                if ((ret != Z_OK) && (ret != Z_STREAM_END))
                {
                    av_log(avctx, AV_LOG_ERROR, "error in decompression of block %dx%d: %d\n", i, j, ret);
                    /* return -1; */
                }
                copy_region(s->tmpblock, s->frame.data[0], s->image_height-(hp+hs+1), wp, hs, ws, s->frame.linesize[0]);
                skip_bits(&gb, 8*size);   /* skip the consumed bits */
            }
        }
    }

    *data_size = sizeof(AVFrame);
    *(AVFrame*)data = s->frame;

    if ((get_bits_count(&gb)/8) != buf_size)
        av_log(avctx, AV_LOG_ERROR, "buffer not fully consumed (%d != %d)\n",
            buf_size, (get_bits_count(&gb)/8));

    /* report that the buffer was completely consumed */
    return buf_size;
}
コード例 #9
0
// size = size of zipped data.  returns size of unzipped data
int UnZip(unsigned short ** dest, unsigned short * source, int len) {
		bool write = false;
		Bytef *uncompr = NULL;
		z_stream strm;
		uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */
		uLong uncomprLen = comprLen;

		int zip_status = 0;
		//dest = new unsigned short[size*3];
		uncompr = new Bytef[uncomprLen];
		strcpy((char*)uncompr, "garbage");

		// The fields next_in, avail_in, zalloc, zfree and opaque must be initialized
		Bytef * byte_src = new Bytef[len];
		for(int i = 0; i < len; i++) {
			byte_src[i] = (Bytef)source[i];
		}
		//strm.next_in = (Bytef*)source;
		strm.next_in = byte_src;
		strm.avail_in = 0;
		strm.zalloc = (alloc_func)0;
		strm.zfree = (free_func)0;
		strm.opaque = (voidpf)0;
		strm.next_out = (Bytef*)uncompr;

		zip_status = inflateInit2 (&strm, 15+16); 
		if(zip_status != Z_OK) { 
			delete [] uncompr;
			delete [] byte_src;
			return 0;
		}
		int size = 0;
		while (strm.total_out < uncomprLen && strm.total_in < comprLen) {
			size++;
			strm.avail_in = strm.avail_out = 1; /* force small buffers */
			zip_status = inflate(&strm, Z_NO_FLUSH);
			if (zip_status == Z_STREAM_END) break;
			if (zip_status == Z_DATA_ERROR) {
				zip_status = inflateSync(&strm);
			}
			if (zip_status == Z_BUF_ERROR) {
				TRACE("unzip error: %d\n", strm.msg);
			}
			if(zip_status != Z_OK) { 
				delete [] uncompr;
				delete [] byte_src;
				return 0;
			}
			
		}
		zip_status = inflateEnd(&strm); 
		if(zip_status != Z_OK) { 
			delete [] uncompr;
			delete [] byte_src;
			return 0;
		}
		unsigned short * data = *dest;
		data = new unsigned short[size];
		for(int i = 0; i < size; i++) {
			data[i] = uncompr[i];
		}
		delete [] uncompr;
		delete [] byte_src;
		*dest = data;
		return size;
}
コード例 #10
0
int Sg_InflateSync(SgZStream *strm)
{
  return inflateSync(strm->strm);
}
コード例 #11
0
ファイル: OTF_File.c プロジェクト: gzt200361/ThirdParty-2.0.0
int OTF_File_seek( OTF_File* file, uint64_t pos ) {


	int ret;

#ifdef HAVE_ZLIB
	int sync;
	uint64_t read;
#endif /* HAVE_ZLIB */

	if( OTF_FILEMODE_WRITE == file->mode ) {
		
		OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n "
				"current file->mode is OTF_FILEMODE_WRITE. seeking forbidden.\n",
				__FUNCTION__, __FILE__, __LINE__ );

		return -1;
	}
		
	
	if( 0 == OTF_File_revive( file, OTF_FILEMODE_SEEK ) ) {

		OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n "
				"OTF_File_revive() failed.\n",
				__FUNCTION__, __FILE__, __LINE__ );

		return -1;
	}
	

	ret= fseeko( file->file, pos, SEEK_SET );
	
#ifdef HAVE_ZLIB

	if ( NULL != file->z && 0 == ret ) {

		do {

			/*
			OTF_fprintf( stderr, "OTF_File_seek() with zlib: jump to %llu\n", 
					(unsigned long long) pos );
			*/

			read= fread( file->zbuffer, 1, file->zbuffersize, file->file );

			/*
			OTF_fprintf( stderr, "OTF_File_seek() with zlib: read %llu bytes\n", 
					(unsigned long long) read );
			*/

			file->z->next_in= file->zbuffer;
			file->z->avail_in= (uInt) read;
			file->z->total_in= 0;

			/* re-initialize z object */
			inflateEnd( file->z );
			inflateInit( file->z );

			/* do not sync at very beginning of compressed stream because it 
			would skip the first block */
			sync= Z_OK;
			if ( 0 != pos ) {

				sync= inflateSync( file->z );
			}

			if ( Z_OK == sync ) {

				return ret;
			}

			if ( Z_BUF_ERROR == sync ) {
			
				continue;
			}
			
			if ( Z_DATA_ERROR == sync ) {
			
				OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n "
						"Z_DATA_ERROR.\n",
						__FUNCTION__, __FILE__, __LINE__ );
				
				return -1;
			}

			if ( Z_STREAM_ERROR == sync ) {
			
				OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n "
						"Z_STREAM_ERROR.\n",
						__FUNCTION__, __FILE__, __LINE__ );
				
				return -1;
			}

		} while ( 1 );
	}

#endif /* HAVE_ZLIB */

	return ret;
}
コード例 #12
0
ファイル: zlib_drv.c プロジェクト: Airon2014/otp
static ErlDrvSSizeT zlib_ctl(ErlDrvData drv_data, unsigned int command, char *buf,
			     ErlDrvSizeT len, char **rbuf, ErlDrvSizeT rlen)
{
    ZLibData* d = (ZLibData*)drv_data;
    int res;

    switch(command) {
    case DEFLATE_INIT:
	if (len != 4) goto badarg;
	if (d->state != ST_NONE) goto badarg;
	res = deflateInit(&d->s, i32(buf));
	if (res == Z_OK) {
	    d->state = ST_DEFLATE;
	    d->want_crc = 0;
	    d->crc = crc32(0L, Z_NULL, 0);
	}
	return zlib_return(res, rbuf, rlen);

    case DEFLATE_INIT2: {
	int wbits;

	if (len != 20) goto badarg;
	if (d->state != ST_NONE) goto badarg;
	wbits = i32(buf+8);
	res = deflateInit2(&d->s, i32(buf), i32(buf+4), wbits, 
			   i32(buf+12), i32(buf+16));
	if (res == Z_OK) {
	    d->state = ST_DEFLATE;
	    d->want_crc = (wbits < 0);
	    d->crc = crc32(0L, Z_NULL, 0);
	}
	return zlib_return(res, rbuf, rlen);
    }
	
    case DEFLATE_SETDICT:
	if (d->state != ST_DEFLATE) goto badarg;
	res = deflateSetDictionary(&d->s, (unsigned char*)buf, len);
	if (res == Z_OK) {
	    return zlib_value(d->s.adler, rbuf, rlen);
	} else {
	    return zlib_return(res, rbuf, rlen);
	}

    case DEFLATE_RESET:
	if (len != 0) goto badarg;
	if (d->state != ST_DEFLATE) goto badarg;
	driver_deq(d->port, driver_sizeq(d->port));
	res = deflateReset(&d->s);
	return zlib_return(res, rbuf, rlen);	
	
    case DEFLATE_END:
	if (len != 0) goto badarg;
	if (d->state != ST_DEFLATE) goto badarg;
	driver_deq(d->port, driver_sizeq(d->port));
	res = deflateEnd(&d->s);
	d->state = ST_NONE;
	return zlib_return(res, rbuf, rlen);

    case DEFLATE_PARAMS:
	if (len != 8) goto badarg;
	if (d->state != ST_DEFLATE) goto badarg;
	res = deflateParams(&d->s, i32(buf), i32(buf+4));
	return zlib_return(res, rbuf, rlen);

    case DEFLATE:
	if (d->state != ST_DEFLATE) goto badarg;
	if (len != 4) goto badarg;
	res = zlib_deflate(d, i32(buf));
	return zlib_return(res, rbuf, rlen);

    case INFLATE_INIT:
	if (len != 0) goto badarg;
	if (d->state != ST_NONE) goto badarg;
	res = inflateInit(&d->s);
	if (res == Z_OK) {
	    d->state = ST_INFLATE;
	    d->inflate_eos_seen = 0;
	    d->want_crc = 0;
	    d->crc = crc32(0L, Z_NULL, 0);
	}
	return zlib_return(res, rbuf, rlen);	
	
    case INFLATE_INIT2: {
	int wbits;

	if (len != 4) goto badarg;	
	if (d->state != ST_NONE) goto badarg;
	wbits = i32(buf);
	res = inflateInit2(&d->s, wbits);
	if (res == Z_OK) {
	    d->state = ST_INFLATE;
	    d->inflate_eos_seen = 0;
	    d->want_crc = (wbits < 0);
	    d->crc = crc32(0L, Z_NULL, 0);
	}
	return zlib_return(res, rbuf, rlen);
    }
	
    case INFLATE_SETDICT:
	if (d->state != ST_INFLATE) goto badarg;
	res = inflateSetDictionary(&d->s, (unsigned char*)buf, len);
	return zlib_return(res, rbuf, rlen);

    case INFLATE_SYNC:
	if (d->state != ST_INFLATE) goto badarg;
	if (len != 0) goto badarg;
	if (driver_sizeq(d->port) == 0) {
	    res = Z_BUF_ERROR;
	} else {
	    int vlen;
	    SysIOVec* iov = driver_peekq(d->port, &vlen);

	    d->s.next_in = iov[0].iov_base;
	    d->s.avail_in = iov[0].iov_len;
	    res = inflateSync(&d->s);
	}
	return zlib_return(res, rbuf, rlen);

    case INFLATE_RESET:
	if (d->state != ST_INFLATE) goto badarg;
	if (len != 0) goto badarg;
	driver_deq(d->port, driver_sizeq(d->port));
	res = inflateReset(&d->s);
	d->inflate_eos_seen = 0;
	return zlib_return(res, rbuf, rlen);

    case INFLATE_END:
	if (d->state != ST_INFLATE) goto badarg;
	if (len != 0) goto badarg;
	driver_deq(d->port, driver_sizeq(d->port));
	res = inflateEnd(&d->s);
	if (res == Z_OK && d->inflate_eos_seen == 0) {
	    res = Z_DATA_ERROR;
	}
	d->state = ST_NONE;
	return zlib_return(res, rbuf, rlen);

    case INFLATE:
	if (d->state != ST_INFLATE) goto badarg;
	if (len != 4) goto badarg;
	res = zlib_inflate(d, i32(buf));
	if (res == Z_NEED_DICT) {
	    return zlib_value2(3, d->s.adler, rbuf, rlen);
	} else {
	    return zlib_return(res, rbuf, rlen);
	}

    case GET_QSIZE:
	return zlib_value(driver_sizeq(d->port), rbuf, rlen);

    case GET_BUFSZ:
	return zlib_value(d->binsz_need, rbuf, rlen);

    case SET_BUFSZ: {
	int need;
	if (len != 4) goto badarg;
	need = i32(buf);
	if ((need < 16) || (need > 0x00ffffff))
	    goto badarg;
	if (d->binsz_need != need) {
	    d->binsz_need = need;
	    if (d->bin != NULL) {
		if (d->s.avail_out == d->binsz) {
		    driver_free_binary(d->bin);
		    d->bin = NULL;
		    d->binsz = 0;
		}
		else
		    zlib_output(d);
	    }
	}
	return zlib_return(Z_OK, rbuf, rlen);
    }

    case CRC32_0:
	return zlib_value(d->crc, rbuf, rlen);

    case CRC32_1: {
	uLong crc = crc32(0L, Z_NULL, 0);
	crc = crc32(crc, (unsigned char*) buf, len);
	return zlib_value(crc, rbuf, rlen);
    }
	
    case CRC32_2: {
	uLong crc;
	if (len < 4) goto badarg;
	crc = (unsigned int) i32(buf);
	crc = crc32(crc, (unsigned char*) buf+4, len-4);
	return zlib_value(crc, rbuf, rlen);
    }

    case ADLER32_1: {
	uLong adler = adler32(0L, Z_NULL, 0);
	adler = adler32(adler, (unsigned char*) buf, len);
	return zlib_value(adler, rbuf, rlen);
    }
	
    case ADLER32_2: {
       uLong adler;
       if (len < 4) goto badarg;
       adler = (unsigned int) i32(buf);
       adler = adler32(adler, (unsigned char*) buf+4, len-4);
       return zlib_value(adler, rbuf, rlen);
    }

    case CRC32_COMBINE: {
       uLong crc, crc1, crc2, len2;
       if (len != 12) goto badarg;
       crc1 = (unsigned int) i32(buf);
       crc2 = (unsigned int) i32(buf+4);
       len2 = (unsigned int) i32(buf+8);
       crc = crc32_combine(crc1, crc2, len2);
       return zlib_value(crc, rbuf, rlen);
    }

    case ADLER32_COMBINE: {
       uLong adler, adler1, adler2, len2;
       if (len != 12) goto badarg;
       adler1 = (unsigned int) i32(buf);
       adler2 = (unsigned int) i32(buf+4);
       len2   = (unsigned int) i32(buf+8);
       adler  = adler32_combine(adler1, adler2, len2);
       return zlib_value(adler, rbuf, rlen);
    }       
    }

 badarg:
    errno = EINVAL;
    return zlib_return(Z_ERRNO, rbuf, rlen);
}