summaryrefslogtreecommitdiff
path: root/ZAPD/ZTexture.cpp
diff options
context:
space:
mode:
authorAnghelo Carvajal <angheloalf95@gmail.com>2021-05-07 17:35:00 -0400
committerGitHub <noreply@github.com>2021-05-07 17:35:00 -0400
commit547c9b200d1dff745dee694c20a9f9e8e409a11d (patch)
tree4eb2ec3fe46fb5709a43d268a2de74668839f2f1 /ZAPD/ZTexture.cpp
parent5a721d58d4b28f4797d6fdf29d9926e5e968a939 (diff)
Change image library to `libpng` and improve how palettized textures are extracted (#133)
* trying to change to libpng * It works again! * move the libpng abstraction to another file * GetBytesPerPixel * I'm dumb * fix warnings and remove dead code * Fix CRC being called multiples times and clean up code * textureDataRaw * code clean * Optimizations and removal of redundant data moves * ups * run format * use fs::path more * i'm dumb again * Add a Readme * remove texDeclarations * handle tluts better * vtx change and set segment file * small changes * Fix ZAPD ignoring textures declared in a scene in the XML * small cleanup before tluts * paletted images are broken * kinda works for automatic textures * fix automatic ci * TEXTURE_DEBUG * Remove extra `-j` * Fix extraction of ci4 * Finally palettes OK * ups * Move textures map to ZFile * Fix intersection warnings * Add `TlutOffset` attribute * Move Tlut declaration to a later step * Hopefully the last cleanup of this branch * Run format * Always calc hash * run format * Delete stb * fix merge issues * run format
Diffstat (limited to 'ZAPD/ZTexture.cpp')
-rw-r--r--ZAPD/ZTexture.cpp772
1 files changed, 346 insertions, 426 deletions
diff --git a/ZAPD/ZTexture.cpp b/ZAPD/ZTexture.cpp
index ebd7c55..cb3eaaa 100644
--- a/ZAPD/ZTexture.cpp
+++ b/ZAPD/ZTexture.cpp
@@ -1,164 +1,67 @@
-#define STB_IMAGE_IMPLEMENTATION
-#define STB_IMAGE_WRITE_IMPLEMENTATION
-#define TINYGLTF_IMPLEMENTATION
-
#include "ZTexture.h"
+
+#include <cassert>
#include "BitConverter.h"
#include "CRC32.h"
+#include "Directory.h"
#include "File.h"
#include "Globals.h"
#include "Path.h"
-#include <Directory.h>
-#include "stb_image.h"
-#include "stb_image_write.h"
-
-using namespace std;
-using namespace tinyxml2;
-
REGISTER_ZFILENODE(Texture, ZTexture);
ZTexture::ZTexture(ZFile* nParent) : ZResource(nParent)
{
- bmpRgb = nullptr;
- bmpRgba = nullptr;
width = 0;
height = 0;
- type = TextureType::Error;
- isPalette = false;
- isRawDataFixed = false;
-}
-
-ZTexture::~ZTexture()
-{
- if (bmpRgb != nullptr)
- {
- stbi_image_free(bmpRgb);
- bmpRgb = nullptr;
- }
-
- if (bmpRgba != nullptr)
- {
- stbi_image_free(bmpRgba);
- bmpRgba = nullptr;
- }
-
- width = 0;
- height = 0;
- type = TextureType::Error;
}
void ZTexture::ExtractFromXML(tinyxml2::XMLElement* reader, const std::vector<uint8_t>& nRawData,
const uint32_t nRawDataIndex)
{
- ParseXML(reader);
- rawDataIndex = nRawDataIndex;
- rawData = vector<uint8_t>(nRawData.data() + rawDataIndex,
- nRawData.data() + rawDataIndex + GetRawDataSize());
-
- FixRawData();
- PrepareBitmap();
-}
-
-ZTexture* ZTexture::FromBinary(TextureType nType, std::vector<uint8_t> nRawData,
- uint32_t nRawDataIndex, std::string nName, int32_t nWidth,
- int32_t nHeight, ZFile* nParent)
-{
- ZTexture* tex = new ZTexture(nParent);
+ ZResource::ExtractFromXML(reader, nRawData, nRawDataIndex);
- tex->width = nWidth;
- tex->height = nHeight;
- tex->type = nType;
- tex->name = nName;
- tex->outName = nName;
- tex->rawDataIndex = nRawDataIndex;
+ auto filepath = Globals::Instance->outputPath / fs::path(name).stem();
- size_t dataEnd = tex->rawDataIndex + tex->GetRawDataSize();
- tex->rawData = vector<uint8_t>(nRawData.data() + tex->rawDataIndex, nRawData.data() + dataEnd);
+ std::string incStr =
+ StringHelper::Sprintf("%s.%s.inc.c", filepath.c_str(), GetExternalExtension().c_str());
- tex->FixRawData();
- tex->CalcHash();
- tex->PrepareBitmap();
-
- return tex;
+ parent->AddDeclarationIncludeArray(rawDataIndex, incStr, GetRawDataSize(), GetSourceTypeName(),
+ name, 0);
}
-// Build Source File Mode
-ZTexture* ZTexture::BuildFromXML(XMLElement* reader, string inFolder, bool readFile)
+void ZTexture::FromBinary(const std::vector<uint8_t>& nRawData, uint32_t nRawDataIndex,
+ int32_t nWidth, int32_t nHeight, TextureType nType, bool nIsPalette)
{
- ZTexture* tex = new ZTexture(nullptr);
-
- tex->ParseXML(reader);
+ width = nWidth;
+ height = nHeight;
+ format = nType;
+ rawDataIndex = nRawDataIndex;
+ isPalette = nIsPalette;
+ name = GetDefaultName(parent->GetName());
+ outName = name;
- if (readFile)
- tex->PrepareRawData(inFolder);
+ rawData.assign(nRawData.begin(), nRawData.end());
- return tex;
+ ParseRawData();
+ CalcHash();
}
-ZTexture* ZTexture::FromPNG(string pngFilePath, TextureType texType)
+void ZTexture::FromPNG(const fs::path& pngFilePath, TextureType texType)
{
- int32_t comp;
- ZTexture* tex = new ZTexture(nullptr);
- tex->type = texType;
- tex->name = StringHelper::Split(Path::GetFileNameWithoutExtension(pngFilePath), ".")[0];
-
- tex->bmpRgb = (uint8_t*)stbi_load((pngFilePath).c_str(), (int*)&tex->width, (int*)&tex->height,
- &comp, STBI_rgb);
- stbi_image_free(tex->bmpRgb);
- tex->bmpRgb = nullptr;
- tex->rawData = vector<uint8_t>(tex->GetRawDataSize());
-
- switch (texType)
- {
- case TextureType::RGBA16bpp:
- tex->PrepareRawDataRGBA16(pngFilePath);
- break;
- case TextureType::RGBA32bpp:
- tex->PrepareRawDataRGBA32(pngFilePath);
- break;
- case TextureType::Grayscale4bpp:
- tex->PrepareRawDataGrayscale4(pngFilePath);
- break;
- case TextureType::Grayscale8bpp:
- tex->PrepareRawDataGrayscale8(pngFilePath);
- break;
- case TextureType::GrayscaleAlpha4bpp:
- tex->PrepareRawDataGrayscaleAlpha4(pngFilePath);
- break;
- case TextureType::GrayscaleAlpha8bpp:
- tex->PrepareRawDataGrayscaleAlpha8(pngFilePath);
- break;
- case TextureType::GrayscaleAlpha16bpp:
- tex->PrepareRawDataGrayscaleAlpha16(pngFilePath);
- break;
- case TextureType::Palette4bpp:
- tex->PrepareRawDataPalette4(pngFilePath);
- break;
- case TextureType::Palette8bpp:
- tex->PrepareRawDataPalette8(pngFilePath);
- break;
- default:
- throw std::runtime_error("Format is not supported!");
- }
-
- tex->FixRawData();
-
- return tex;
+ format = texType;
+ name = StringHelper::Split(Path::GetFileNameWithoutExtension(pngFilePath), ".")[0];
+ PrepareRawDataFromFile(pngFilePath);
}
-ZTexture* ZTexture::FromHLTexture(HLTexture* hlTex)
+void ZTexture::FromHLTexture(HLTexture* hlTex)
{
- ZTexture* tex = new ZTexture(nullptr);
-
- tex->width = hlTex->width;
- tex->height = hlTex->height;
- tex->type = (TextureType)hlTex->type;
-
- return tex;
+ width = hlTex->width;
+ height = hlTex->height;
+ format = static_cast<TextureType>(hlTex->type);
}
-void ZTexture::ParseXML(XMLElement* reader)
+void ZTexture::ParseXML(tinyxml2::XMLElement* reader)
{
ZResource::ParseXML(reader);
@@ -168,7 +71,8 @@ void ZTexture::ParseXML(XMLElement* reader)
}
else
{
- throw std::runtime_error("Width == nullptr for asset " + (string)reader->Attribute("Name"));
+ throw std::runtime_error("Width == nullptr for asset " +
+ std::string(reader->Attribute("Name")));
}
if (reader->Attribute("Height") != nullptr)
@@ -178,58 +82,39 @@ void ZTexture::ParseXML(XMLElement* reader)
else
{
throw std::runtime_error("Height == nullptr for asset " +
- (string)reader->Attribute("Name"));
+ std::string(reader->Attribute("Name")));
}
- string formatStr = reader->Attribute("Format");
+ std::string formatStr = reader->Attribute("Format");
- type = GetTextureTypeFromString(formatStr);
+ format = GetTextureTypeFromString(formatStr);
- if (type == TextureType::Error)
+ if (format == TextureType::Error)
throw std::runtime_error("Format " + formatStr + " is not supported!");
-}
-void ZTexture::FixRawData()
-{
- if (type == TextureType::RGBA32bpp)
+ auto tlutOffsetXml = reader->Attribute("TlutOffset");
+ if (tlutOffsetXml != nullptr)
{
- for (size_t i = 0; i < rawData.size(); i += 4)
+ switch (format)
{
- uint8_t tmp = rawData[i];
- rawData[i] = rawData[i + 2];
- rawData[i + 2] = tmp;
+ case TextureType::Palette4bpp:
+ case TextureType::Palette8bpp:
+ tlutOffset = StringHelper::StrToL(std::string(tlutOffsetXml), 16);
+ break;
+
+ default:
+ throw std::runtime_error(StringHelper::Sprintf(
+ "ZTexture::ParseXML: Error in %s\n"
+ "\t 'TlutOffset' declared in non color-indexed (ci4 or ci8) texture.\n",
+ name.c_str()));
+ break;
}
}
- else if (type == TextureType::RGBA16bpp) // || type == TextureType::GrayscaleAlpha16bpp)
- {
- for (size_t i = 0; i < rawData.size(); i += 2)
- {
- uint8_t tmp = rawData[i];
- rawData[i] = rawData[i + 1];
- rawData[i + 1] = tmp;
- }
- }
-
- isRawDataFixed = !isRawDataFixed;
}
-void ZTexture::PrepareBitmap()
+void ZTexture::ParseRawData()
{
- switch (type)
- {
- case TextureType::RGBA16bpp:
- case TextureType::RGBA32bpp:
- case TextureType::GrayscaleAlpha4bpp:
- case TextureType::GrayscaleAlpha8bpp:
- case TextureType::GrayscaleAlpha16bpp:
- bmpRgba = new uint8_t[width * height * 4];
- break;
- default:
- bmpRgb = new uint8_t[width * height * 3];
- break;
- }
-
- switch (type)
+ switch (format)
{
case TextureType::RGBA16bpp:
PrepareBitmapRGBA16();
@@ -265,60 +150,62 @@ void ZTexture::PrepareBitmap()
void ZTexture::PrepareBitmapRGBA16()
{
- for (int32_t y = 0; y < height; y++)
+ textureData.InitEmptyRGBImage(width, height, true);
+ auto parentRawData = parent->GetRawData();
+ for (size_t y = 0; y < height; y++)
{
- for (int32_t x = 0; x < width; x++)
+ for (size_t x = 0; x < width; x++)
{
- int32_t pos = ((y * width) + x) * 2;
- short data = (short)((rawData[pos + 1] << 8) + rawData[pos]);
- uint8_t r = (uint8_t)((data & 0xF800) >> 11);
- uint8_t g = (uint8_t)((data & 0x07C0) >> 6);
- uint8_t b = (uint8_t)((data & 0x003E) >> 1);
- uint8_t alpha = (uint8_t)(data & 0x01);
-
- bmpRgba[(((y * width) + x) * 4) + 0] = r * 8;
- bmpRgba[(((y * width) + x) * 4) + 1] = g * 8;
- bmpRgba[(((y * width) + x) * 4) + 2] = b * 8;
- bmpRgba[(((y * width) + x) * 4) + 3] = alpha * 255;
+ int32_t pos = rawDataIndex + ((y * width) + x) * 2;
+ uint16_t data = parentRawData.at(pos + 1) | (parentRawData.at(pos) << 8);
+ uint8_t r = (data & 0xF800) >> 11;
+ uint8_t g = (data & 0x07C0) >> 6;
+ uint8_t b = (data & 0x003E) >> 1;
+ uint8_t alpha = data & 0x01;
+
+ textureData.SetRGBPixel(y, x, r * 8, g * 8, b * 8, alpha * 255);
}
}
}
void ZTexture::PrepareBitmapRGBA32()
{
- for (uint16_t y = 0; y < height; y++)
+ textureData.InitEmptyRGBImage(width, height, true);
+ auto parentRawData = parent->GetRawData();
+ for (size_t y = 0; y < height; y++)
{
- for (uint16_t x = 0; x < width; x++)
+ for (size_t x = 0; x < width; x++)
{
- uint16_t pos = ((y * width) + x) * 4;
+ size_t pos = rawDataIndex + ((y * width) + x) * 4;
+ uint8_t r = parentRawData.at(pos + 0);
+ uint8_t g = parentRawData.at(pos + 1);
+ uint8_t b = parentRawData.at(pos + 2);
+ uint8_t alpha = parentRawData.at(pos + 3);
- bmpRgba[(((y * width) + x) * 4) + 0] = rawData[pos + 2];
- bmpRgba[(((y * width) + x) * 4) + 1] = rawData[pos + 1];
- bmpRgba[(((y * width) + x) * 4) + 2] = rawData[pos + 0];
- bmpRgba[(((y * width) + x) * 4) + 3] = rawData[pos + 3];
+ textureData.SetRGBPixel(y, x, r, g, b, alpha);
}
}
}
void ZTexture::PrepareBitmapGrayscale4()
{
- for (uint16_t y = 0; y < height; y++)
+ textureData.InitEmptyRGBImage(width, height, false);
+ auto parentRawData = parent->GetRawData();
+ for (size_t y = 0; y < height; y++)
{
- for (uint16_t x = 0; x < width; x += 2)
+ for (size_t x = 0; x < width; x += 2)
{
for (uint8_t i = 0; i < 2; i++)
{
- uint16_t pos = ((y * width) + x) / 2;
+ size_t pos = rawDataIndex + ((y * width) + x) / 2;
uint8_t grayscale = 0;
if (i == 0)
- grayscale = rawData[pos] & 0xF0;
+ grayscale = parentRawData.at(pos) & 0xF0;
else
- grayscale = (rawData[pos] & 0x0F) << 4;
+ grayscale = (parentRawData.at(pos) & 0x0F) << 4;
- bmpRgb[(((y * width) + x + i) * 3) + 0] = grayscale;
- bmpRgb[(((y * width) + x + i) * 3) + 1] = grayscale;
- bmpRgb[(((y * width) + x + i) * 3) + 2] = grayscale;
+ textureData.SetGrayscalePixel(y, x + i, grayscale);
}
}
}
@@ -326,42 +213,41 @@ void ZTexture::PrepareBitmapGrayscale4()
void ZTexture::PrepareBitmapGrayscale8()
{
- for (uint16_t y = 0; y < height; y++)
+ textureData.InitEmptyRGBImage(width, height, false);
+ auto parentRawData = parent->GetRawData();
+ for (size_t y = 0; y < height; y++)
{
- for (uint16_t x = 0; x < width; x++)
+ for (size_t x = 0; x < width; x++)
{
- uint16_t pos = ((y * width) + x) * 1;
+ size_t pos = rawDataIndex + ((y * width) + x) * 1;
- bmpRgb[(((y * width) + x) * 3) + 0] = rawData[pos];
- bmpRgb[(((y * width) + x) * 3) + 1] = rawData[pos];
- bmpRgb[(((y * width) + x) * 3) + 2] = rawData[pos];
+ textureData.SetGrayscalePixel(y, x, parentRawData.at(pos));
}
}
}
void ZTexture::PrepareBitmapGrayscaleAlpha4()
{
- for (uint16_t y = 0; y < height; y++)
+ textureData.InitEmptyRGBImage(width, height, true);
+ auto parentRawData = parent->GetRawData();
+ for (size_t y = 0; y < height; y++)
{
- for (uint16_t x = 0; x < width; x += 2)
+ for (size_t x = 0; x < width; x += 2)
{
for (uint16_t i = 0; i < 2; i++)
{
- uint16_t pos = ((y * width) + x) / 2;
+ size_t pos = rawDataIndex + ((y * width) + x) / 2;
uint8_t data = 0;
if (i == 0)
- data = (rawData[pos] & 0xF0) >> 4;
+ data = (parentRawData.at(pos) & 0xF0) >> 4;
else
- data = rawData[pos] & 0x0F;
+ data = parentRawData.at(pos) & 0x0F;
uint8_t grayscale = ((data & 0x0E) >> 1) * 32;
uint8_t alpha = (data & 0x01) * 255;
- bmpRgba[(((y * width) + x + i) * 4) + 0] = grayscale;
- bmpRgba[(((y * width) + x + i) * 4) + 1] = grayscale;
- bmpRgba[(((y * width) + x + i) * 4) + 2] = grayscale;
- bmpRgba[(((y * width) + x + i) * 4) + 3] = alpha;
+ textureData.SetGrayscalePixel(y, x + i, grayscale, alpha);
}
}
}
@@ -369,59 +255,57 @@ void ZTexture::PrepareBitmapGrayscaleAlpha4()
void ZTexture::PrepareBitmapGrayscaleAlpha8()
{
- for (uint16_t y = 0; y < height; y++)
+ textureData.InitEmptyRGBImage(width, height, true);
+ auto parentRawData = parent->GetRawData();
+ for (size_t y = 0; y < height; y++)
{
- for (uint16_t x = 0; x < width; x++)
+ for (size_t x = 0; x < width; x++)
{
- uint16_t pos = ((y * width) + x) * 1;
- uint8_t grayscale = rawData[pos] & 0xF0;
- uint8_t alpha = (rawData[pos] & 0x0F) << 4;
-
- bmpRgba[(((y * width) + x) * 4) + 0] = grayscale;
- bmpRgba[(((y * width) + x) * 4) + 1] = grayscale;
- bmpRgba[(((y * width) + x) * 4) + 2] = grayscale;
- bmpRgba[(((y * width) + x) * 4) + 3] = alpha;
+ size_t pos = rawDataIndex + ((y * width) + x) * 1;
+ uint8_t grayscale = parentRawData.at(pos) & 0xF0;
+ uint8_t alpha = (parentRawData.at(pos) & 0x0F) << 4;
+
+ textureData.SetGrayscalePixel(y, x, grayscale, alpha);
}
}
}
void ZTexture::PrepareBitmapGrayscaleAlpha16()
{
- for (uint16_t y = 0; y < height; y++)
+ textureData.InitEmptyRGBImage(width, height, true);
+ auto parentRawData = parent->GetRawData();
+ for (size_t y = 0; y < height; y++)
{
- for (uint16_t x = 0; x < width; x++)
+ for (size_t x = 0; x < width; x++)
{
- uint16_t pos = ((y * width) + x) * 2;
- uint8_t grayscale = rawData[pos + 0];
- uint8_t alpha = rawData[pos + 1];
-
- bmpRgba[(((y * width) + x) * 4) + 0] = grayscale;
- bmpRgba[(((y * width) + x) * 4) + 1] = grayscale;
- bmpRgba[(((y * width) + x) * 4) + 2] = grayscale;
- bmpRgba[(((y * width) + x) * 4) + 3] = alpha;
+ size_t pos = rawDataIndex + ((y * width) + x) * 2;
+ uint8_t grayscale = parentRawData.at(pos + 0);
+ uint8_t alpha = parentRawData.at(pos + 1);
+
+ textureData.SetGrayscalePixel(y, x, grayscale, alpha);
}
}
}
void ZTexture::PrepareBitmapPalette4()
{
- for (uint16_t y = 0; y < height; y++)
+ textureData.InitEmptyPaletteImage(width, height);
+ auto parentRawData = parent->GetRawData();
+ for (size_t y = 0; y < height; y++)
{
- for (uint16_t x = 0; x < width; x += 2)
+ for (size_t x = 0; x < width; x += 2)
{
for (uint16_t i = 0; i < 2; i++)
{
- uint16_t pos = ((y * width) + x) / 2;
+ size_t pos = rawDataIndex + ((y * width) + x) / 2;
uint8_t paletteIndex = 0;
if (i == 0)
- paletteIndex = (rawData[pos] & 0xF0) >> 4;
+ paletteIndex = (parentRawData.at(pos) & 0xF0) >> 4;
else
- paletteIndex = (rawData[pos] & 0x0F);
+ paletteIndex = (parentRawData.at(pos) & 0x0F);
- bmpRgb[(((y * width) + x + i) * 3) + 0] = paletteIndex * 16;
- bmpRgb[(((y * width) + x + i) * 3) + 1] = paletteIndex * 16;
- bmpRgb[(((y * width) + x + i) * 3) + 2] = paletteIndex * 16;
+ textureData.SetIndexedPixel(y, x + i, paletteIndex, paletteIndex * 16);
}
}
}
@@ -429,267 +313,310 @@ void ZTexture::PrepareBitmapPalette4()
void ZTexture::PrepareBitmapPalette8()
{
- for (uint16_t y = 0; y < height; y++)
+ textureData.InitEmptyPaletteImage(width, height);
+ auto parentRawData = parent->GetRawData();
+ for (size_t y = 0; y < height; y++)
{
- for (uint16_t x = 0; x < width; x++)
+ for (size_t x = 0; x < width; x++)
{
- uint16_t pos = ((y * width) + x) * 1;
+ size_t pos = rawDataIndex + ((y * width) + x) * 1;
+ uint8_t grayscale = parentRawData.at(pos);
- bmpRgb[(((y * width) + x) * 3) + 0] = rawData[pos];
- bmpRgb[(((y * width) + x) * 3) + 1] = rawData[pos];
- bmpRgb[(((y * width) + x) * 3) + 2] = rawData[pos];
+ textureData.SetIndexedPixel(y, x, grayscale, grayscale);
}
}
}
-void ZTexture::PrepareRawData(string inFolder)
+void ZTexture::DeclareReferences(const std::string& prefix)
{
- rawData = vector<uint8_t>(GetRawDataSize());
+ if (tlutOffset != static_cast<uint32_t>(-1))
+ {
+ tlut = parent->GetTextureResource(tlutOffset);
+ if (tlut == nullptr)
+ {
+ int32_t tlutDim = 16;
+ if (format == TextureType::Palette4bpp)
+ tlutDim = 4;
+
+ auto filepath = Globals::Instance->outputPath / fs::path(name).stem();
+ std::string incStr = StringHelper::Sprintf("%s.%s.inc.c", filepath.c_str(),
+ GetExternalExtension().c_str());
+
+ tlut = new ZTexture(parent);
+ tlut->FromBinary(rawData, tlutOffset, tlutDim, tlutDim, TextureType::RGBA16bpp, true);
+ parent->AddTextureResource(tlutOffset, tlut);
+ parent->AddDeclarationIncludeArray(tlutOffset, incStr, tlut->GetRawDataSize(),
+ tlut->GetSourceTypeName(), tlut->GetName(), 0);
+ }
+ else
+ {
+ tlut->isPalette = true;
+ }
+ SetTlut(tlut);
+ }
+}
- switch (type)
+void ZTexture::PrepareRawDataFromFile(const fs::path& pngFilePath)
+{
+ switch (format)
{
case TextureType::RGBA16bpp:
- PrepareRawDataRGBA16(inFolder + "/" + outName + ".rgba5a1.png");
+ PrepareRawDataRGBA16(pngFilePath);
break;
case TextureType::RGBA32bpp:
- PrepareRawDataRGBA32(inFolder + "/" + outName + ".rgba32.png");
+ PrepareRawDataRGBA32(pngFilePath);
break;
case TextureType::Grayscale4bpp:
- PrepareRawDataGrayscale4(inFolder + "/" + outName + ".i4.png");
+ PrepareRawDataGrayscale4(pngFilePath);
break;
case TextureType::Grayscale8bpp:
- PrepareRawDataGrayscale8(inFolder + "/" + outName + ".i8.png");
+ PrepareRawDataGrayscale8(pngFilePath);
break;
case TextureType::GrayscaleAlpha4bpp:
- PrepareRawDataGrayscaleAlpha4(inFolder + "/" + outName + ".ia4.png");
+ PrepareRawDataGrayscaleAlpha4(pngFilePath);
break;
case TextureType::GrayscaleAlpha8bpp:
- PrepareRawDataGrayscaleAlpha8(inFolder + "/" + outName + ".ia8.png");
+ PrepareRawDataGrayscaleAlpha8(pngFilePath);
break;
case TextureType::GrayscaleAlpha16bpp:
- PrepareRawDataGrayscaleAlpha16(inFolder + "/" + outName + ".ia16.png");
+ PrepareRawDataGrayscaleAlpha16(pngFilePath);
break;
case TextureType::Palette4bpp:
- PrepareRawDataPalette4(inFolder + "/" + outName + ".ci4.png");
+ PrepareRawDataPalette4(pngFilePath);
break;
case TextureType::Palette8bpp:
- PrepareRawDataPalette8(inFolder + "/" + outName + ".ci8.png");
+ PrepareRawDataPalette8(pngFilePath);
break;
default:
- throw std::runtime_error("Build Mode: Format is not supported!");
+ throw std::runtime_error("Format is not supported!");
}
}
-void ZTexture::PrepareRawDataRGBA16(string rgbaPath)
+void ZTexture::PrepareRawDataRGBA16(const fs::path& rgbaPath)
{
- int32_t width;
- int32_t height;
- int32_t comp;
+ textureData.ReadPng(rgbaPath);
- bmpRgba = (uint8_t*)stbi_load(rgbaPath.c_str(), &width, &height, &comp, STBI_rgb_alpha);
+ width = textureData.GetWidth();
+ height = textureData.GetHeight();
+ textureDataRaw.clear();
+ textureDataRaw.resize(GetRawDataSize());
for (uint16_t y = 0; y < height; y++)
{
for (uint16_t x = 0; x < width; x++)
{
- uint16_t pos = ((y * width) + x) * 2;
+ size_t pos = ((y * width) + x) * 2;
+ RGBAPixel pixel = textureData.GetPixel(y, x);
- uint8_t r = bmpRgba[(((y * width) + x) * 4) + 0] / 8;
- uint8_t g = bmpRgba[(((y * width) + x) * 4) + 1] / 8;
- uint8_t b = bmpRgba[(((y * width) + x) * 4) + 2] / 8;
+ uint8_t r = pixel.r / 8;
+ uint8_t g = pixel.g / 8;
+ uint8_t b = pixel.b / 8;
- uint8_t alphaBit = bmpRgba[(((y * width) + x) * 4) + 3] != 0;
+ uint8_t alphaBit = pixel.a != 0;
uint16_t data = (r << 11) + (g << 6) + (b << 1) + alphaBit;
- rawData[pos + 0] = (data & 0xFF00) >> 8;
- rawData[pos + 1] = (data & 0x00FF);
+ textureDataRaw[pos + 0] = (data & 0xFF00) >> 8;
+ textureDataRaw[pos + 1] = (data & 0x00FF);
}
}
}
-void ZTexture::PrepareRawDataRGBA32(string rgbaPath)
+void ZTexture::PrepareRawDataRGBA32(const fs::path& rgbaPath)
{
- int32_t width;
- int32_t height;
- int32_t comp;
+ textureData.ReadPng(rgbaPath);
- bmpRgba = (uint8_t*)stbi_load(rgbaPath.c_str(), &width, &height, &comp, STBI_rgb_alpha);
+ width = textureData.GetWidth();
+ height = textureData.GetHeight();
+ textureDataRaw.clear();
+ textureDataRaw.resize(GetRawDataSize());
for (uint16_t y = 0; y < height; y++)
{
for (uint16_t x = 0; x < width; x++)
{
- uint16_t pos = ((y * width) + x) * 4;
+ size_t pos = ((y * width) + x) * 4;
+ RGBAPixel pixel = textureData.GetPixel(y, x);
- rawData[pos + 0] = bmpRgba[(((y * width) + x) * 4) + 0];
- rawData[pos + 1] = bmpRgba[(((y * width) + x) * 4) + 1];
- rawData[pos + 2] = bmpRgba[(((y * width) + x) * 4) + 2];
- rawData[pos + 3] = bmpRgba[(((y * width) + x) * 4) + 3];
+ textureDataRaw[pos + 0] = pixel.r;
+ textureDataRaw[pos + 1] = pixel.g;
+ textureDataRaw[pos + 2] = pixel.b;
+ textureDataRaw[pos + 3] = pixel.a;
}
}
}
-void ZTexture::PrepareRawDataGrayscale4(string grayPath)
+void ZTexture::PrepareRawDataGrayscale4(const fs::path& grayPath)
{
- int32_t width;
- int32_t height;
- int32_t comp;
+ textureData.ReadPng(grayPath);
- bmpRgb = (uint8_t*)stbi_load(grayPath.c_str(), &width, &height, &comp, STBI_rgb);
+ width = textureData.GetWidth();
+ height = textureData.GetHeight();
+ textureDataRaw.clear();
+ textureDataRaw.resize(GetRawDataSize());
for (uint16_t y = 0; y < height; y++)
{
for (uint16_t x = 0; x < width; x += 2)
{
- uint16_t pos = ((y * width) + x) / 2;
- uint8_t r1 = bmpRgb[(((y * width) + x) * 3) + 0];
- uint8_t r2 = bmpRgb[(((y * width) + x + 1) * 3) + 0];
+ size_t pos = ((y * width) + x) / 2;
+ uint8_t r1 = textureData.GetPixel(y, x).r;
+ uint8_t r2 = textureData.GetPixel(y, x + 1).r;
- rawData[pos] = (uint8_t)(((r1 / 16) << 4) + (r2 / 16));
+ textureDataRaw[pos] = (uint8_t)(((r1 / 16) << 4) + (r2 / 16));
}
}
}
-void ZTexture::PrepareRawDataGrayscale8(string grayPath)
+void ZTexture::PrepareRawDataGrayscale8(const fs::path& grayPath)
{
- int32_t width;
- int32_t height;
- int32_t comp;
+ textureData.ReadPng(grayPath);
- bmpRgb = (uint8_t*)stbi_load(grayPath.c_str(), &width, &height, &comp, STBI_rgb);
+ width = textureData.GetWidth();
+ height = textureData.GetHeight();
+ textureDataRaw.clear();
+ textureDataRaw.resize(GetRawDataSize());
for (uint16_t y = 0; y < height; y++)
{
for (uint16_t x = 0; x < width; x++)
{
- uint16_t pos = (y * width) + x;
- rawData[pos] = bmpRgb[(((y * width) + x) * 3) + 0];
+ size_t pos = (y * width) + x;
+ RGBAPixel pixel = textureData.GetPixel(y, x);
+ textureDataRaw[pos] = pixel.r;
}
}
}
-void ZTexture::PrepareRawDataGrayscaleAlpha4(string grayAlphaPath)
+void ZTexture::PrepareRawDataGrayscaleAlpha4(const fs::path& grayAlphaPath)
{
- int32_t width;
- int32_t height;
- int32_t comp;
+ textureData.ReadPng(grayAlphaPath);
- bmpRgba = (uint8_t*)stbi_load(grayAlphaPath.c_str(), &width, &height, &comp, STBI_rgb_alpha);
+ width = textureData.GetWidth();
+ height = textureData.GetHeight();
+ textureDataRaw.clear();
+ textureDataRaw.resize(GetRawDataSize());
for (uint16_t y = 0; y < height; y++)
{
for (uint16_t x = 0; x < width; x += 2)
{
- uint16_t pos = ((y * width) + x) / 2;
+ size_t pos = ((y * width) + x) / 2;
uint8_t data = 0;
for (uint16_t i = 0; i < 2; i++)
{
- uint8_t cR = bmpRgba[(((y * width) + x + i) * 4) + 0];
- uint8_t alphaBit = bmpRgba[(((y * width) + x + i) * 4) + 3] != 0;
+ RGBAPixel pixel = textureData.GetPixel(y, x + i);
+ uint8_t cR = pixel.r;
+ uint8_t alphaBit = pixel.a != 0;
if (i == 0)
- data += (((cR / 32) << 1) + alphaBit) << 4;
+ data |= (((cR / 32) << 1) + alphaBit) << 4;
else
- data += ((cR / 32) << 1) + alphaBit;
+ data |= ((cR / 32) << 1) + alphaBit;
}
- rawData[pos] = data;
+ textureDataRaw[pos] = data;
}
}
}
-void ZTexture::PrepareRawDataGrayscaleAlpha8(string grayAlphaPath)
+void ZTexture::PrepareRawDataGrayscaleAlpha8(const fs::path& grayAlphaPath)
{
- int32_t width;
- int32_t height;
- int32_t comp;
+ textureData.ReadPng(grayAlphaPath);
- bmpRgba = (uint8_t*)stbi_load(grayAlphaPath.c_str(), &width, &height, &comp, STBI_rgb_alpha);
+ width = textureData.GetWidth();
+ height = textureData.GetHeight();
+ textureDataRaw.clear();
+ textureDataRaw.resize(GetRawDataSize());
for (uint16_t y = 0; y < height; y++)
{
for (uint16_t x = 0; x < width; x++)
{
- uint16_t pos = ((y * width) + x) * 1;
+ size_t pos = ((y * width) + x) * 1;
+ RGBAPixel pixel = textureData.GetPixel(y, x);
- uint8_t r = bmpRgba[(((y * width) + x) * 4) + 0];
- uint8_t a = bmpRgba[(((y * width) + x) * 4) + 3];
+ uint8_t r = pixel.r;
+ uint8_t a = pixel.a;
- rawData[pos] = ((r / 16) << 4) + (a / 16);
+ textureDataRaw[pos] = ((r / 16) << 4) + (a / 16);
}
}
}
-void ZTexture::PrepareRawDataGrayscaleAlpha16(string grayAlphaPath)
+void ZTexture::PrepareRawDataGrayscaleAlpha16(const fs::path& grayAlphaPath)
{
- int32_t width;
- int32_t height;
- int32_t comp;
+ textureData.ReadPng(grayAlphaPath);
- bmpRgba = (uint8_t*)stbi_load(grayAlphaPath.c_str(), &width, &height, &comp, STBI_rgb_alpha);
+ width = textureData.GetWidth();
+ height = textureData.GetHeight();
+ textureDataRaw.clear();
+ textureDataRaw.resize(GetRawDataSize());
for (uint16_t y = 0; y < height; y++)
{
for (uint16_t x = 0; x < width; x++)
{
- uint16_t pos = ((y * width) + x) * 2;
+ size_t pos = ((y * width) + x) * 2;
+ RGBAPixel pixel = textureData.GetPixel(y, x);
- uint8_t cR = bmpRgba[(((y * width) + x) * 4) + 0];
- uint8_t aR = bmpRgba[(((y * width) + x) * 4) + 3];
+ uint8_t cR = pixel.r;
+ uint8_t aR = pixel.a;
- rawData[pos + 0] = cR;
- rawData[pos + 1] = aR;
+ textureDataRaw[pos + 0] = cR;
+ textureDataRaw[pos + 1] = aR;
}
}
}
-void ZTexture::PrepareRawDataPalette4(string palPath)
+void ZTexture::PrepareRawDataPalette4(const fs::path& palPath)
{
- int32_t width;
- int32_t height;
- int32_t comp;
+ textureData.ReadPng(palPath);
- bmpRgb = (uint8_t*)stbi_load(palPath.c_str(), &width, &height, &comp, STBI_rgb);
+ width = textureData.GetWidth();
+ height = textureData.GetHeight();
+ textureDataRaw.clear();
+ textureDataRaw.resize(GetRawDataSize());
for (uint16_t y = 0; y < height; y++)
{
for (uint16_t x = 0; x < width; x += 2)
{
- uint16_t pos = ((y * width) + x) / 2;
+ size_t pos = ((y * width) + x) / 2;
- uint8_t cR1 = bmpRgb[(((y * width) + x) * 3) + 0];
- uint8_t cR2 = bmpRgb[(((y * width) + x + 1) * 3) + 0];
+ uint8_t cR1 = textureData.GetIndexedPixel(y, x);
+ uint8_t cR2 = textureData.GetIndexedPixel(y, x + 1);
- rawData[pos] = ((cR1 / 16) << 4) + (cR2 / 16);
+ textureDataRaw[pos] = (cR1 << 4) | (cR2);
}
}
}
-void ZTexture::PrepareRawDataPalette8(string palPath)
+void ZTexture::PrepareRawDataPalette8(const fs::path& palPath)
{
- int32_t width;
- int32_t height;
- int32_t comp;
+ textureData.ReadPng(palPath);
- bmpRgb = (uint8_t*)stbi_load(palPath.c_str(), &width, &height, &comp, STBI_rgb);
+ width = textureData.GetWidth();
+ height = textureData.GetHeight();
+ textureDataRaw.clear();
+ textureDataRaw.resize(GetRawDataSize());
for (uint16_t y = 0; y < height; y++)
{
for (uint16_t x = 0; x < width; x++)
{
- uint16_t pos = ((y * width) + x);
+ size_t pos = ((y * width) + x);
+ uint8_t cR = textureData.GetIndexedPixel(y, x);
- uint8_t cR = bmpRgb[(((y * width) + x) * 3) + 0];
- rawData[pos] = cR;
+ textureDataRaw[pos] = cR;
}
}
}
-float ZTexture::GetPixelMultiplyer()
+float ZTexture::GetPixelMultiplyer() const
{
- switch (type)
+ switch (format)
{
case TextureType::Grayscale4bpp:
case TextureType::GrayscaleAlpha4bpp:
@@ -716,7 +643,7 @@ size_t ZTexture::GetRawDataSize()
std::string ZTexture::GetIMFmtFromType()
{
- switch (type)
+ switch (format)
{
case TextureType::RGBA32bpp:
case TextureType::RGBA16bpp:
@@ -738,7 +665,7 @@ std::string ZTexture::GetIMFmtFromType()
std::string ZTexture::GetIMSizFromType()
{
- switch (type)
+ switch (format)
{
case TextureType::Grayscale4bpp:
case TextureType::Palette4bpp:
@@ -757,99 +684,78 @@ std::string ZTexture::GetIMSizFromType()
}
}
-uint16_t ZTexture::GetWidth()
+std::string ZTexture::GetDefaultName(const std::string& prefix)
{
- return width;
+ const char* suffix = "Tex";
+ if (isPalette)
+ suffix = "TLUT";
+ return StringHelper::Sprintf("%s%s_%06X", prefix.c_str(), suffix, rawDataIndex);
}
-uint16_t ZTexture::GetHeight()
+uint32_t ZTexture::GetWidth() const
{
- return height;
+ return width;
}
-void ZTexture::SetWidth(uint16_t nWidth)
+uint32_t ZTexture::GetHeight() const
{
- width = nWidth;
+ return height;
}
-void ZTexture::SetHeight(uint16_t nHeight)
+void ZTexture::SetDimensions(uint32_t nWidth, uint32_t nHeight)
{
+ width = nWidth;
height = nHeight;
+ ParseRawData();
}
TextureType ZTexture::GetTextureType()
{
- return type;
+ return format;
}
-void ZTexture::Save(const std::string& outFolder)
+void ZTexture::Save(const fs::path& outFolder)
{
// Optionally generate text file containing CRC information. This is going to be a one time
// process for generating the Texture Pool XML.
- if (Globals::Instance->testMode)
+ if (Globals::Instance->outputCrc)
{
- if (hash != 0)
- {
- File::WriteAllText(StringHelper::Sprintf("%s/%s.txt",
- Globals::Instance->outputPath.c_str(),
- outName.c_str()),
- StringHelper::Sprintf("%08lX", hash));
- hash = 0;
- }
+ File::WriteAllText(Globals::Instance->outputPath / (outName + ".txt"),
+ StringHelper::Sprintf("%08lX", hash));
}
- std::string outPath = GetPoolOutPath(outFolder);
+ auto outPath = GetPoolOutPath(outFolder);
if (!Directory::Exists(outPath))
Directory::CreateDirectory(outPath);
- if (type == TextureType::RGBA32bpp)
- stbi_write_png((outPath + "/" + outName + ".rgba32.png").c_str(), width, height, 4, bmpRgba,
- width * 4);
- else if (type == TextureType::RGBA16bpp)
- stbi_write_png((outPath + "/" + outName + ".rgb5a1.png").c_str(), width, height, 4, bmpRgba,
- width * 4);
- else if (type == TextureType::Grayscale8bpp)
- stbi_write_png((outPath + "/" + outName + ".i8.png").c_str(), width, height, 3, bmpRgb,
- width * 3);
- else if (type == TextureType::Grayscale4bpp)
- stbi_write_png((outPath + "/" + outName + ".i4.png").c_str(), width, height, 3, bmpRgb,
- width * 3);
- else if (type == TextureType::GrayscaleAlpha16bpp)
- stbi_write_png((outPath + "/" + outName + ".ia16.png").c_str(), width, height, 4, bmpRgba,
- width * 4);
- else if (type == TextureType::GrayscaleAlpha8bpp)
- stbi_write_png((outPath + "/" + outName + ".ia8.png").c_str(), width, height, 4, bmpRgba,
- width * 4);
- else if (type == TextureType::GrayscaleAlpha4bpp)
- stbi_write_png((outPath + "/" + outName + ".ia4.png").c_str(), width, height, 4, bmpRgba,
- width * 4);
- else if (type == TextureType::Palette4bpp)
- stbi_write_png((outPath + "/" + outName + ".ci4.png").c_str(), width, height, 3, bmpRgb,
- width * 3);
- else if (type == TextureType::Palette8bpp)
- stbi_write_png((outPath + "/" + outName + ".ci8.png").c_str(), width, height, 3, bmpRgb,
- width * 3);
-
- // if (outName != name && outName != "")
- // File::WriteAllText(outFolder + "/" + outName + ".cfg", name.c_str());
-}
-
-string ZTexture::GetSourceOutputCode(const std::string& prefix)
-{
- sourceOutput = "";
-
- FixRawData();
-
- uint8_t* rawDataArr = rawData.data();
-
- for (size_t i = 0; i < rawData.size(); i += 8)
+ auto outFileName = outPath / (outName + "." + GetExternalExtension() + ".png");
+
+#ifdef TEXTURE_DEBUG
+ printf("Saving PNG: %s\n", outFileName.c_str());
+ printf("\t Var name: %s\n", name.c_str());
+ if (tlut != nullptr)
+ printf("\t TLUT name: %s\n", tlut->name.c_str());
+#endif
+
+ textureData.WritePng(outFileName);
+
+#ifdef TEXTURE_DEBUG
+ printf("\n");
+#endif
+}
+
+std::string ZTexture::GetBodySourceCode() const
+{
+ std::string sourceOutput = "";
+
+ for (size_t i = 0; i < textureDataRaw.size(); i += 8)
{
if (i % 32 == 0)
sourceOutput += " ";
sourceOutput +=
- StringHelper::Sprintf("0x%016llX, ", BitConverter::ToUInt64BE(rawDataArr, i));
+ StringHelper::Sprintf("0x%016llX, ", BitConverter::ToUInt64BE(textureDataRaw, i));
if (i % 32 == 24)
sourceOutput += StringHelper::Sprintf(" // 0x%06X \n", rawDataIndex + ((i / 32) * 32));
@@ -880,21 +786,13 @@ std::string ZTexture::GetSourceTypeName()
void ZTexture::CalcHash()
{
- // Make sure raw data is fixed before we calc the hash...
- bool fixFlag = !isRawDataFixed;
-
- if (fixFlag)
- FixRawData();
-
- hash = CRC32B(rawData.data(), GetRawDataSize());
-
- if (fixFlag)
- FixRawData();
+ auto parentRawData = parent->GetRawData();
+ hash = CRC32B(parentRawData.data() + rawDataIndex, GetRawDataSize());
}
std::string ZTexture::GetExternalExtension()
{
- switch (type)
+ switch (format)
{
case TextureType::RGBA32bpp:
return "rgba32";
@@ -919,7 +817,7 @@ std::string ZTexture::GetExternalExtension()
}
}
-std::string ZTexture::GetPoolOutPath(std::string defaultValue)
+fs::path ZTexture::GetPoolOutPath(const fs::path& defaultValue)
{
if (Globals::Instance->cfg.texturePool.find(hash) != Globals::Instance->cfg.texturePool.end())
return Path::GetDirectoryName(Globals::Instance->cfg.texturePool[hash].path.string());
@@ -927,12 +825,7 @@ std::string ZTexture::GetPoolOutPath(std::string defaultValue)
return defaultValue;
}
-string ZTexture::GetSourceOutputHeader(const std::string& prefix)
-{
- return "";
-}
-
-TextureType ZTexture::GetTextureTypeFromString(string str)
+TextureType ZTexture::GetTextureTypeFromString(std::string str)
{
TextureType texType = TextureType::Error;
@@ -955,6 +848,33 @@ TextureType ZTexture::GetTextureTypeFromString(string str)
else if (str == "ci8")
texType = TextureType::Palette8bpp;
else
- fprintf(stderr, "Encountered Unknown Texture Type %s \n", str.c_str());
+ fprintf(stderr, "Encountered Unknown Texture format %s \n", str.c_str());
return texType;
}
+
+bool ZTexture::IsColorIndexed() const
+{
+ switch (format)
+ {
+ case TextureType::Palette4bpp:
+ case TextureType::Palette8bpp:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+void ZTexture::SetTlut(ZTexture* nTlut)
+{
+ assert(IsColorIndexed());
+ assert(nTlut->isPalette);
+ tlut = nTlut;
+
+ textureData.SetPalette(tlut->textureData);
+}
+
+bool ZTexture::HasTlut() const
+{
+ return tlut != nullptr;
+}