1 // nbvtf.h - v1.03 - Writer for Valve Texture Format - public domain
2 // Written by Harry 'hgn' Godden
5 // Rich Geldreich - bc7enc (BC1/BC3 High Quality texture compression)
6 // Fabian "ryg" Giesen, stb - stb_dxt (BC1/BC3 realtime compressors)
7 // Sean Barrett - stb_image.h, stb_image_write.h (Image I/O)
10 // This library assumes normal maps are input in OpenGL(correct) format, and will be converted into DirectX(incorrect) at
11 // compile time automatically. Do not submit DirectX normals into this software.
13 // Since this project uses stb_image, use '#define STB_IMAGE_IMPLEMENTATION' before including
14 // Additionally, to use high quality DXT, '#define USE_LIBRGBCX'
17 // Call these functions:
18 // int nbvtf_convert( const char *src, int w, int h, int mipmap, EImageFormat_t format, uint32_t usr_flags, const char *dest );
19 // int nbvtf_write( uint8_t *src, int w, int h, int mipmap, EImageFormat_t format, uint32_t usr_flags, const char *dest );
22 // src - RGBA byte data of image
24 // h - height of image
25 // mipmap - enable mipmap generation (box filter), 1/0
26 // format - Choose from: k_EImageFormat_DXT1, compressedk_EImageFormat_DXT5, k_EImageFormat_BGR888, k_EImageFormat_ABGR8888
27 // usr_flags - You can append any flags but only really need TEXTUREFLAGS_NORMAL if texture is normal map
28 // dest - file path to write vtf to
29 // qual - Image quality 0-18 (rgbcx, stb always highqual)
32 // src - file path of source image to convert
33 // w, h - MAXIMUM image dimentions of final product. Set as 0 to be automatic
36 // v1.03 - Added quality switch, moved init (major api revision)
37 // v1.02 - Improved box filtering, small bug fixes
38 // v1.01 - switch to OpenGL normal format for input
39 // v1.00 - (hgn) first release
42 // See end of file for license information.
48 #define NBVTF_MAX_MIPLEVELS 9
49 #define nbvtf__min(a,b) (((a)<(b))?(a):(b))
50 #define nbvtf__max(a,b) (((a)>(b))?(a):(b))
58 #define NBVTF_SHOW_STDERR
59 #define STB_IMAGE_IMPLEMENTATION
62 #define STBI_NO_THREAD_LOCALS
63 #include "stb/stb_image.h"
66 // #define RGBCX_NO_ALGORITHM
68 #define HAS_DXT_COMPRESSOR
72 #define STB_DXT_IMPLEMENTATION
73 #include "stb/stb_dxt.h"
74 #define HAS_DXT_COMPRESSOR
77 #ifndef HAS_DXT_COMPRESSOR
78 #warning No DXT compressor specified! S3 Output will be invalid.
81 #ifdef NBVTF_SHOW_STDERR
82 #define NBVTF_ERR(...)
84 #define NBVTF_ERR(...) fprintf( stderr, __VA_ARGS__ )
89 typedef enum EImageFormat
92 k_EImageFormat_NONE
= -1,
93 k_EImageFormat_RGBA8888
= 0, // YES
94 k_EImageFormat_ABGR8888
,
95 k_EImageFormat_RGB888
, // YES
96 k_EImageFormat_BGR888
,
97 k_EImageFormat_RGB565
,
102 k_EImageFormat_RGB888_BLUESCREEN
,
103 k_EImageFormat_BGR888_BLUESCREEN
,
104 k_EImageFormat_ARGB8888
,
105 k_EImageFormat_BGRA8888
,
106 k_EImageFormat_DXT1
, // YES
108 k_EImageFormat_DXT5
, // YES
109 k_EImageFormat_BGRX8888
,
110 k_EImageFormat_BGR565
,
111 k_EImageFormat_BGRX5551
,
112 k_EImageFormat_BGRA4444
,
113 k_EImageFormat_DXT1_ONEBITALPHA
,
114 k_EImageFormat_BGRA5551
,
116 k_EImageFormat_UVWQ8888
,
117 k_EImageFormat_RGBA16161616F
,
118 k_EImageFormat_RGBA16161616
,
119 k_EImageFormat_UVLX8888
122 const char *vtf_format_strings
[] =
124 // Name // Supported?
164 // Flags from the *.txt config file
165 TEXTUREFLAGS_POINTSAMPLE
= 0x00000001,
166 TEXTUREFLAGS_TRILINEAR
= 0x00000002,
167 TEXTUREFLAGS_CLAMPS
= 0x00000004,
168 TEXTUREFLAGS_CLAMPT
= 0x00000008,
169 TEXTUREFLAGS_ANISOTROPIC
= 0x00000010,
170 TEXTUREFLAGS_HINT_DXT5
= 0x00000020,
171 TEXTUREFLAGS_PWL_CORRECTED
= 0x00000040,
172 TEXTUREFLAGS_NORMAL
= 0x00000080,
173 TEXTUREFLAGS_NOMIP
= 0x00000100,
174 TEXTUREFLAGS_NOLOD
= 0x00000200,
175 TEXTUREFLAGS_ALL_MIPS
= 0x00000400,
176 TEXTUREFLAGS_PROCEDURAL
= 0x00000800,
178 // These are automatically generated by vtex from the texture data.
179 TEXTUREFLAGS_ONEBITALPHA
= 0x00001000,
180 TEXTUREFLAGS_EIGHTBITALPHA
= 0x00002000,
182 // Newer flags from the *.txt config file
183 TEXTUREFLAGS_ENVMAP
= 0x00004000,
184 TEXTUREFLAGS_RENDERTARGET
= 0x00008000,
185 TEXTUREFLAGS_DEPTHRENDERTARGET
= 0x00010000,
186 TEXTUREFLAGS_NODEBUGOVERRIDE
= 0x00020000,
187 TEXTUREFLAGS_SINGLECOPY
= 0x00040000,
188 TEXTUREFLAGS_PRE_SRGB
= 0x00080000,
190 TEXTUREFLAGS_UNUSED_00100000
= 0x00100000,
191 TEXTUREFLAGS_UNUSED_00200000
= 0x00200000,
192 TEXTUREFLAGS_UNUSED_00400000
= 0x00400000,
194 TEXTUREFLAGS_NODEPTHBUFFER
= 0x00800000,
196 TEXTUREFLAGS_UNUSED_01000000
= 0x01000000,
198 TEXTUREFLAGS_CLAMPU
= 0x02000000,
199 TEXTUREFLAGS_VERTEXTEXTURE
= 0x04000000,
200 TEXTUREFLAGS_SSBUMP
= 0x08000000,
202 TEXTUREFLAGS_UNUSED_10000000
= 0x10000000,
204 TEXTUREFLAGS_BORDER
= 0x20000000,
206 TEXTUREFLAGS_UNUSED_40000000
= 0x40000000,
207 TEXTUREFLAGS_UNUSED_80000000
= 0x80000000,
210 typedef struct vtfheader
214 char signature
[4]; // File signature ("VTF\0"). (or as little-endian integer, 0x00465456)
218 unsigned int version
[2]; // version[0].version[1] (currently 7.2).
219 unsigned int headerSize
; // Size of the header struct (16 byte aligned; currently 80 bytes) + size of the resources dictionary (7.3+).
220 unsigned short width
; // Width of the largest mipmap in pixels. Must be a power of 2.
221 unsigned short height
; // Height of the largest mipmap in pixels. Must be a power of 2.
222 unsigned int flags
; // VTF flags.
223 unsigned short frames
; // Number of frames, if animated (1 for no animation).
224 unsigned short firstFrame
; // First frame in animation (0 based).
225 unsigned char padding0
[4]; // reflectivity padding (16 byte alignment).
226 float reflectivity
[3]; // reflectivity vector.
227 unsigned char padding1
[4]; // reflectivity padding (8 byte packing).
228 float bumpmapScale
; // Bumpmap scale.
229 unsigned int highResImageFormat
; // High resolution image format.
230 unsigned char mipmapCount
; // Number of mipmaps.
231 unsigned int lowResImageFormat
; // Low resolution image format (always DXT1).
232 unsigned char lowResImageWidth
; // Low resolution image width.
233 unsigned char lowResImageHeight
; // Low resolution image height.
236 unsigned short depth
; // Depth of the largest mipmap in pixels.
237 // Must be a power of 2. Can be 0 or 1 for a 2D texture (v7.2 only).
240 unsigned char padding2
[3]; // depth padding (4 byte alignment).
241 unsigned int numResources
; // Number of resources this vtf has
243 unsigned char padding3
[8]; // Necessary on certain compilers
248 #pragma pack(push, 1)
249 struct DDS_PIXELFORMAT
254 uint32_t dwRGBBitCount
;
266 uint32_t dwPitchOrLinearSize
;
268 uint32_t dwMipMapCount
;
269 uint32_t dwReserved1
[11];
270 struct DDS_PIXELFORMAT ddspf
;
275 uint32_t dwReserved2
;
280 uint32_t swap_endian(uint32_t val
)
282 return (val
<< 24) | ((val
<< 8) & 0x00ff0000) |
283 ((val
>> 8) & 0x0000ff00) | (val
>> 24);
286 #define DDSD_CAPS 0x1
287 #define DDSD_HEIGHT 0x2
288 #define DDSD_WIDTH 0x4
289 #define DDSD_PITCH 0x8
290 #define DDSD_PIXELFORMAT 0x1000
291 #define DDSD_MIPMAPCOUNT 0x20000
292 #define DDSD_LINEARSIZE 0x80000
293 #define DDSD_DEPTH 0x800000
295 #define DDPF_ALPHAPIXELS 0x1
296 #define DDPF_ALPHA 0x2
297 #define DDPF_FOURCC 0x4
298 #define DDPF_RGB 0x40
299 #define DDPF_YUV 0x200
300 #define DDPF_LUMINANCE 0x20000
302 #define DDSCAPS_COMPLEX 0x8
303 #define DDSCAPS_MIPMAP 0x400000
304 #define DDSCAPS_TEXTURE 0x1000
306 #define BLOCK_SIZE_DXT1 8
307 #define BLOCK_SIZE_DXT5 16
309 #define BBP_RGB888 24
310 #define BBP_RGBA8888 32
312 #define DDS_HEADER_SIZE 124
313 #define DDS_HEADER_PFSIZE 32
314 #define DDS_MAGICNUM 0x20534444;
316 #define DDS_FLIP_VERTICALLY_ON_WRITE
318 typedef struct mipimg
325 int nbvtf_power2( uint32_t x
)
327 return (x
!= 0) && ((x
& (x
- 1)) == 0);
330 int nbvtf_power2x( uint32_t y
, uint32_t x
)
332 return nbvtf_power2( y
) && nbvtf_power2( x
);
335 int nbvtf_lower( int *x
, int *y
)
337 if( *x
== 1 && *y
== 1 )
342 *x
= nbvtf__max( 1, (*x
)/2 );
343 *y
= nbvtf__max( 1, (*y
)/2 );
348 int nbvtf_lowres_index( int w
, int h
)
358 if( (x
<= 16) && ( y
<= 16 ) )
365 nbvtf_lower( &x
, &y
);
369 // Simple box filter downscale
370 void nbvtf_downscale( uint8_t *src
, int w
, int h
, int dw
, int dh
, uint8_t *dest
)
376 for( int y
= 0; y
< dh
; y
++ )
377 for( int x
= 0; x
< dw
; x
++ )
379 // Average block colours
380 uint32_t tr
= 0, tg
= 0, tb
= 0, ta
= 0;
382 for( int yy
= 0; yy
< by
; yy
++ )
383 for( int xx
= 0; xx
< bx
; xx
++ )
385 uint8_t *psrc
= &src
[ (x
*bx
+xx
+ (y
*by
+yy
)*w
)*4 ];
392 uint8_t *pdst
= &dest
[ (y
*dw
+ x
)*4 ];
400 uint8_t *nbvtf_create_mipmaps( uint8_t *src
, int w
, int h
, mipimg_t
*offsets
, int *num
)
408 while( nbvtf_lower( &x
, &y
) )
411 uint8_t *mipmem
= (uint8_t *)malloc( memory
);
420 uint8_t *dest
= mipmem
;
424 if( !nbvtf_lower( &x
, &y
) )
427 nbvtf_downscale( src
, w
, h
, x
, y
, dest
);
429 offsets
[ i
].src_offset
= offset
;
435 dest
= mipmem
+ offset
;
443 NBVTF_ERR( "nbvtf_write:err out of memory allocating mipmap buffer!\n" );
448 void nbvtf_reflectivity( uint8_t *src
, int w
, int h
, float *dest
)
450 uint32_t totals
[3] = {0,0,0};
452 for( int i
= 0; i
< w
*h
; i
++ )
454 totals
[0] += src
[i
*4+0];
455 totals
[1] += src
[i
*4+1];
456 totals
[2] += src
[i
*4+2];
459 dest
[0] = (float)( totals
[0] / (w
*h
) ) / 255.0f
;
460 dest
[1] = (float)( totals
[1] / (w
*h
) ) / 255.0f
;
461 dest
[2] = (float)( totals
[2] / (w
*h
) ) / 255.0f
;
464 #ifdef NBVTF_ALLOW_EXPORT
465 void nbvtf_debug_view_mips( uint8_t *src
, int w
, int h
)
476 while( nbvtf_lower( &x
, &y
) )
478 sprintf( fnbuf
, "mip_%d.png", i
++ );
480 stbi_write_png( fnbuf
, x
,y
, 4, dest
, x
*4 );
486 void nbvtf_dxt_pad( uint8_t *src
, int bx
, int by
, int w
, int h
, uint8_t *dest
)
491 uint32_t *stream
= (uint32_t *)src
;
492 uint32_t *stream_out
= (uint32_t *)dest
;
494 for( int y
= 0; y
< 4; y
++ )
496 for( int x
= 0; x
< 4; x
++ )
498 stream_out
[ y
*4+x
] = stream
[ nbvtf__min( py
+y
, h
-1 )*w
+ nbvtf__min( px
+x
, w
-1 ) ];
503 uint32_t nbvtf_dxt_sizeimg( int w
, int h
, int alpha
)
505 uint32_t blocks_x
, blocks_y
;
506 int block_size
= alpha
? 16: 8;
508 blocks_x
= ((uint32_t)w
) >> 2;
509 blocks_y
= ((uint32_t)h
) >> 2;
511 int padx
= w
% 4 != 0? 1: 0;
512 int pady
= h
% 4 != 0? 1: 0;
514 return (blocks_x
+padx
)*(blocks_y
+pady
)*block_size
;
517 uint32_t nbvtf_sizeimg( int w
, int h
, EImageFormat_t format
)
519 if( format
== k_EImageFormat_DXT5
|| format
== k_EImageFormat_DXT1
)
521 return nbvtf_dxt_sizeimg( w
, h
, format
== k_EImageFormat_DXT1
? 0: 1 );
524 if( format
== k_EImageFormat_BGR888
)
527 if( format
== k_EImageFormat_ABGR8888
)
534 __attribute__((visibility("default")))
536 void nbvtf_init(void)
543 void nbvtf_dxt_block( uint8_t *dest
, uint8_t *src
, int alpha
, int qual
)
548 rgbcx__encode_bc3( qual
, dest
, src
);
552 rgbcx__encode_bc1( qual
, dest
, src
, 0, 0 );
557 stb_compress_dxt_block( dest
, src
, alpha
, STB_DXT_HIGHQUAL
);
560 #ifndef HAS_DXT_COMPRESSOR
562 for( int i
=0; i
<alpha
? 16: 8; i
++ )
563 dest
[i
] = i
%1? 0xff: 0x00;
567 void nbvtf_compress_dxt( uint8_t *src
, int w
, int h
, int alpha
, int qual
,
570 uint32_t blocks_x
, blocks_y
;
572 blocks_x
= ((uint32_t)w
) >> 2;
573 blocks_y
= ((uint32_t)h
) >> 2;
575 int padx
= w
% 4 != 0? 1: 0;
576 int pady
= h
% 4 != 0? 1: 0;
578 int block_size
= alpha
? 16: 8;
580 uint8_t *dest_block
= dest
;
582 uint8_t working_block
[ 4*4*4 ];
585 for( int y
= 0; y
< blocks_y
; y
++ )
587 for( int x
= 0; x
< blocks_x
; x
++ )
589 uint8_t *src_begin
= src
+ (y
*w
*4 + x
*4)*4;
590 for( int i
= 0; i
< 4; i
++ )
592 memcpy( working_block
+ i
*4*4, src_begin
+ w
*4*i
, 4*4 );
595 nbvtf_dxt_block( dest_block
, working_block
, alpha
, qual
);
596 dest_block
+= block_size
;
601 nbvtf_dxt_pad( src
, blocks_x
, y
, w
, h
, working_block
);
602 nbvtf_dxt_block( dest_block
, working_block
, alpha
, qual
);
603 dest_block
+= block_size
;
607 // Compress remainder row
610 for( int x
= 0; x
< blocks_x
; x
++ )
612 nbvtf_dxt_pad( src
, x
, blocks_y
, w
, h
, working_block
);
613 nbvtf_dxt_block( dest_block
, working_block
, alpha
, qual
);
614 dest_block
+= block_size
;
618 // Compress last little corner
621 nbvtf_dxt_pad( src
, blocks_x
, blocks_y
, w
, h
, working_block
);
622 nbvtf_dxt_block( dest_block
, working_block
, alpha
, qual
);
626 void nbvtf_swizzle_to( uint8_t *src
, int n
, int nc
, uint8_t *dest
)
628 for( int i
= 0; i
< n
; i
++ )
630 for( int j
= 0; j
< nc
; j
++ )
632 dest
[ i
*nc
+nc
-j
-1 ] = src
[ i
*4+j
];
637 void nbvtf_write_img_data( uint8_t *src
, int w
, int h
,
638 EImageFormat_t format
, int qual
, uint8_t *wb
, FILE *file
)
642 case k_EImageFormat_DXT1
:
643 nbvtf_compress_dxt( src
, w
, h
, 0, qual
, wb
);
644 fwrite( wb
, nbvtf_dxt_sizeimg( w
, h
, 0 ), 1, file
);
646 case k_EImageFormat_DXT5
:
647 nbvtf_compress_dxt( src
, w
, h
, 1, qual
, wb
);
648 fwrite( wb
, nbvtf_dxt_sizeimg( w
, h
, 1 ), 1, file
);
650 case k_EImageFormat_ABGR8888
:
651 nbvtf_swizzle_to( src
, w
*h
, 4, wb
);
652 fwrite( wb
, w
*h
*4, 1, file
);
654 case k_EImageFormat_BGR888
:
655 nbvtf_swizzle_to( src
, w
*h
, 3, wb
);
656 fwrite( wb
, w
*h
*3, 1, file
);
667 __attribute__((visibility("default")))
669 int nbvtf_write_dds_dxt1( uint8_t *reference
, int w
, int h
, int qual
, const char *dest
)
671 if( !nbvtf_power2x(w
,h
) )
673 NBVTF_ERR( "nbvtf_write:err image dimentions were not power of two (%d %d)\n", w
, h
);
677 struct DDS_HEADER header
= {0};
678 header
.dwSize
= DDS_HEADER_SIZE
;
679 header
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
682 header
.dwPitchOrLinearSize
= nbvtf__max(1, ((w
+ 3) / 4)) * BLOCK_SIZE_DXT1
;
683 header
.ddspf
.dwSize
= DDS_HEADER_PFSIZE
;
684 header
.ddspf
.dwFlags
|= DDPF_FOURCC
;
685 header
.ddspf
.dwFourCC
= ((uint32_t)'D'<<0) |
687 ((uint32_t)'T'<<16) |
690 header
.dwFlags
|= DDSD_LINEARSIZE
;
691 header
.dwMipMapCount
= 0;
692 header
.dwCaps
= DDSCAPS_TEXTURE
;
695 uint32_t magic
= DDS_MAGICNUM
;
697 FILE *file
= fopen( dest
, "wb" );
698 fwrite( &magic
, sizeof(uint32_t), 1, file
);
699 fwrite( &header
, DDS_HEADER_SIZE
, 1, file
);
701 uint32_t size_highres
= nbvtf_sizeimg( w
, h
, k_EImageFormat_DXT1
);
702 uint8_t *working_buffer
= malloc( size_highres
);
704 nbvtf_compress_dxt( reference
, w
, h
, 0, qual
, working_buffer
);
705 fwrite( working_buffer
, size_highres
, 1, file
);
707 free( working_buffer
);
713 __attribute__((visibility("default")))
715 int nbvtf_write( uint8_t *reference
, int w
, int h
, int mipmap
,
716 EImageFormat_t format
, int qual
, uint32_t usr_flags
, const char *dest
)
718 if( !nbvtf_power2x(w
,h
) )
720 NBVTF_ERR( "nbvtf_write:err image dimentions were not power of two (%d %d)\n", w
, h
);
724 mipimg_t mip_offsets
[ 16 ];
729 // Convert to directx normal
730 if( usr_flags
& TEXTUREFLAGS_NORMAL
)
732 src
= malloc( w
*h
*4 );
733 for( int i
= 0; i
< w
*h
; i
++ )
735 src
[i
*4+0] = reference
[i
*4+0];
736 src
[i
*4+1] = 0xFF-reference
[i
*4+1];
737 src
[i
*4+2] = reference
[i
*4+2];
738 src
[i
*4+3] = reference
[i
*4+3];
744 uint8_t *mip_data
= nbvtf_create_mipmaps( src
, w
, h
, mip_offsets
, &num_mips
);
748 NBVTF_ERR( "nbvtf_write:err mipmap data failed to generate" );
750 if( usr_flags
& TEXTUREFLAGS_NORMAL
)
756 vtfheader_t header
= {0};
758 header
.usig
= 0x00465456;
759 header
.headerSize
= sizeof( vtfheader_t
);
760 header
.version
[0] = 7;
761 header
.version
[1] = 2;
765 header
.flags
= usr_flags
;
767 // Append format flags
770 header
.flags
|= TEXTUREFLAGS_NOLOD
;
771 header
.flags
|= TEXTUREFLAGS_NOMIP
;
774 if( format
== k_EImageFormat_DXT5
|| format
== k_EImageFormat_ABGR8888
)
776 header
.flags
|= TEXTUREFLAGS_EIGHTBITALPHA
;
780 header
.firstFrame
= 0;
781 nbvtf_reflectivity( mip_data
+ mip_offsets
[ num_mips
-1 ].src_offset
, 1,1, header
.reflectivity
);
782 header
.bumpmapScale
= 1.0f
;
784 header
.highResImageFormat
= format
;
785 header
.mipmapCount
= mipmap
?
786 nbvtf__min(num_mips
,NBVTF_MAX_MIPLEVELS
)+1: 1;
788 header
.lowResImageFormat
= k_EImageFormat_DXT1
;
791 header
.numResources
= 0;
793 int lr_index
= nbvtf_lowres_index( w
, h
);
799 mipimg_t
*mip
= mip_offsets
+ (lr_index
-1);
800 lr_src
= mip_data
+ mip
->src_offset
;
802 header
.lowResImageWidth
= mip
->w
;
803 header
.lowResImageHeight
= mip
->h
;
809 header
.lowResImageWidth
= w
;
810 header
.lowResImageHeight
= h
;
813 uint32_t size_highres
= nbvtf_sizeimg( w
, h
, format
);
814 uint32_t size_lowres
=
815 nbvtf_dxt_sizeimg( header
.lowResImageWidth
, header
.lowResImageHeight
, 0 );
817 uint8_t *working_buffer
=
818 (uint8_t *)malloc( nbvtf__max( size_highres
, size_lowres
) );
820 if( !working_buffer
)
822 NBVTF_ERR( "nbvtf_write:err out of memory allocating working buffer\n" );
825 if( usr_flags
& TEXTUREFLAGS_NORMAL
)
831 FILE *file
= fopen( dest
, "wb" );
835 NBVTF_ERR( "nbvtf_write:err could not open file stream for writing\n" );
837 free( working_buffer
);
840 if( usr_flags
& TEXTUREFLAGS_NORMAL
)
847 fwrite( &header
, sizeof( vtfheader_t
), 1, file
);
850 nbvtf_write_img_data(
851 lr_src
, header
.lowResImageWidth
, header
.lowResImageHeight
,
852 k_EImageFormat_DXT1
, qual
, working_buffer
, file
855 // Write texture data
858 // !! Experimental !!
859 int start
= nbvtf__max( 0, num_mips
-NBVTF_MAX_MIPLEVELS
);
861 for( int i
= start
; i
< num_mips
; i
++ )
863 mipimg_t
*mip
= mip_offsets
+ (num_mips
- i
-1);
864 nbvtf_write_img_data( mip_data
+ mip
->src_offset
, mip
->w
, mip
->h
,
865 format
, qual
, working_buffer
, file
);
869 // Write high resolution
870 nbvtf_write_img_data( src
, w
, h
, format
, qual
, working_buffer
, file
);
874 free( working_buffer
);
877 if( usr_flags
& TEXTUREFLAGS_NORMAL
)
884 __attribute__((visibility("default")))
886 int nbvtf_convert( const char *src
, int w
, int h
, int mipmap
,
887 EImageFormat_t format
, int qual
, uint32_t usr_flags
, const char *dest
)
889 if( (w
&& h
) && !nbvtf_power2x(w
,h
) )
891 NBVTF_ERR( "nbvtf_convert:err requested dimentions were not power of two (%d %d)\n", w
, h
);
896 uint8_t *data
= stbi_load( src
, &x
, &y
, &n
, 4 );
900 if( !nbvtf_power2x(x
,y
) )
902 NBVTF_ERR( "nbvtf_convert:err loaded image dimentions were not power two (%d %d)\n", x
, y
);
903 stbi_image_free( data
);
907 // Image size needs to be made smaller
908 if( (w
&& h
) && ( x
> w
|| y
> h
) )
910 nbvtf_downscale( data
, x
, y
, w
, h
, data
);
915 int status
= nbvtf_write( data
, x
,y
, mipmap
, format
, qual
, usr_flags
, dest
);
917 stbi_image_free( data
);
932 LICENSE - Applies to nbvtf.h, pynbvtf.py, librgbcx.cc, librgbcx.h, vtf_cmd.c
933 ------------------------------------------------------------------------------
934 Public Domain (www.unlicense.org)
935 This is free and unencumbered software released into the public domain.
936 Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
937 software, either in source code form or as a compiled binary, for any purpose,
938 commercial or non-commercial, and by any means.
939 In jurisdictions that recognize copyright laws, the author or authors of this
940 software dedicate any and all copyright interest in the software to the public
941 domain. We make this dedication for the benefit of the public at large and to
942 the detriment of our heirs and successors. We intend this dedication to be an
943 overt act of relinquishment in perpetuity of all present and future rights to
944 this software under copyright law.
945 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
946 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
947 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
948 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
949 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
950 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
951 ------------------------------------------------------------------------------