packages feed

biohazard-2.0: cbits/zlib.c

#include <stdint.h>
#include <string.h>
#include <zlib.h>

// header stolen from the EOF marker
static const char header[18] = "\x1f\x8b\x8\x4\0\0\0\0\0\xff\x6\0\x42\x43\x2\0" ;

// Compresses one bgzf chunk.  We assemble the header ourselves and call
// deflate in raw mode, because some tools seems to be extremely picky
// about irrelevant details.
int compress_chunk ( char *dest, int *dest_len, char *source, int source_len, int level )
{
    z_stream stream = {0} ;
    stream.next_in = source ;
    stream.next_out = dest + 18 ;
    stream.avail_in = source_len ;
    stream.avail_out = *dest_len ;

    memmove( dest, header, 16 ) ;

    int rc = deflateInit2( &stream, level, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY ) ;
    if( rc != Z_OK ) return rc ;

    rc = deflate( &stream, Z_FINISH ) ;
    int rc2 = deflateEnd( &stream ) ;
    if( rc != Z_STREAM_END ) return rc ;
    if( rc2 != Z_OK ) return rc2 ;

    long crc  = crc32( crc32( 0, 0, 0 ), source, source_len ) ;

    int compressed_length = 18 + 8 + stream.total_out ;
    if (compressed_length > 65536) return Z_BUF_ERROR ;

    dest[16] = (compressed_length-1) & 0xff ;
    dest[17] = (compressed_length-1) >> 8 ;

    *(uint32_t*)(dest+compressed_length-8) = crc ;
    *(uint32_t*)(dest+compressed_length-4) = source_len ;

    *dest_len = compressed_length ;
    return Z_OK ;
}

// Decompresses one bgzf chunk.  We receive no header, so we call
// inflate in raw mode and check the crc32 ourselves.
int decompress_chunk ( char *dest, int dest_len, char *source, int source_len )
{
    z_stream stream = {0} ;
    stream.next_in = source ;
    stream.next_out = dest ;
    stream.avail_in = source_len - 8 ;
    stream.avail_out = dest_len ;

    int rc = inflateInit2( &stream, -15 ) ;
    if( rc != Z_OK ) return rc ;

    rc = inflate( &stream, Z_FINISH ) ;
    int rc2 = inflateEnd( &stream ) ;
    if( rc != Z_STREAM_END ) return rc ;
    if( rc2 != Z_OK ) return rc2 ;

    long crc  = crc32( crc32( 0, 0, 0 ), dest, dest_len ) ;
    return *(uint32_t*)(dest+dest_len-8) == crc && stream.avail_out == 0 ? Z_OK : Z_STREAM_ERROR ;
}