Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 24 additions & 13 deletions tools/meta/meta.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ static void version()
);
}

static const bx::CommandLineOption s_options[] =
{
{ 'h', "help", 0, NULL, "Display this help and exit." },
{ 'v', "version", 0, NULL, "Output version information and exit." },
};

static void help(const char* _error = NULL)
{
if (NULL != _error)
Expand All @@ -63,8 +69,12 @@ static void help(const char* _error = NULL)
"file without decoding pixel data, similar to the UNIX `file` tool.\n"
"\n"
"Options:\n"
" -h, --help Display this help and exit.\n"
" -v, --version Output version information and exit.\n"
);

bx::Error err;
bx::write(bx::getStdOut(), s_options, BX_COUNTOF(s_options), &err);

bx::printf(
"\n"
"For more information, see https://github.com/bkaradzic/bimg\n"
);
Expand Down Expand Up @@ -162,7 +172,7 @@ static bool processFile(bx::AllocatorI* _allocator, const char* _filePath)

int main(int _argc, const char* _argv[])
{
bx::CommandLine cmdLine(_argc, _argv);
bx::CommandLine cmdLine(_argc, _argv, s_options, BX_COUNTOF(s_options) );

if (cmdLine.hasArg('v', "version") )
{
Expand All @@ -176,23 +186,24 @@ int main(int _argc, const char* _argv[])
return bx::kExitSuccess;
}

const char* unknown = cmdLine.findUnknownOption();
if (NULL != unknown)
{
char error[256];
bx::snprintf(error, BX_COUNTOF(error), "Unknown option '%s'.", unknown);
help(error);
return bx::kExitFailure;
}

bx::DefaultAllocator allocator;

bool any = false;
bool ok = true;

for (int32_t ii = 1, num = cmdLine.getNum(); ii < num; ++ii)
for (int32_t ii = 1, num = cmdLine.getNumPositional(); ii < num; ++ii)
{
const char* arg = cmdLine.get(ii);

// Skip options; only positional arguments are treated as files.
if ('-' == arg[0])
{
continue;
}

any = true;
ok &= processFile(&allocator, arg);
ok &= processFile(&allocator, cmdLine.getPositional(ii) );
}

if (!any)
Expand Down
223 changes: 187 additions & 36 deletions tools/texturec/texturec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -897,6 +897,162 @@ bimg::ImageContainer* convert(bx::AllocatorI* _allocator, const void* _inputData
return output;
}

static const char* const s_outputExt[] =
{
"dds",
"exr",
"hdr",
"ktx",
"ktx2",
"png",
NULL,
};

struct FileFormatDesc
{
const char* ext;
const char* description;
};

static const FileFormatDesc s_fileFormatDesc[] =
{
{ "avif", "AV1 Image File Format." },
{ "bmp", "Windows Bitmap." },
{ "dds", "Direct Draw Surface." },
{ "exr", "OpenEXR." },
{ "gif", "Graphics Interchange Format." },
{ "hdr", "Radiance RGBE." },
{ "heic", "High Efficiency Image Coding." },
{ "jpeg", "JPEG Interchange Format." },
{ "jpg", "JPEG Interchange Format." },
{ "ktx", "Khronos Texture." },
{ "ktx2", "Khronos Texture 2." },
{ "pgm", "Portable Gray Map." },
{ "png", "Portable Network Graphics." },
{ "ppm", "Portable Pixel Map." },
{ "psd", "Photoshop Document." },
{ "pvr", "PowerVR." },
{ "tga", "Truevision TGA." },
{ "webp", "WebP." },
};

static bool isInList(const char* const* _list, const bx::StringView& _ext)
{
for (const char* const* ext = _list; NULL != *ext; ++ext)
{
if (bx::isEqual(_ext, *ext, false) )
{
return true;
}
}

return false;
}

static const char* getFileFormatDesc(const bx::StringView& _ext)
{
for (uint32_t ii = 0; ii < BX_COUNTOF(s_fileFormatDesc); ++ii)
{
if (bx::isEqual(_ext, s_fileFormatDesc[ii].ext, false) )
{
return s_fileFormatDesc[ii].description;
}
}
return "";
}

static int32_t writeExt(char* _out, int32_t _max, const char* _ext, bool _input, bool _output)
{
return bx::snprintf(_out, _max, "*.%s (%s%s%s)"
, _ext
, _input ? "input" : ""
, _input && _output ? ", " : ""
, _output ? "output" : ""
);
}

static int32_t writeFileFormats(bx::WriterI* _writer, bx::Error* _err)
{
struct FileFormat
{
const char* ext;
bool input;
bool output;
};

FileFormat formats[64];
int32_t num = 0;

const char* const* inputExt = bimg::getSupportedExt();

for (const char* const* ext = inputExt; NULL != *ext && num < int32_t(BX_COUNTOF(formats) ); ++ext)
{
formats[num++] = { *ext, true, isInList(s_outputExt, *ext) };
}

for (const char* const* ext = s_outputExt; NULL != *ext && num < int32_t(BX_COUNTOF(formats) ); ++ext)
{
if (!isInList(inputExt, *ext) )
{
formats[num++] = { *ext, false, true };
}
}

char column[64];
int32_t width = 0;

for (int32_t ii = 0; ii < num; ++ii)
{
width = bx::max(width, writeExt(column, sizeof(column), formats[ii].ext, formats[ii].input, formats[ii].output) );
}

int32_t total = 0;

for (int32_t ii = 0; ii < num; ++ii)
{
const FileFormat& format = formats[ii];

const int32_t len = writeExt(column, sizeof(column), format.ext, format.input, format.output);

total += bx::write(_writer, _err, " %s", column);
total += bx::writeRep(_writer, ' ', width - len + 2, _err);
total += bx::write(_writer, _err, "%s\n", getFileFormatDesc(format.ext) );
}

return total;
}

static const bx::CommandLineOption s_options[] =
{
{ 'h', "help", 0, NULL, "Help." },
{ 'v', "version", 0, NULL, "Version information only." },
{ 'f', NULL, 1, "<file path>", "Input file path.\n"
"Input and output may also be passed positionally, without\n"
"-f/-o." },
{ 'o', NULL, 1, "<file path>", "Output file path." },
{ 't', NULL, 1, "<format>", "Output format type (BC1/2/3/4/5, ETC1, PVR14, etc.)." },
{ 'q', NULL, 1, "<quality>", "Encoding quality (default, fastest, highest)." },
{ 'm', "mips", 0, NULL, "Generate mip-maps." },
{ '\0', "mipskip", 1, "<N>", "Skip <N> number of mips." },
{ 'n', "normalmap", 0, NULL, "Input texture is normal map. (Implies --linear)" },
{ '\0', "equirect", 0, NULL, "Input texture is equirectangular projection of cubemap." },
{ '\0', "strip", 0, NULL, "Input texture is horizontal or vertical strip of cubemap." },
{ '\0', "sdf", 0, NULL, "Compute SDF texture." },
{ '\0', "ref", 1, "<alpha>", "Alpha reference value." },
{ '\0', "iqa", 0, NULL, "Image Quality Assessment" },
{ '\0', "pma", 0, NULL, "Premultiply alpha into RGB channel." },
{ '\0', "linear", 0, NULL, "Input and output texture is linear color space (gamma\n"
"correction won't be applied)." },
{ '\0', "max", 1, "<max size>", "Maximum width/height (image will be scaled down and\n"
"aspect ratio will be preserved)" },
{ '\0', "radiance", 1, "<model>", "Radiance cubemap filter. (Lighting model: Phong, PhongBrdf,\n"
"Blinn, BlinnBrdf, GGX)" },
{ '\0', "as", 1, "<extension>", "Save as." },
{ '\0', "formats", 0, NULL, "List all supported formats." },
{ '\0', "validate", 0, NULL, "*DEBUG* Validate that output image produced matches after\n"
"loading." },
};

void help(const char* _error = NULL, bool _showHelp = true)
{
if (NULL != _error)
Expand All @@ -918,49 +1074,25 @@ void help(const char* _error = NULL, bool _showHelp = true)
, BIMG_API_VERSION
);

bx::Error err;

bx::printf(
"Usage: texturec -f <in> -o <out> [-t <texture format>]\n"

" texturec <in> <out> [-t <texture format>]\n"
"\n"
"Supported file formats:\n"
" *.bmp (input) Windows Bitmap.\n"
" *.dds (input, output) Direct Draw Surface.\n"
" *.exr (input, output) OpenEXR.\n"
" *.gif (input) Graphics Interchange Format.\n"
" *.jpg (input) JPEG Interchange Format.\n"
" *.hdr (input, output) Radiance RGBE.\n"
" *.ktx (input, output) Khronos Texture.\n"
" *.ktx2 (input, output) Khronos Texture 2.\n"
" *.png (input, output) Portable Network Graphics.\n"
" *.psd (input) Photoshop Document.\n"
" *.pvr (input) PowerVR.\n"
" *.tga (input) Truevision TGA.\n"
);

writeFileFormats(bx::getStdOut(), &err);

bx::printf(
"\n"
"Options:\n"
" -h, --help Help.\n"
" -v, --version Version information only.\n"
" -f <file path> Input file path.\n"
" -o <file path> Output file path.\n"
" -t <format> Output format type (BC1/2/3/4/5, ETC1, PVR14, etc.).\n"
" -q <quality> Encoding quality (default, fastest, highest).\n"
" -m, --mips Generate mip-maps.\n"
" --mipskip <N> Skip <N> number of mips.\n"
" -n, --normalmap Input texture is normal map. (Implies --linear)\n"
" --equirect Input texture is equirectangular projection of cubemap.\n"
" --strip Input texture is horizontal or vertical strip of cubemap.\n"
" --sdf Compute SDF texture.\n"
" --ref <alpha> Alpha reference value.\n"
" --iqa Image Quality Assessment\n"
" --pma Premultiply alpha into RGB channel.\n"
" --linear Input and output texture is linear color space (gamma correction won't be applied).\n"
" --max <max size> Maximum width/height (image will be scaled down and\n"
" aspect ratio will be preserved)\n"
" --radiance <model> Radiance cubemap filter. (Lighting model: Phong, PhongBrdf, Blinn, BlinnBrdf, GGX)\n"
" --as <extension> Save as.\n"
" --formats List all supported formats.\n"
" --validate *DEBUG* Validate that output image produced matches after loading.\n"
);

bx::write(bx::getStdOut(), s_options, BX_COUNTOF(s_options), &err);

bx::printf(
"\n"
"For additional information, see https://github.com/bkaradzic/bimg\n"
);
Expand Down Expand Up @@ -1009,7 +1141,7 @@ class AlignedAllocator : public bx::AllocatorI

int main(int _argc, const char* _argv[])
{
bx::CommandLine cmdLine(_argc, _argv);
bx::CommandLine cmdLine(_argc, _argv, s_options, BX_COUNTOF(s_options) );

if (cmdLine.hasArg('v', "version") )
{
Expand Down Expand Up @@ -1052,14 +1184,33 @@ int main(int _argc, const char* _argv[])
return bx::kExitSuccess;
}

const char* unknown = cmdLine.findUnknownOption();
if (NULL != unknown)
{
char error[256];
bx::snprintf(error, BX_COUNTOF(error), "Unknown option '%s'.", unknown);
help(error);
return bx::kExitFailure;
}

int32_t positional = 1;

const char* inputFileName = cmdLine.findOption('f');
inputFileName = NULL != inputFileName
? inputFileName
: cmdLine.getPositional(positional++)
;
if (NULL == inputFileName)
{
help("Input file must be specified.");
return bx::kExitFailure;
}

const char* outputFileName = cmdLine.findOption('o');
outputFileName = NULL != outputFileName
? outputFileName
: cmdLine.getPositional(positional++)
;
if (NULL == outputFileName)
{
help("Output file must be specified.");
Expand Down
Loading