X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=src%2Fnbvtf%2Fnbvtf.h;fp=src%2Fnbvtf%2Fnbvtf.h;h=0000000000000000000000000000000000000000;hb=2937c186209f5ff766cacc9f17a118744ede7b7a;hp=3ed85369cd0f02b0dbae43f30f0b3992fcfa9b93;hpb=2d8415532d13da0132b762dcff2d043b77441d33;p=convexer.git diff --git a/src/nbvtf/nbvtf.h b/src/nbvtf/nbvtf.h deleted file mode 100644 index 3ed8536..0000000 --- a/src/nbvtf/nbvtf.h +++ /dev/null @@ -1,799 +0,0 @@ -// nbvtf.h - v1.02 - Writer for Valve Texture Format - public domain -// Written by Harry 'hgn' Godden -// -// Credits: -// Rich Geldreich - bc7enc (BC1/BC3 High Quality texture compression) -// Fabian "ryg" Giesen, stb - stb_dxt (BC1/BC3 realtime compressors) -// Sean Barrett - stb_image.h, stb_image_write.h (Image I/O) -// -// Note: -// This library assumes normal maps are input in OpenGL(correct) format, and will be converted into DirectX(incorrect) at -// compile time automatically. Do not submit DirectX normals into this software. -// -// Since this project uses stb_image, use '#define STB_IMAGE_IMPLEMENTATION' before including -// Additionally, to use high quality DXT, '#define USE_LIBRGBCX' -// -// USAGE: -// Call these functions: -// int nbvtf_convert( const char *src, int w, int h, int mipmap, EImageFormat_t format, uint32_t usr_flags, const char *dest ); -// int nbvtf_write( uint8_t *src, int w, int h, int mipmap, EImageFormat_t format, uint32_t usr_flags, const char *dest ); -// -// Param definitions: -// src - RGBA byte data of image -// w - width of image -// h - height of image -// mipmap - enable mipmap generation (box filter), 1/0 -// format - Choose from: k_EImageFormat_DXT1, compressedk_EImageFormat_DXT5, k_EImageFormat_BGR888, k_EImageFormat_ABGR8888 -// usr_flags - You can append any flags but only really need TEXTUREFLAGS_NORMAL if texture is normal map -// dest - file path to write vtf to -// -// Convert specific: -// src - file path of source image to convert -// w, h - MAXIMUM image dimentions of final product. Set as 0 to be automatic -// -// version history: -// v1.02 - Improved box filtering, small bug fixes -// v1.01 - switch to OpenGL normal format for input -// v1.00 - (hgn) first release -// -// LICENSE -// See end of file for license information. - -#ifdef __cplusplus -extern "C" { -#endif - -#define NBVTF_MAX_MIPLEVELS 9 -#define nbvtf__min(a,b) (((a)<(b))?(a):(b)) -#define nbvtf__max(a,b) (((a)>(b))?(a):(b)) - -#ifdef NBVTF_AS_SO - #include - #include - #include - #include - - #define NBVTF_SHOW_STDERR - #define STB_IMAGE_IMPLEMENTATION -#endif - -#include "stb/stb_image.h" - -#ifdef USE_LIBRGBCX - #include "librgbcx.h" -#else - #define STB_DXT_IMPLEMENTATION - #include "stb/stb_dxt.h" -#endif - -#ifdef NBVTF_SHOW_STDERR - #define NBVTF_ERR(...) -#else - #define NBVTF_ERR(...) fprintf( stderr, __VA_ARGS__ ) -#endif - -#pragma pack(push, 1) - -typedef enum EImageFormat -{ - // Name // Supported? - k_EImageFormat_NONE = -1, - k_EImageFormat_RGBA8888 = 0, // YES - k_EImageFormat_ABGR8888, - k_EImageFormat_RGB888, // YES - k_EImageFormat_BGR888, - k_EImageFormat_RGB565, - k_EImageFormat_I8, - k_EImageFormat_IA88, - k_EImageFormat_P8, - k_EImageFormat_A8, - k_EImageFormat_RGB888_BLUESCREEN, - k_EImageFormat_BGR888_BLUESCREEN, - k_EImageFormat_ARGB8888, - k_EImageFormat_BGRA8888, - k_EImageFormat_DXT1, // YES - k_EImageFormat_DXT3, - k_EImageFormat_DXT5, // YES - k_EImageFormat_BGRX8888, - k_EImageFormat_BGR565, - k_EImageFormat_BGRX5551, - k_EImageFormat_BGRA4444, - k_EImageFormat_DXT1_ONEBITALPHA, - k_EImageFormat_BGRA5551, - k_EImageFormat_UV88, - k_EImageFormat_UVWQ8888, - k_EImageFormat_RGBA16161616F, - k_EImageFormat_RGBA16161616, - k_EImageFormat_UVLX8888 -} EImageFormat_t; - -const char *vtf_format_strings[] = -{ - // Name // Supported? - "RGBA8888", - "ABGR8888", - "RGB888", - "BGR888", - "RGB565", - "I8", - "IA88", - "P8", - "A8", - "RGB888_BLUESCREEN", - "BGR888_BLUESCREEN", - "ARGB8888", - "BGRA8888", -#ifdef USE_LIBRGBCX - "DXT1 (rgbcx.h)", -#else - "DXT1 (stb_dxt.h)", -#endif - "DXT3", -#ifdef USE_LIBRGBCX - "DXT5 (rgbcx.h)", -#else - "DXT5 (stb_dxt.h)", -#endif - "BGRX8888", - "BGR565", - "BGRX5551", - "BGRA4444", - "DXT1_ONEBITALPHA", - "BGRA5551", - "UV88", - "UVWQ8888", - "RGBA16161616F", - "RGBA16161616", - "UVLX8888" -}; - -enum flag -{ - // Flags from the *.txt config file - TEXTUREFLAGS_POINTSAMPLE = 0x00000001, - TEXTUREFLAGS_TRILINEAR = 0x00000002, - TEXTUREFLAGS_CLAMPS = 0x00000004, - TEXTUREFLAGS_CLAMPT = 0x00000008, - TEXTUREFLAGS_ANISOTROPIC = 0x00000010, - TEXTUREFLAGS_HINT_DXT5 = 0x00000020, - TEXTUREFLAGS_PWL_CORRECTED = 0x00000040, - TEXTUREFLAGS_NORMAL = 0x00000080, - TEXTUREFLAGS_NOMIP = 0x00000100, - TEXTUREFLAGS_NOLOD = 0x00000200, - TEXTUREFLAGS_ALL_MIPS = 0x00000400, - TEXTUREFLAGS_PROCEDURAL = 0x00000800, - - // These are automatically generated by vtex from the texture data. - TEXTUREFLAGS_ONEBITALPHA = 0x00001000, - TEXTUREFLAGS_EIGHTBITALPHA = 0x00002000, - - // Newer flags from the *.txt config file - TEXTUREFLAGS_ENVMAP = 0x00004000, - TEXTUREFLAGS_RENDERTARGET = 0x00008000, - TEXTUREFLAGS_DEPTHRENDERTARGET = 0x00010000, - TEXTUREFLAGS_NODEBUGOVERRIDE = 0x00020000, - TEXTUREFLAGS_SINGLECOPY = 0x00040000, - TEXTUREFLAGS_PRE_SRGB = 0x00080000, - - TEXTUREFLAGS_UNUSED_00100000 = 0x00100000, - TEXTUREFLAGS_UNUSED_00200000 = 0x00200000, - TEXTUREFLAGS_UNUSED_00400000 = 0x00400000, - - TEXTUREFLAGS_NODEPTHBUFFER = 0x00800000, - - TEXTUREFLAGS_UNUSED_01000000 = 0x01000000, - - TEXTUREFLAGS_CLAMPU = 0x02000000, - TEXTUREFLAGS_VERTEXTEXTURE = 0x04000000, - TEXTUREFLAGS_SSBUMP = 0x08000000, - - TEXTUREFLAGS_UNUSED_10000000 = 0x10000000, - - TEXTUREFLAGS_BORDER = 0x20000000, - - TEXTUREFLAGS_UNUSED_40000000 = 0x40000000, - TEXTUREFLAGS_UNUSED_80000000 = 0x80000000, -}; - -typedef struct vtfheader -{ - union - { - char signature[4]; // File signature ("VTF\0"). (or as little-endian integer, 0x00465456) - uint32_t usig; - }; - - unsigned int version[2]; // version[0].version[1] (currently 7.2). - unsigned int headerSize; // Size of the header struct (16 byte aligned; currently 80 bytes) + size of the resources dictionary (7.3+). - unsigned short width; // Width of the largest mipmap in pixels. Must be a power of 2. - unsigned short height; // Height of the largest mipmap in pixels. Must be a power of 2. - unsigned int flags; // VTF flags. - unsigned short frames; // Number of frames, if animated (1 for no animation). - unsigned short firstFrame; // First frame in animation (0 based). - unsigned char padding0[4]; // reflectivity padding (16 byte alignment). - float reflectivity[3]; // reflectivity vector. - unsigned char padding1[4]; // reflectivity padding (8 byte packing). - float bumpmapScale; // Bumpmap scale. - unsigned int highResImageFormat; // High resolution image format. - unsigned char mipmapCount; // Number of mipmaps. - unsigned int lowResImageFormat; // Low resolution image format (always DXT1). - unsigned char lowResImageWidth; // Low resolution image width. - unsigned char lowResImageHeight; // Low resolution image height. - - // 7.2+ - unsigned short depth; // Depth of the largest mipmap in pixels. - // Must be a power of 2. Can be 0 or 1 for a 2D texture (v7.2 only). - - // 7.3+ - unsigned char padding2[3]; // depth padding (4 byte alignment). - unsigned int numResources; // Number of resources this vtf has - - unsigned char padding3[8]; // Necessary on certain compilers -} vtfheader_t; - -#pragma pack(pop) - -typedef struct mipimg -{ - uint32_t w; - uint32_t h; - uint32_t src_offset; -} mipimg_t; - -int nbvtf_power2( uint32_t x ) -{ - return (x != 0) && ((x & (x - 1)) == 0); -} - -int nbvtf_power2x( uint32_t y, uint32_t x ) -{ - return nbvtf_power2( y ) && nbvtf_power2( x ); -} - -int nbvtf_lower( int *x, int *y ) -{ - if( *x == 1 && *y == 1 ) - { - return 0; - } - - *x = nbvtf__max( 1, (*x)/2 ); - *y = nbvtf__max( 1, (*y)/2 ); - - return 1; -} - -int nbvtf_lowres_index( int w, int h ) -{ - int x, y; - int i = 0; - - x = w; - y = h; - - while(1) - { - if( (x <= 16) && ( y <= 16 ) ) - { - return i; - } - - i ++; - - nbvtf_lower( &x, &y ); - } -} - -// Simple box filter downscale -void nbvtf_downscale( uint8_t *src, int w, int h, int dw, int dh, uint8_t *dest ) -{ - int bx = w/dw; - int by = h/dh; - int div = bx*by; - - for( int y = 0; y < dh; y ++ ) - for( int x = 0; x < dw; x ++ ) - { - // Average block colours - uint32_t tr = 0, tg = 0, tb = 0, ta = 0; - - for( int yy = 0; yy < by; yy ++ ) - for( int xx = 0; xx < bx; xx ++ ) - { - uint8_t *psrc = &src[ (x*bx+xx + (y*by+yy)*w)*4 ]; - tr+=psrc[0]; - tg+=psrc[1]; - tb+=psrc[2]; - ta+=psrc[3]; - } - - uint8_t *pdst = &dest[ (y*dw + x)*4 ]; - pdst[0] = tr / div; - pdst[1] = tg / div; - pdst[2] = tb / div; - pdst[3] = ta / div; - } -} - -uint8_t *nbvtf_create_mipmaps( uint8_t *src, int w, int h, mipimg_t *offsets, int *num ) -{ - int memory = 0; - int x, y, i; - uint32_t offset; - - x = w; - y = h; - while( nbvtf_lower( &x, &y ) ) - memory += x*y*4; - - uint8_t *mipmem = (uint8_t *)malloc( memory ); - - if( mipmem ) - { - x = w; - y = h; - i = 0; - offset = 0; - - uint8_t *dest = mipmem; - - while(1) - { - if( !nbvtf_lower( &x, &y ) ) - break; - - nbvtf_downscale( src, w, h, x, y, dest ); - - offsets[ i ].src_offset = offset; - offsets[ i ].w = x; - offsets[ i ].h = y; - i ++; - - offset += x*y*4; - dest = mipmem + offset; - } - - *num = i; - return mipmem; - } - else - { - NBVTF_ERR( "nbvtf_write:err out of memory allocating mipmap buffer!\n" ); - return NULL; - } -} - -void nbvtf_reflectivity( uint8_t *src, int w, int h, float *dest ) -{ - uint32_t totals[3] = {0,0,0}; - - for( int i = 0; i < w*h; i ++ ) - { - totals[0] += src[i*4+0]; - totals[1] += src[i*4+1]; - totals[2] += src[i*4+2]; - } - - dest[0] = (float)( totals[0] / (w*h) ) / 255.0f; - dest[1] = (float)( totals[1] / (w*h) ) / 255.0f; - dest[2] = (float)( totals[2] / (w*h) ) / 255.0f; -} - -#ifdef NBVTF_ALLOW_EXPORT -void nbvtf_debug_view_mips( uint8_t *src, int w, int h ) -{ - int x, y, i; - char fnbuf[512]; - - x = w; - y = h; - i = 1; - - uint8_t *dest = src; - - while( nbvtf_lower( &x, &y ) ) - { - sprintf( fnbuf, "mip_%d.png", i ++ ); - - stbi_write_png( fnbuf, x,y, 4, dest, x*4 ); - dest += x*y*4; - } -} -#endif - -void nbvtf_dxt_pad( uint8_t *src, int bx, int by, int w, int h, uint8_t *dest ) -{ - int px = bx*4; - int py = by*4; - - uint32_t *stream = (uint32_t *)src; - uint32_t *stream_out = (uint32_t *)dest; - - for( int y = 0; y < 4; y ++ ) - { - for( int x = 0; x < 4; x ++ ) - { - stream_out[ y*4+x ] = stream[ nbvtf__min( py+y, h-1 )*w + nbvtf__min( px+x, w-1 ) ]; - } - } -} - -uint32_t nbvtf_dxt_sizeimg( int w, int h, int alpha ) -{ - uint32_t blocks_x, blocks_y; - int block_size = alpha? 16: 8; - - blocks_x = ((uint32_t)w) >> 2; - blocks_y = ((uint32_t)h) >> 2; - - int padx = w % 4 != 0? 1: 0; - int pady = h % 4 != 0? 1: 0; - - return (blocks_x+padx)*(blocks_y+pady)*block_size; -} - -uint32_t nbvtf_sizeimg( int w, int h, EImageFormat_t format ) -{ - if( format == k_EImageFormat_DXT5 || format == k_EImageFormat_DXT1 ) - { - return nbvtf_dxt_sizeimg( w, h, format == k_EImageFormat_DXT1? 0: 1 ); - } - - if( format == k_EImageFormat_BGR888 ) - return w*h*3; - - if( format == k_EImageFormat_ABGR8888 ) - return w*h*4; - - return 0; -} - -void nbvtf_dxt_block( uint8_t *dest, uint8_t *src, int alpha ) -{ -#ifdef USE_LIBRGBCX - // TODO: move this somewehre else - static int init = 0; - if( !init ) - { - rgbcx__init(); - init = 1; - } - - if( alpha ) - { - rgbcx__encode_bc3( 12, dest, src ); - } - else - { - rgbcx__encode_bc1( 12, dest, src, 0, 0 ); - } -#else - stb_compress_dxt_block( dest, src, alpha, STB_DXT_HIGHQUAL ); -#endif -} - -void nbvtf_compress_dxt( uint8_t *src, int w, int h, int alpha, uint8_t *dest ) -{ - uint32_t blocks_x, blocks_y; - - blocks_x = ((uint32_t)w) >> 2; - blocks_y = ((uint32_t)h) >> 2; - - int padx = w % 4 != 0? 1: 0; - int pady = h % 4 != 0? 1: 0; - - int block_size = alpha? 16: 8; - - uint8_t *dest_block = dest; - - uint8_t working_block[ 4*4*4 ]; - - // Compress rows - for( int y = 0; y < blocks_y; y ++ ) - { - for( int x = 0; x < blocks_x; x ++ ) - { - uint8_t *src_begin = src + (y*w*4 + x*4)*4; - for( int i = 0; i < 4; i ++ ) - { - memcpy( working_block + i*4*4, src_begin + w*4*i, 4*4 ); - } - - nbvtf_dxt_block( dest_block, working_block, alpha ); - dest_block += block_size; - } - - if( padx ) - { - nbvtf_dxt_pad( src, blocks_x, y, w, h, working_block ); - nbvtf_dxt_block( dest_block, working_block, alpha ); - dest_block += block_size; - } - } - - // Compress remainder row - if( pady ) - { - for( int x = 0; x < blocks_x; x ++ ) - { - nbvtf_dxt_pad( src, x, blocks_y, w, h, working_block ); - nbvtf_dxt_block( dest_block, working_block, alpha ); - dest_block += block_size; - } - } - - // Compress last little corner - if( padx && pady ) - { - nbvtf_dxt_pad( src, blocks_x, blocks_y, w, h, working_block ); - nbvtf_dxt_block( dest_block, working_block, alpha ); - } -} - -void nbvtf_swizzle_to( uint8_t *src, int n, int nc, uint8_t *dest ) -{ - for( int i = 0; i < n; i ++ ) - { - for( int j = 0; j < nc; j ++ ) - { - dest[ i*nc+nc-j-1 ] = src[ i*4+j ]; - } - } -} - -void nbvtf_write_img_data( uint8_t *src, int w, int h, EImageFormat_t format, uint8_t *wb, FILE *file ) -{ - switch( format ) - { - case k_EImageFormat_DXT1: - nbvtf_compress_dxt( src, w, h, 0, wb ); - fwrite( wb, nbvtf_dxt_sizeimg( w, h, 0 ), 1, file ); - break; - case k_EImageFormat_DXT5: - nbvtf_compress_dxt( src, w, h, 1, wb ); - fwrite( wb, nbvtf_dxt_sizeimg( w, h, 1 ), 1, file ); - break; - case k_EImageFormat_ABGR8888: - nbvtf_swizzle_to( src, w*h, 4, wb ); - fwrite( wb, w*h*4, 1, file ); - break; - case k_EImageFormat_BGR888: - nbvtf_swizzle_to( src, w*h, 3, wb ); - fwrite( wb, w*h*3, 1, file ); - break; - - default: - break; - } -} - -#ifdef NBVTF_AS_SO -__attribute__((visibility("default"))) -#endif -int nbvtf_write( uint8_t *reference, int w, int h, int mipmap, EImageFormat_t format, uint32_t usr_flags, const char *dest ) -{ - if( !nbvtf_power2x(w,h) ) - { - NBVTF_ERR( "nbvtf_write:err image dimentions were not power of two (%d %d)\n", w, h ); - return 0; - } - - mipimg_t mip_offsets[ 16 ]; - int num_mips; - - uint8_t *src; - - // Convert to directx normal - if( usr_flags & TEXTUREFLAGS_NORMAL ) - { - src = malloc( w*h*4 ); - for( int i = 0; i < w*h; i ++ ) - { - src[i*4+0] = reference[i*4+0]; - src[i*4+1] = 0xFF-reference[i*4+1]; - src[i*4+2] = reference[i*4+2]; - src[i*4+3] = reference[i*4+3]; - } - } - else - src = reference; - - uint8_t *mip_data = nbvtf_create_mipmaps( src, w, h, mip_offsets, &num_mips ); - - if( !mip_data ) - { - NBVTF_ERR( "nbvtf_write:err mipmap data failed to generate" ); - - if( usr_flags & TEXTUREFLAGS_NORMAL ) - free( src ); - - return 0; - } - - vtfheader_t header = {0}; - - header.usig = 0x00465456; - header.headerSize = sizeof( vtfheader_t ); - header.version[0] = 7; - header.version[1] = 2; - - header.width = w; - header.height = h; - header.flags = usr_flags; - - // Append format flags - if( !mipmap ) - { - header.flags |= TEXTUREFLAGS_NOLOD; - header.flags |= TEXTUREFLAGS_NOMIP; - } - - if( format == k_EImageFormat_DXT5 || format == k_EImageFormat_ABGR8888 ) - { - header.flags |= TEXTUREFLAGS_EIGHTBITALPHA; - } - - header.frames = 1; - header.firstFrame = 0; - nbvtf_reflectivity( mip_data + mip_offsets[ num_mips-1 ].src_offset, 1,1, header.reflectivity ); - header.bumpmapScale = 1.0f; - - header.highResImageFormat = format; - header.mipmapCount = mipmap? - nbvtf__min(num_mips,NBVTF_MAX_MIPLEVELS)+1: 1; - - header.lowResImageFormat = k_EImageFormat_DXT1; - - header.depth = 1; - header.numResources = 0; - - int lr_index = nbvtf_lowres_index( w, h ); - - uint8_t *lr_src; - - if( lr_index ) - { - mipimg_t *mip = mip_offsets + (lr_index-1); - lr_src = mip_data + mip->src_offset; - - header.lowResImageWidth = mip->w; - header.lowResImageHeight = mip->h; - } - else - { - lr_src = src; - - header.lowResImageWidth = w; - header.lowResImageHeight = h; - } - - uint32_t size_highres = nbvtf_sizeimg( w, h, format ); - uint32_t size_lowres = nbvtf_dxt_sizeimg( header.lowResImageWidth, header.lowResImageHeight, 0 ); - - uint8_t *working_buffer = (uint8_t *)malloc( nbvtf__max( size_highres, size_lowres ) ); - - if( !working_buffer ) - { - NBVTF_ERR( "nbvtf_write:err out of memory allocating working buffer\n" ); - free( mip_data ); - - if( usr_flags & TEXTUREFLAGS_NORMAL ) - free( src ); - - return 0; - } - - FILE *file = fopen( dest, "wb" ); - - if( !file ) - { - NBVTF_ERR( "nbvtf_write:err could not open file stream for writing\n" ); - - free( working_buffer ); - free( mip_data ); - - if( usr_flags & TEXTUREFLAGS_NORMAL ) - free( src ); - - return 0; - } - - // Write header - fwrite( &header, sizeof( vtfheader_t ), 1, file ); - - // Write low res - nbvtf_write_img_data( - lr_src, header.lowResImageWidth, header.lowResImageHeight, k_EImageFormat_DXT1, working_buffer, file - ); - - // Write texture data - if( mipmap ) - { - // !! Experimental !! - int start = nbvtf__max( 0, num_mips-NBVTF_MAX_MIPLEVELS ); - - for( int i = start; i < num_mips; i ++ ) - { - mipimg_t *mip = mip_offsets + (num_mips - i -1); - nbvtf_write_img_data( mip_data + mip->src_offset, mip->w, mip->h, format, working_buffer, file ); - } - } - - // Write high resolution - nbvtf_write_img_data( src, w, h, format, working_buffer, file ); - - fclose( file ); - - free( working_buffer ); - free( mip_data ); - - if( usr_flags & TEXTUREFLAGS_NORMAL ) - free( src ); - - return 1; -} - -#ifdef NBVTF_AS_SO -__attribute__((visibility("default"))) -#endif -int nbvtf_convert( const char *src, int w, int h, int mipmap, EImageFormat_t format, uint32_t usr_flags, const char *dest ) -{ - if( (w && h) && !nbvtf_power2x(w,h) ) - { - NBVTF_ERR( "nbvtf_convert:err requested dimentions were not power of two (%d %d)\n", w, h ); - return 0; - } - - int x,y,n; - uint8_t *data = stbi_load( src, &x, &y, &n, 4 ); - - if( data ) - { - if( !nbvtf_power2x(x,y) ) - { - NBVTF_ERR( "nbvtf_convert:err loaded image dimentions were not power two (%d %d)\n", x, y ); - stbi_image_free( data ); - return 0; - } - - // Image size needs retargeting - if( (w && h) && ( x > w || y > h ) ) - nbvtf_downscale( data, x, y, w, h, data ); - - int status = nbvtf_write( data, w, h, mipmap, format, usr_flags, dest ); - stbi_image_free( data ); - - return status; - } - else - { - return 0; - } -} - -#ifdef __cplusplus -} -#endif - -/* -LICENSE - Applies to nbvtf.h, pynbvtf.py, librgbcx.cc, librgbcx.h, vtf_cmd.c ------------------------------------------------------------------------------- -Public Domain (www.unlicense.org) -This is free and unencumbered software released into the public domain. -Anyone is free to copy, modify, publish, use, compile, sell, or distribute this -software, either in source code form or as a compiled binary, for any purpose, -commercial or non-commercial, and by any means. -In jurisdictions that recognize copyright laws, the author or authors of this -software dedicate any and all copyright interest in the software to the public -domain. We make this dedication for the benefit of the public at large and to -the detriment of our heirs and successors. We intend this dedication to be an -overt act of relinquishment in perpetuity of all present and future rights to -this software under copyright law. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ------------------------------------------------------------------------------- -*/