Dawn/src/dawntools/texturetool/TextureTool.cpp

107 lines
2.8 KiB
C++

// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "TextureTool.hpp"
using namespace Dawn;
std::vector<std::string> TextureTool::getRequiredFlags() {
return std::vector<std::string>{ "input", "output" };
}
std::map<std::string, std::string> TextureTool::getOptionalFlags() {
return {
{ "wrapX", "clamp" },
{ "wrapY", "clamp" },
{ "filterMin", "linear" },
{ "filterMax", "linear" }
};
}
int32_t TextureTool::start() {
// Finished with XML data, now we can write data out.
File fileOut(flags["output"] + ".texture");
if(fileOut.exists()) return 0;
// Load input file
File in(flags["input"]);
if(!in.open(FILE_MODE_READ)) {
std::cout << "Failed to open input file " << in.filename << std::endl;
return 1;
}
int w, h, channels;
auto imageRaw = stbi_load_from_file(in.file, &w, &h, &channels, STBI_rgb_alpha);
if(imageRaw == NULL) {
std::cout << "Failed to load input texture!" << std::endl;
return 1;
}
in.close();
// Convert to floating points
size_t len = STBI_rgb_alpha * w * h;
uint8_t *dataImage = (uint8_t*)malloc(sizeof(uint8_t) * len);
for(size_t i = 0; i < len; i++) {
auto dataIn = imageRaw[i];
dataImage[i] = dataIn;
}
stbi_image_free(imageRaw);
std::function<int32_t(std::string)> wrapFromString = [&](std::string wr) {
if(wr == "repeat") return 0;
if(wr == "mirror") return 1;
if(wr == "clamp") return 2;
if(wr == "border") return 3;
return -1;
};
int32_t wrapX = wrapFromString(flags["wrapX"]);
if(wrapX == -1) {
std::cout << "Invalid wrapX value " << flags["wrapX"] << std::endl;
return 1;
}
int32_t wrapY = wrapFromString(flags["wrapY"]);
if(wrapY == -1) {
std::cout << "Invalid wrapY value " << flags["wrapY"] << std::endl;
return 1;
}
// Write info
char headerBuffer[256];
size_t headerBufferLength = sprintf((char *)headerBuffer, "DT_1.00|%i|%i|%i|%i|%i|%i|%i|",
w,
h,
4, // RGBA,
wrapX, // WRAPX
wrapY, // WRAPY
flags["filterMin"] == "nearest" ? 0 : 1,
flags["filterMag"] == "nearest" ? 0 : 1
);
// Open and create output
File out(flags["output"] + ".texture");
if(!out.mkdirp()) {
std::cout << "Failed to make output dir " << out.filename << std::endl;
return 1;
}
if(!out.open(FILE_MODE_WRITE)) {
std::cout << "Failed to open texture file for writing " << out.filename << std::endl;
return 1;
}
if(!out.writeRaw(headerBuffer, headerBufferLength)) {
std::cout << "Failed to write texture header for " << out.filename << std::endl;
return 1;
}
// Write texture
if(!out.writeRaw((char *)dataImage, sizeof(uint8_t) * len)) {
std::cout << "Failed to write texture data for " << out.filename << std::endl;
return 1;
}
free(dataImage);
return 0;
}