-// 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 <stdio.h>
- #include <string.h>
- #include <stdint.h>
- #include <math.h>
-
- #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.
-------------------------------------------------------------------------------
-*/