2013-02-21 21:07:31 -08:00
/*
2015-01-01 15:04:46 -08:00
* Copyright 2011 - 2015 Branimir Karadzic . All rights reserved .
2013-02-21 21:07:31 -08:00
* License : http : //www.opensource.org/licenses/BSD-2-Clause
*/
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
// Just hacking DDS loading code in here.
# include "bgfx_p.h"
2013-09-02 16:22:53 -07:00
# include "image.h"
2015-12-14 17:35:24 -08:00
# include <libsquish/squish.h>
2015-12-15 22:13:01 -08:00
# include <etc1/etc1.h>
2015-12-20 20:40:35 -08:00
# include <nvtt/nvtt.h>
2013-02-21 21:07:31 -08:00
#if 0
# define BX_TRACE(_format, ...) fprintf(stderr, "" _format "\n", ##__VA_ARGS__)
# endif // DEBUG
# include <bx/bx.h>
2015-11-19 20:10:51 -08:00
# include <bx/allocator.h>
2013-02-21 21:07:31 -08:00
# include <bx/commandline.h>
# include <bx/uint32_t.h>
namespace bgfx
{
const Memory * alloc ( uint32_t _size )
{
Memory * mem = ( Memory * ) : : realloc ( NULL , sizeof ( Memory ) + _size ) ;
mem - > size = _size ;
mem - > data = ( uint8_t * ) mem + sizeof ( Memory ) ;
return mem ;
}
2015-11-15 20:40:23 -08:00
void release ( const Memory * _mem )
2013-02-21 21:07:31 -08:00
{
2015-11-15 20:40:23 -08:00
Memory * mem = const_cast < Memory * > ( _mem ) ;
: : free ( mem ) ;
}
2013-02-21 21:07:31 -08:00
2015-12-22 15:40:55 -08:00
void imageEncodeFromRgba8 ( uint8_t * _dst , const uint8_t * _src , uint32_t _width , uint32_t _height , uint8_t _format )
{
TextureFormat : : Enum format = TextureFormat : : Enum ( _format ) ;
switch ( format )
{
case TextureFormat : : BC1 :
case TextureFormat : : BC2 :
case TextureFormat : : BC3 :
case TextureFormat : : BC4 :
case TextureFormat : : BC5 :
squish : : CompressImage ( _src , _width , _height , _dst
, format = = TextureFormat : : BC1 ? squish : : kDxt1
: format = = TextureFormat : : BC2 ? squish : : kDxt3
: format = = TextureFormat : : BC3 ? squish : : kDxt5
: format = = TextureFormat : : BC4 ? squish : : kBc4
: squish : : kBc5
) ;
break ;
case TextureFormat : : BC6H :
nvtt : : compressBC6H ( _src , _width , _height , 4 , _dst ) ;
break ;
case TextureFormat : : BC7 :
nvtt : : compressBC7 ( _src , _width , _height , 4 , _dst ) ;
break ;
case TextureFormat : : ETC1 :
etc1_encode_image ( _src , _width , _height , 4 , _width * 4 , _dst ) ;
break ;
case TextureFormat : : ETC2 :
case TextureFormat : : ETC2A :
case TextureFormat : : ETC2A1 :
case TextureFormat : : PTC12 :
case TextureFormat : : PTC14 :
case TextureFormat : : PTC12A :
case TextureFormat : : PTC14A :
case TextureFormat : : PTC22 :
case TextureFormat : : PTC24 :
break ;
default :
break ;
}
}
2015-11-15 20:40:23 -08:00
} // namespace bgfx
void help ( const char * _error = NULL )
{
if ( NULL ! = _error )
{
fprintf ( stderr , " Error: \n %s \n \n " , _error ) ;
2013-02-21 21:07:31 -08:00
}
2015-11-15 20:40:23 -08:00
fprintf ( stderr
, " texturec, bgfx texture compiler tool \n "
" Copyright 2011-2015 Branimir Karadzic. All rights reserved. \n "
" License: http://www.opensource.org/licenses/BSD-2-Clause \n \n "
) ;
2013-02-21 21:07:31 -08:00
}
int main ( int _argc , const char * _argv [ ] )
{
2015-12-18 18:15:30 -08:00
using namespace bgfx ;
2013-02-21 21:07:31 -08:00
bx : : CommandLine cmdLine ( _argc , _argv ) ;
2015-11-15 20:40:23 -08:00
if ( cmdLine . hasArg ( ' h ' , " help " ) )
{
help ( ) ;
return EXIT_FAILURE ;
}
2013-09-02 16:22:53 -07:00
2015-11-15 20:40:23 -08:00
const char * inputFileName = cmdLine . findOption ( ' i ' ) ;
2013-09-02 16:22:53 -07:00
if ( NULL = = inputFileName )
{
2015-11-15 20:40:23 -08:00
help ( " Input file must be specified. " ) ;
return EXIT_FAILURE ;
2013-09-02 16:22:53 -07:00
}
2015-11-19 20:10:51 -08:00
const char * outputFileName = cmdLine . findOption ( ' o ' ) ;
if ( NULL = = outputFileName )
{
help ( " Output file must be specified. " ) ;
return EXIT_FAILURE ;
}
2013-09-02 16:22:53 -07:00
bx : : CrtFileReader reader ;
2015-11-15 20:40:23 -08:00
if ( 0 ! = bx : : open ( & reader , inputFileName ) )
{
help ( " Failed to open input file. " ) ;
return EXIT_FAILURE ;
}
2015-12-18 18:15:30 -08:00
const bool mips = cmdLine . hasArg ( ' m ' , " mips " ) ;
const char * type = cmdLine . findOption ( ' t ' ) ;
TextureFormat : : Enum format = TextureFormat : : BGRA8 ;
if ( NULL ! = type )
{
if ( 0 = = bx : : stricmp ( type , " bc1 " )
| | 0 = = bx : : stricmp ( type , " dxt1 " ) )
{
format = TextureFormat : : BC1 ;
}
else if ( 0 = = bx : : stricmp ( type , " bc2 " )
| | 0 = = bx : : stricmp ( type , " dxt3 " ) )
{
format = TextureFormat : : BC2 ;
}
else if ( 0 = = bx : : stricmp ( type , " bc3 " )
| | 0 = = bx : : stricmp ( type , " dxt5 " ) )
{
format = TextureFormat : : BC3 ;
}
2015-12-22 15:40:55 -08:00
else if ( 0 = = bx : : stricmp ( type , " bc4 " ) )
{
format = TextureFormat : : BC4 ;
}
else if ( 0 = = bx : : stricmp ( type , " bc5 " ) )
{
format = TextureFormat : : BC5 ;
}
2015-12-18 18:15:30 -08:00
else if ( 0 = = bx : : stricmp ( type , " etc1 " ) )
{
format = TextureFormat : : ETC1 ;
}
2015-12-20 20:40:35 -08:00
else if ( 0 = = bx : : stricmp ( type , " bc6h " ) )
{
format = TextureFormat : : BC6H ;
}
else if ( 0 = = bx : : stricmp ( type , " bc7 " ) )
{
format = TextureFormat : : BC7 ;
}
2015-12-18 18:15:30 -08:00
}
2013-09-02 16:22:53 -07:00
uint32_t size = ( uint32_t ) bx : : getSize ( & reader ) ;
2013-02-21 21:07:31 -08:00
const Memory * mem = alloc ( size ) ;
2013-09-02 16:22:53 -07:00
bx : : read ( & reader , mem - > data , mem - > size ) ;
bx : : close ( & reader ) ;
2013-02-21 21:07:31 -08:00
2013-09-02 16:22:53 -07:00
ImageContainer imageContainer ;
2013-02-21 21:07:31 -08:00
2015-12-18 18:15:30 -08:00
bool loaded = imageParse ( imageContainer , mem - > data , mem - > size ) ;
if ( ! loaded )
2015-11-19 20:10:51 -08:00
{
2015-12-22 15:40:55 -08:00
2015-11-19 20:10:51 -08:00
}
2015-12-18 18:15:30 -08:00
BX_UNUSED ( mips ) ;
if ( loaded )
2013-02-21 21:07:31 -08:00
{
2015-12-18 18:15:30 -08:00
bx : : CrtAllocator allocator ;
uint8_t * output = NULL ;
2013-02-21 21:07:31 -08:00
2015-12-18 18:15:30 -08:00
ImageMip mip ;
if ( imageGetRawData ( imageContainer , 0 , 0 , mem - > data , mem - > size , mip ) )
2013-02-21 21:07:31 -08:00
{
2015-12-18 18:15:30 -08:00
uint8_t * rgba = ( uint8_t * ) BX_ALLOC ( & allocator , imageGetSize ( TextureFormat : : RGBA8 , mip . m_width , mip . m_height ) ) ;
2013-02-21 21:07:31 -08:00
2015-12-18 18:15:30 -08:00
imageDecodeToRgba8 ( rgba , mip . m_data , mip . m_width , mip . m_height , mip . m_width * mip . m_bpp / 8 , mip . m_format ) ;
output = ( uint8_t * ) BX_ALLOC ( & allocator , imageGetSize ( format , mip . m_width , mip . m_height ) ) ;
2015-12-22 15:40:55 -08:00
imageContainer . m_format = format ;
imageEncodeFromRgba8 ( output , rgba , mip . m_width , mip . m_height , format ) ;
2015-12-18 18:15:30 -08:00
BX_FREE ( & allocator , rgba ) ;
2013-02-21 21:07:31 -08:00
}
2015-12-18 18:15:30 -08:00
if ( NULL ! = output )
2013-02-21 21:07:31 -08:00
{
2015-12-18 18:15:30 -08:00
bx : : CrtFileWriter writer ;
if ( 0 = = bx : : open ( & writer , outputFileName ) )
2013-02-21 21:07:31 -08:00
{
2015-12-18 18:15:30 -08:00
if ( NULL ! = bx : : stristr ( outputFileName , " .ktx " ) )
2013-02-21 21:07:31 -08:00
{
2015-12-18 18:15:30 -08:00
imageWriteKtx ( & writer , imageContainer , mem - > data , mem - > size ) ;
2013-02-21 21:07:31 -08:00
}
2015-12-18 18:15:30 -08:00
bx : : close ( & writer ) ;
2013-02-21 21:07:31 -08:00
}
2015-12-18 18:15:30 -08:00
BX_FREE ( & allocator , output ) ;
2013-02-21 21:07:31 -08:00
}
}
2015-11-15 20:40:23 -08:00
release ( mem ) ;
2013-02-21 21:07:31 -08:00
return EXIT_SUCCESS ;
}