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 #include "stb/stb_image.h"
67 #define STB_DXT_IMPLEMENTATION
68 #include "stb/stb_dxt.h"
71 #ifdef NBVTF_SHOW_STDERR
72 #define NBVTF_ERR(...)
74 #define NBVTF_ERR(...) fprintf( stderr, __VA_ARGS__ )
79 typedef enum EImageFormat
82 k_EImageFormat_NONE
= -1,
83 k_EImageFormat_RGBA8888
= 0, // YES
84 k_EImageFormat_ABGR8888
,
85 k_EImageFormat_RGB888
, // YES
86 k_EImageFormat_BGR888
,
87 k_EImageFormat_RGB565
,
92 k_EImageFormat_RGB888_BLUESCREEN
,
93 k_EImageFormat_BGR888_BLUESCREEN
,
94 k_EImageFormat_ARGB8888
,
95 k_EImageFormat_BGRA8888
,
96 k_EImageFormat_DXT1
, // YES
98 k_EImageFormat_DXT5
, // YES
99 k_EImageFormat_BGRX8888
,
100 k_EImageFormat_BGR565
,
101 k_EImageFormat_BGRX5551
,
102 k_EImageFormat_BGRA4444
,
103 k_EImageFormat_DXT1_ONEBITALPHA
,
104 k_EImageFormat_BGRA5551
,
106 k_EImageFormat_UVWQ8888
,
107 k_EImageFormat_RGBA16161616F
,
108 k_EImageFormat_RGBA16161616
,
109 k_EImageFormat_UVLX8888
112 const char *vtf_format_strings
[] =
114 // Name // Supported?
154 // Flags from the *.txt config file
155 TEXTUREFLAGS_POINTSAMPLE
= 0x00000001,
156 TEXTUREFLAGS_TRILINEAR
= 0x00000002,
157 TEXTUREFLAGS_CLAMPS
= 0x00000004,
158 TEXTUREFLAGS_CLAMPT
= 0x00000008,
159 TEXTUREFLAGS_ANISOTROPIC
= 0x00000010,
160 TEXTUREFLAGS_HINT_DXT5
= 0x00000020,
161 TEXTUREFLAGS_PWL_CORRECTED
= 0x00000040,
162 TEXTUREFLAGS_NORMAL
= 0x00000080,
163 TEXTUREFLAGS_NOMIP
= 0x00000100,
164 TEXTUREFLAGS_NOLOD
= 0x00000200,
165 TEXTUREFLAGS_ALL_MIPS
= 0x00000400,
166 TEXTUREFLAGS_PROCEDURAL
= 0x00000800,
168 // These are automatically generated by vtex from the texture data.
169 TEXTUREFLAGS_ONEBITALPHA
= 0x00001000,
170 TEXTUREFLAGS_EIGHTBITALPHA
= 0x00002000,
172 // Newer flags from the *.txt config file
173 TEXTUREFLAGS_ENVMAP
= 0x00004000,
174 TEXTUREFLAGS_RENDERTARGET
= 0x00008000,
175 TEXTUREFLAGS_DEPTHRENDERTARGET
= 0x00010000,
176 TEXTUREFLAGS_NODEBUGOVERRIDE
= 0x00020000,
177 TEXTUREFLAGS_SINGLECOPY
= 0x00040000,
178 TEXTUREFLAGS_PRE_SRGB
= 0x00080000,
180 TEXTUREFLAGS_UNUSED_00100000
= 0x00100000,
181 TEXTUREFLAGS_UNUSED_00200000
= 0x00200000,
182 TEXTUREFLAGS_UNUSED_00400000
= 0x00400000,
184 TEXTUREFLAGS_NODEPTHBUFFER
= 0x00800000,
186 TEXTUREFLAGS_UNUSED_01000000
= 0x01000000,
188 TEXTUREFLAGS_CLAMPU
= 0x02000000,
189 TEXTUREFLAGS_VERTEXTEXTURE
= 0x04000000,
190 TEXTUREFLAGS_SSBUMP
= 0x08000000,
192 TEXTUREFLAGS_UNUSED_10000000
= 0x10000000,
194 TEXTUREFLAGS_BORDER
= 0x20000000,
196 TEXTUREFLAGS_UNUSED_40000000
= 0x40000000,
197 TEXTUREFLAGS_UNUSED_80000000
= 0x80000000,
200 typedef struct vtfheader
204 char signature
[4]; // File signature ("VTF\0"). (or as little-endian integer, 0x00465456)
208 unsigned int version
[2]; // version[0].version[1] (currently 7.2).
209 unsigned int headerSize
; // Size of the header struct (16 byte aligned; currently 80 bytes) + size of the resources dictionary (7.3+).
210 unsigned short width
; // Width of the largest mipmap in pixels. Must be a power of 2.
211 unsigned short height
; // Height of the largest mipmap in pixels. Must be a power of 2.
212 unsigned int flags
; // VTF flags.
213 unsigned short frames
; // Number of frames, if animated (1 for no animation).
214 unsigned short firstFrame
; // First frame in animation (0 based).
215 unsigned char padding0
[4]; // reflectivity padding (16 byte alignment).
216 float reflectivity
[3]; // reflectivity vector.
217 unsigned char padding1
[4]; // reflectivity padding (8 byte packing).
218 float bumpmapScale
; // Bumpmap scale.
219 unsigned int highResImageFormat
; // High resolution image format.
220 unsigned char mipmapCount
; // Number of mipmaps.
221 unsigned int lowResImageFormat
; // Low resolution image format (always DXT1).
222 unsigned char lowResImageWidth
; // Low resolution image width.
223 unsigned char lowResImageHeight
; // Low resolution image height.
226 unsigned short depth
; // Depth of the largest mipmap in pixels.
227 // Must be a power of 2. Can be 0 or 1 for a 2D texture (v7.2 only).
230 unsigned char padding2
[3]; // depth padding (4 byte alignment).
231 unsigned int numResources
; // Number of resources this vtf has
233 unsigned char padding3
[8]; // Necessary on certain compilers
238 #pragma pack(push, 1)
239 struct DDS_PIXELFORMAT
244 uint32_t dwRGBBitCount
;
256 uint32_t dwPitchOrLinearSize
;
258 uint32_t dwMipMapCount
;
259 uint32_t dwReserved1
[11];
260 struct DDS_PIXELFORMAT ddspf
;
265 uint32_t dwReserved2
;
270 uint32_t swap_endian(uint32_t val
)
272 return (val
<< 24) | ((val
<< 8) & 0x00ff0000) |
273 ((val
>> 8) & 0x0000ff00) | (val
>> 24);
276 #define DDSD_CAPS 0x1
277 #define DDSD_HEIGHT 0x2
278 #define DDSD_WIDTH 0x4
279 #define DDSD_PITCH 0x8
280 #define DDSD_PIXELFORMAT 0x1000
281 #define DDSD_MIPMAPCOUNT 0x20000
282 #define DDSD_LINEARSIZE 0x80000
283 #define DDSD_DEPTH 0x800000
285 #define DDPF_ALPHAPIXELS 0x1
286 #define DDPF_ALPHA 0x2
287 #define DDPF_FOURCC 0x4
288 #define DDPF_RGB 0x40
289 #define DDPF_YUV 0x200
290 #define DDPF_LUMINANCE 0x20000
292 #define DDSCAPS_COMPLEX 0x8
293 #define DDSCAPS_MIPMAP 0x400000
294 #define DDSCAPS_TEXTURE 0x1000
296 #define BLOCK_SIZE_DXT1 8
297 #define BLOCK_SIZE_DXT5 16
299 #define BBP_RGB888 24
300 #define BBP_RGBA8888 32
302 #define DDS_HEADER_SIZE 124
303 #define DDS_HEADER_PFSIZE 32
304 #define DDS_MAGICNUM 0x20534444;
306 #define DDS_FLIP_VERTICALLY_ON_WRITE
308 typedef struct mipimg
315 int nbvtf_power2( uint32_t x
)
317 return (x
!= 0) && ((x
& (x
- 1)) == 0);
320 int nbvtf_power2x( uint32_t y
, uint32_t x
)
322 return nbvtf_power2( y
) && nbvtf_power2( x
);
325 int nbvtf_lower( int *x
, int *y
)
327 if( *x
== 1 && *y
== 1 )
332 *x
= nbvtf__max( 1, (*x
)/2 );
333 *y
= nbvtf__max( 1, (*y
)/2 );
338 int nbvtf_lowres_index( int w
, int h
)
348 if( (x
<= 16) && ( y
<= 16 ) )
355 nbvtf_lower( &x
, &y
);
359 // Simple box filter downscale
360 void nbvtf_downscale( uint8_t *src
, int w
, int h
, int dw
, int dh
, uint8_t *dest
)
366 for( int y
= 0; y
< dh
; y
++ )
367 for( int x
= 0; x
< dw
; x
++ )
369 // Average block colours
370 uint32_t tr
= 0, tg
= 0, tb
= 0, ta
= 0;
372 for( int yy
= 0; yy
< by
; yy
++ )
373 for( int xx
= 0; xx
< bx
; xx
++ )
375 uint8_t *psrc
= &src
[ (x
*bx
+xx
+ (y
*by
+yy
)*w
)*4 ];
382 uint8_t *pdst
= &dest
[ (y
*dw
+ x
)*4 ];
390 uint8_t *nbvtf_create_mipmaps( uint8_t *src
, int w
, int h
, mipimg_t
*offsets
, int *num
)
398 while( nbvtf_lower( &x
, &y
) )
401 uint8_t *mipmem
= (uint8_t *)malloc( memory
);
410 uint8_t *dest
= mipmem
;
414 if( !nbvtf_lower( &x
, &y
) )
417 nbvtf_downscale( src
, w
, h
, x
, y
, dest
);
419 offsets
[ i
].src_offset
= offset
;
425 dest
= mipmem
+ offset
;
433 NBVTF_ERR( "nbvtf_write:err out of memory allocating mipmap buffer!\n" );
438 void nbvtf_reflectivity( uint8_t *src
, int w
, int h
, float *dest
)
440 uint32_t totals
[3] = {0,0,0};
442 for( int i
= 0; i
< w
*h
; i
++ )
444 totals
[0] += src
[i
*4+0];
445 totals
[1] += src
[i
*4+1];
446 totals
[2] += src
[i
*4+2];
449 dest
[0] = (float)( totals
[0] / (w
*h
) ) / 255.0f
;
450 dest
[1] = (float)( totals
[1] / (w
*h
) ) / 255.0f
;
451 dest
[2] = (float)( totals
[2] / (w
*h
) ) / 255.0f
;
454 #ifdef NBVTF_ALLOW_EXPORT
455 void nbvtf_debug_view_mips( uint8_t *src
, int w
, int h
)
466 while( nbvtf_lower( &x
, &y
) )
468 sprintf( fnbuf
, "mip_%d.png", i
++ );
470 stbi_write_png( fnbuf
, x
,y
, 4, dest
, x
*4 );
476 void nbvtf_dxt_pad( uint8_t *src
, int bx
, int by
, int w
, int h
, uint8_t *dest
)
481 uint32_t *stream
= (uint32_t *)src
;
482 uint32_t *stream_out
= (uint32_t *)dest
;
484 for( int y
= 0; y
< 4; y
++ )
486 for( int x
= 0; x
< 4; x
++ )
488 stream_out
[ y
*4+x
] = stream
[ nbvtf__min( py
+y
, h
-1 )*w
+ nbvtf__min( px
+x
, w
-1 ) ];
493 uint32_t nbvtf_dxt_sizeimg( int w
, int h
, int alpha
)
495 uint32_t blocks_x
, blocks_y
;
496 int block_size
= alpha
? 16: 8;
498 blocks_x
= ((uint32_t)w
) >> 2;
499 blocks_y
= ((uint32_t)h
) >> 2;
501 int padx
= w
% 4 != 0? 1: 0;
502 int pady
= h
% 4 != 0? 1: 0;
504 return (blocks_x
+padx
)*(blocks_y
+pady
)*block_size
;
507 uint32_t nbvtf_sizeimg( int w
, int h
, EImageFormat_t format
)
509 if( format
== k_EImageFormat_DXT5
|| format
== k_EImageFormat_DXT1
)
511 return nbvtf_dxt_sizeimg( w
, h
, format
== k_EImageFormat_DXT1
? 0: 1 );
514 if( format
== k_EImageFormat_BGR888
)
517 if( format
== k_EImageFormat_ABGR8888
)
524 __attribute__((visibility("default")))
526 void nbvtf_init(void)
533 void nbvtf_dxt_block( uint8_t *dest
, uint8_t *src
, int alpha
, int qual
)
538 rgbcx__encode_bc3( qual
, dest
, src
);
542 rgbcx__encode_bc1( qual
, dest
, src
, 0, 0 );
545 stb_compress_dxt_block( dest
, src
, alpha
, STB_DXT_HIGHQUAL
);
549 void nbvtf_compress_dxt( uint8_t *src
, int w
, int h
, int alpha
, int qual
,
552 uint32_t blocks_x
, blocks_y
;
554 blocks_x
= ((uint32_t)w
) >> 2;
555 blocks_y
= ((uint32_t)h
) >> 2;
557 int padx
= w
% 4 != 0? 1: 0;
558 int pady
= h
% 4 != 0? 1: 0;
560 int block_size
= alpha
? 16: 8;
562 uint8_t *dest_block
= dest
;
564 uint8_t working_block
[ 4*4*4 ];
567 for( int y
= 0; y
< blocks_y
; y
++ )
569 for( int x
= 0; x
< blocks_x
; x
++ )
571 uint8_t *src_begin
= src
+ (y
*w
*4 + x
*4)*4;
572 for( int i
= 0; i
< 4; i
++ )
574 memcpy( working_block
+ i
*4*4, src_begin
+ w
*4*i
, 4*4 );
577 nbvtf_dxt_block( dest_block
, working_block
, alpha
, qual
);
578 dest_block
+= block_size
;
583 nbvtf_dxt_pad( src
, blocks_x
, y
, w
, h
, working_block
);
584 nbvtf_dxt_block( dest_block
, working_block
, alpha
, qual
);
585 dest_block
+= block_size
;
589 // Compress remainder row
592 for( int x
= 0; x
< blocks_x
; x
++ )
594 nbvtf_dxt_pad( src
, x
, blocks_y
, w
, h
, working_block
);
595 nbvtf_dxt_block( dest_block
, working_block
, alpha
, qual
);
596 dest_block
+= block_size
;
600 // Compress last little corner
603 nbvtf_dxt_pad( src
, blocks_x
, blocks_y
, w
, h
, working_block
);
604 nbvtf_dxt_block( dest_block
, working_block
, alpha
, qual
);
608 void nbvtf_swizzle_to( uint8_t *src
, int n
, int nc
, uint8_t *dest
)
610 for( int i
= 0; i
< n
; i
++ )
612 for( int j
= 0; j
< nc
; j
++ )
614 dest
[ i
*nc
+nc
-j
-1 ] = src
[ i
*4+j
];
619 void nbvtf_write_img_data( uint8_t *src
, int w
, int h
,
620 EImageFormat_t format
, int qual
, uint8_t *wb
, FILE *file
)
624 case k_EImageFormat_DXT1
:
625 nbvtf_compress_dxt( src
, w
, h
, 0, qual
, wb
);
626 fwrite( wb
, nbvtf_dxt_sizeimg( w
, h
, 0 ), 1, file
);
628 case k_EImageFormat_DXT5
:
629 nbvtf_compress_dxt( src
, w
, h
, 1, qual
, wb
);
630 fwrite( wb
, nbvtf_dxt_sizeimg( w
, h
, 1 ), 1, file
);
632 case k_EImageFormat_ABGR8888
:
633 nbvtf_swizzle_to( src
, w
*h
, 4, wb
);
634 fwrite( wb
, w
*h
*4, 1, file
);
636 case k_EImageFormat_BGR888
:
637 nbvtf_swizzle_to( src
, w
*h
, 3, wb
);
638 fwrite( wb
, w
*h
*3, 1, file
);
649 __attribute__((visibility("default")))
651 int nbvtf_write_dds_dxt1( uint8_t *reference
, int w
, int h
, int qual
, const char *dest
)
653 if( !nbvtf_power2x(w
,h
) )
655 NBVTF_ERR( "nbvtf_write:err image dimentions were not power of two (%d %d)\n", w
, h
);
659 struct DDS_HEADER header
= {0};
660 header
.dwSize
= DDS_HEADER_SIZE
;
661 header
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
664 header
.dwPitchOrLinearSize
= nbvtf__max(1, ((w
+ 3) / 4)) * BLOCK_SIZE_DXT1
;
665 header
.ddspf
.dwSize
= DDS_HEADER_PFSIZE
;
666 header
.ddspf
.dwFlags
|= DDPF_FOURCC
;
667 header
.ddspf
.dwFourCC
= ((uint32_t)'D'<<0) |
669 ((uint32_t)'T'<<16) |
672 header
.dwFlags
|= DDSD_LINEARSIZE
;
673 header
.dwMipMapCount
= 0;
674 header
.dwCaps
= DDSCAPS_TEXTURE
;
677 uint32_t magic
= DDS_MAGICNUM
;
679 FILE *file
= fopen( dest
, "wb" );
680 fwrite( &magic
, sizeof(uint32_t), 1, file
);
681 fwrite( &header
, DDS_HEADER_SIZE
, 1, file
);
683 uint32_t size_highres
= nbvtf_sizeimg( w
, h
, k_EImageFormat_DXT1
);
684 uint8_t *working_buffer
= malloc( size_highres
);
686 nbvtf_compress_dxt( reference
, w
, h
, 0, qual
, working_buffer
);
687 fwrite( working_buffer
, size_highres
, 1, file
);
689 free( working_buffer
);
695 __attribute__((visibility("default")))
697 int nbvtf_write( uint8_t *reference
, int w
, int h
, int mipmap
,
698 EImageFormat_t format
, int qual
, uint32_t usr_flags
, const char *dest
)
700 if( !nbvtf_power2x(w
,h
) )
702 NBVTF_ERR( "nbvtf_write:err image dimentions were not power of two (%d %d)\n", w
, h
);
706 mipimg_t mip_offsets
[ 16 ];
711 // Convert to directx normal
712 if( usr_flags
& TEXTUREFLAGS_NORMAL
)
714 src
= malloc( w
*h
*4 );
715 for( int i
= 0; i
< w
*h
; i
++ )
717 src
[i
*4+0] = reference
[i
*4+0];
718 src
[i
*4+1] = 0xFF-reference
[i
*4+1];
719 src
[i
*4+2] = reference
[i
*4+2];
720 src
[i
*4+3] = reference
[i
*4+3];
726 uint8_t *mip_data
= nbvtf_create_mipmaps( src
, w
, h
, mip_offsets
, &num_mips
);
730 NBVTF_ERR( "nbvtf_write:err mipmap data failed to generate" );
732 if( usr_flags
& TEXTUREFLAGS_NORMAL
)
738 vtfheader_t header
= {0};
740 header
.usig
= 0x00465456;
741 header
.headerSize
= sizeof( vtfheader_t
);
742 header
.version
[0] = 7;
743 header
.version
[1] = 2;
747 header
.flags
= usr_flags
;
749 // Append format flags
752 header
.flags
|= TEXTUREFLAGS_NOLOD
;
753 header
.flags
|= TEXTUREFLAGS_NOMIP
;
756 if( format
== k_EImageFormat_DXT5
|| format
== k_EImageFormat_ABGR8888
)
758 header
.flags
|= TEXTUREFLAGS_EIGHTBITALPHA
;
762 header
.firstFrame
= 0;
763 nbvtf_reflectivity( mip_data
+ mip_offsets
[ num_mips
-1 ].src_offset
, 1,1, header
.reflectivity
);
764 header
.bumpmapScale
= 1.0f
;
766 header
.highResImageFormat
= format
;
767 header
.mipmapCount
= mipmap
?
768 nbvtf__min(num_mips
,NBVTF_MAX_MIPLEVELS
)+1: 1;
770 header
.lowResImageFormat
= k_EImageFormat_DXT1
;
773 header
.numResources
= 0;
775 int lr_index
= nbvtf_lowres_index( w
, h
);
781 mipimg_t
*mip
= mip_offsets
+ (lr_index
-1);
782 lr_src
= mip_data
+ mip
->src_offset
;
784 header
.lowResImageWidth
= mip
->w
;
785 header
.lowResImageHeight
= mip
->h
;
791 header
.lowResImageWidth
= w
;
792 header
.lowResImageHeight
= h
;
795 uint32_t size_highres
= nbvtf_sizeimg( w
, h
, format
);
796 uint32_t size_lowres
=
797 nbvtf_dxt_sizeimg( header
.lowResImageWidth
, header
.lowResImageHeight
, 0 );
799 uint8_t *working_buffer
=
800 (uint8_t *)malloc( nbvtf__max( size_highres
, size_lowres
) );
802 if( !working_buffer
)
804 NBVTF_ERR( "nbvtf_write:err out of memory allocating working buffer\n" );
807 if( usr_flags
& TEXTUREFLAGS_NORMAL
)
813 FILE *file
= fopen( dest
, "wb" );
817 NBVTF_ERR( "nbvtf_write:err could not open file stream for writing\n" );
819 free( working_buffer
);
822 if( usr_flags
& TEXTUREFLAGS_NORMAL
)
829 fwrite( &header
, sizeof( vtfheader_t
), 1, file
);
832 nbvtf_write_img_data(
833 lr_src
, header
.lowResImageWidth
, header
.lowResImageHeight
,
834 k_EImageFormat_DXT1
, qual
, working_buffer
, file
837 // Write texture data
840 // !! Experimental !!
841 int start
= nbvtf__max( 0, num_mips
-NBVTF_MAX_MIPLEVELS
);
843 for( int i
= start
; i
< num_mips
; i
++ )
845 mipimg_t
*mip
= mip_offsets
+ (num_mips
- i
-1);
846 nbvtf_write_img_data( mip_data
+ mip
->src_offset
, mip
->w
, mip
->h
,
847 format
, qual
, working_buffer
, file
);
851 // Write high resolution
852 nbvtf_write_img_data( src
, w
, h
, format
, qual
, working_buffer
, file
);
856 free( working_buffer
);
859 if( usr_flags
& TEXTUREFLAGS_NORMAL
)
866 __attribute__((visibility("default")))
868 int nbvtf_convert( const char *src
, int w
, int h
, int mipmap
,
869 EImageFormat_t format
, int qual
, uint32_t usr_flags
, const char *dest
)
871 if( (w
&& h
) && !nbvtf_power2x(w
,h
) )
873 NBVTF_ERR( "nbvtf_convert:err requested dimentions were not power of two (%d %d)\n", w
, h
);
878 uint8_t *data
= stbi_load( src
, &x
, &y
, &n
, 4 );
882 if( !nbvtf_power2x(x
,y
) )
884 NBVTF_ERR( "nbvtf_convert:err loaded image dimentions were not power two (%d %d)\n", x
, y
);
885 stbi_image_free( data
);
889 // Image size needs to be made smaller
890 if( (w
&& h
) && ( x
> w
|| y
> h
) )
892 nbvtf_downscale( data
, x
, y
, w
, h
, data
);
897 int status
= nbvtf_write( data
, x
,y
, mipmap
, format
, qual
, usr_flags
, dest
);
899 stbi_image_free( data
);
914 LICENSE - Applies to nbvtf.h, pynbvtf.py, librgbcx.cc, librgbcx.h, vtf_cmd.c
915 ------------------------------------------------------------------------------
916 Public Domain (www.unlicense.org)
917 This is free and unencumbered software released into the public domain.
918 Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
919 software, either in source code form or as a compiled binary, for any purpose,
920 commercial or non-commercial, and by any means.
921 In jurisdictions that recognize copyright laws, the author or authors of this
922 software dedicate any and all copyright interest in the software to the public
923 domain. We make this dedication for the benefit of the public at large and to
924 the detriment of our heirs and successors. We intend this dedication to be an
925 overt act of relinquishment in perpetuity of all present and future rights to
926 this software under copyright law.
927 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
928 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
929 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
930 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
931 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
932 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
933 ------------------------------------------------------------------------------