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
12 changes: 6 additions & 6 deletions inc/starlet-serializer/parser/mesh/meshParserBase.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@

namespace Starlet::Serializer {

struct MeshData;
struct MeshData;

class MeshParserBase : public Parser {
public:
virtual ~MeshParserBase() = default;
class MeshParserBase : public Parser {
public:
virtual ~MeshParserBase() = default;

virtual bool parse(const std::string& path, MeshData& out) = 0;
};
virtual bool parse(const std::string& path, MeshData& out) = 0;
};

}
22 changes: 11 additions & 11 deletions inc/starlet-serializer/parser/meshParser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,19 @@

namespace Starlet::Serializer {

struct MeshData;
struct MeshData;

class MeshParser : public Parser {
public:
bool parse(const std::string& path, MeshData& out);
class MeshParser : public Parser {
public:
bool parse(const std::string& path, MeshData& out);

private:
enum class MeshFormat {
PLY,
UNKNOWN
};

MeshFormat detectFormat(const std::string& path);
private:
enum class MeshFormat {
PLY,
UNKNOWN
};

MeshFormat detectFormat(const std::string& path);
};

}
30 changes: 14 additions & 16 deletions inc/starlet-serializer/parser/parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,35 +8,33 @@
namespace Starlet {

namespace Math {

template <typename T> struct Vec2;
template <typename T> struct Vec3;
template <typename T> struct Vec4;

template <typename T> struct Vec2;
template <typename T> struct Vec3;
template <typename T> struct Vec4;
}

namespace Serializer {

#ifndef STARLET_PARSE_OR
#define STARLET_PARSE_OR(onFail, parser, target, errorMsg) \
do { \
if (!(parser(p, target))) { \
if((errorMsg) && *(errorMsg) != '\0') fprintf(stderr, "[Parser ERROR]: Failed to parse %s\n", errorMsg); \
onFail; \
if (!(parser(p, target))) { \
if((errorMsg) && *(errorMsg) != '\0') fprintf(stderr, "[Parser ERROR]: Failed to parse %s\n", errorMsg); \
onFail; \
} \
} while(0)
#endif

#ifndef STARLET_PARSE_STRING_OR
#define STARLET_PARSE_STRING_OR(onFail, p, target, size, label) \
do {\
char temp[size]{}; \
if (!parseToken(p, reinterpret_cast<unsigned char*>(temp), size) || strlen(temp) == 0) { \
fprintf(stderr, "[Parser ERROR] Failed to parse %s\n", label); \
onFail; \
} \
target = temp; \
} while (0)
do {\
char temp[size]{}; \
if (!parseToken(p, reinterpret_cast<unsigned char*>(temp), size) || strlen(temp) == 0) { \
fprintf(stderr, "[Parser ERROR] Failed to parse %s\n", label); \
onFail; \
} \
target = temp; \
} while (0)
#endif

class Parser {
Expand Down
12 changes: 6 additions & 6 deletions src/parser/image/bmpParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ bool BmpParser::parse(const std::string& path, ImageData& out) {
const bool bottomUp = (height > 0);
const uint32_t absHeight = static_cast<uint32_t>(bottomUp ? height : -height);

if (!allocatePixelBuffer(out, width, absHeight))
if (!allocatePixelBuffer(out, width, absHeight))
return false;

if (!copyPixelData(p, file->size(), dataOffset, out, width, absHeight, bottomUp))
Expand All @@ -44,24 +44,24 @@ bool BmpParser::parseHeader(const unsigned char* p, size_t fileSize, uint32_t& w
if (!validateFileSignature(p, fileSize)) return false;

dataOffset = readUint32(p, 10);
if (dataOffset >= fileSize) return Logger::error("BmpParser", "parseBmpHeader", "Invalid data offset: " + std::to_string(dataOffset));
if (dataOffset >= fileSize) return Logger::error("BmpParser", "parseHeader", "Invalid data offset: " + std::to_string(dataOffset));

uint32_t dibSize = readUint32(p, 14);
if (dibSize < BMP_DIB_HEADER_SIZE_MIN) return Logger::error("BmpParser", "parseBmpHeader", "Unsupported DIB header size: " + std::to_string(dibSize));
if (dibSize < BMP_DIB_HEADER_SIZE_MIN) return Logger::error("BmpParser", "parseHeader", "Unsupported DIB header size: " + std::to_string(dibSize));

width = readUint32(p, 18);
height = static_cast<int32_t>(readUint32(p, 22));
const uint32_t absHeight = static_cast<uint32_t>(height > 0 ? height : -height);
if (!validateDimensions(width, absHeight)) return false;

uint16_t planes = readUint16(p, 26);
if (planes != BMP_PLANES_EXPECTED) return Logger::error("BmpParser", "parseBmpHeader", "Planes != 1: " + std::to_string(planes));
if (planes != BMP_PLANES_EXPECTED) return Logger::error("BmpParser", "parseHeader", "Planes != 1: " + std::to_string(planes));

uint16_t bpp = readUint16(p, 28);
if (bpp != BMP_BPP_24) return Logger::error("BmpParser", "parseBmpHeader", "Only 24bpp supported: " + std::to_string(bpp));
if (bpp != BMP_BPP_24) return Logger::error("BmpParser", "parseHeader", "Only 24bpp supported: " + std::to_string(bpp));

uint32_t compression = readUint32(p, 30);
if (compression != BMP_COMPRESSION_NONE) return Logger::error("BmpParser", "parseBmpHeader", "Compressed BMP not supported: " + std::to_string(compression));
if (compression != BMP_COMPRESSION_NONE) return Logger::error("BmpParser", "parseHeader", "Compressed BMP not supported: " + std::to_string(compression));

return true;
}
Expand Down
12 changes: 6 additions & 6 deletions src/parser/image/imageParserBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,24 @@ void ImageParserBase::clearImageData(ImageData& data) const {
std::optional<std::vector<unsigned char>> ImageParserBase::loadImageData(const std::string& path) {
std::vector<unsigned char> file;
if (!loadBinaryFile(file, path)) {
Logger::error("ImageParser", "loadImageData", std::string("Failed to load file: ") + path);
Logger::error("ImageParserBase", "loadImageData", std::string("Failed to load file: ") + path);
return std::nullopt;
}

if (file.empty()) {
Logger::error("ImageParser", "loadImageData", "File is empty");
Logger::error("ImageParserBase", "loadImageData", "File is empty");
return std::nullopt;
}

return file;
}

bool ImageParserBase::validateDimensions(uint32_t width, uint32_t height) const {
if (width == 0) return Logger::error("ImageParser", "validateDimensions", "Invalid width: " + std::to_string(width));
if (height == 0) return Logger::error("ImageParser", "validateDimensions", "Invalid height: " + std::to_string(height));
if (width == 0) return Logger::error("ImageParserBase", "validateDimensions", "Invalid width: " + std::to_string(width));
if (height == 0) return Logger::error("ImageParserBase", "validateDimensions", "Invalid height: " + std::to_string(height));
constexpr size_t MAX_DIMENSION = 65536;
if (width > MAX_DIMENSION) return Logger::error("ImageParser", "validateDimensions", "Width exceeds maximum: " + std::to_string(width));
if (height > MAX_DIMENSION) return Logger::error("ImageParser", "validateDimensions", "Height exceeds maximum: " + std::to_string(height));
if (width > MAX_DIMENSION) return Logger::error("ImageParserBase", "validateDimensions", "Width exceeds maximum: " + std::to_string(width));
if (height > MAX_DIMENSION) return Logger::error("ImageParserBase", "validateDimensions", "Height exceeds maximum: " + std::to_string(height));
return true;
}

Expand Down
8 changes: 4 additions & 4 deletions src/parser/image/tgaParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@ bool TgaParser::parseHeader(const unsigned char* p, size_t fileSize, uint32_t& w
const uint8_t imageType = p[2];

if (imageType != TGA_IMAGE_TYPE_UNCOMPRESSED_TRUE_COLOR)
return Logger::error("TgaParser", "parseTgaHeader", "Unsupported TGA image type (only uncompressed true-colour TGA supported (2)), got: " + std::to_string(imageType));
return Logger::error("TgaParser", "parseHeader", "Unsupported TGA image type (only uncompressed true-colour TGA supported (2)), got: " + std::to_string(imageType));

if (colourMapType != TGA_COLOUR_MAP_TYPE_NONE)
return Logger::error("TgaParser", "parseTgaHeader", "Unsupported TGA colour map type (only no colour map supported (0)), got: " + std::to_string(colourMapType));
return Logger::error("TgaParser", "parseHeader", "Unsupported TGA colour map type (only no colour map supported (0)), got: " + std::to_string(colourMapType));

width = static_cast<uint32_t>(readUint16(p, 12));
height = static_cast<uint32_t>(readUint16(p, 14));
Expand All @@ -56,14 +56,14 @@ bool TgaParser::parseHeader(const unsigned char* p, size_t fileSize, uint32_t& w

bpp = p[16];
if (bpp != 24 && bpp != 32)
return Logger::error("TgaParser", "parseTgaHeader", "Unsupported TGA bits per pixel (only 24 and 32 supported), got: " + std::to_string(bpp));
return Logger::error("TgaParser", "parseHeader", "Unsupported TGA bits per pixel (only 24 and 32 supported), got: " + std::to_string(bpp));

const uint8_t imageDescriptor = p[17];
topDown = (imageDescriptor & TGA_ORIGIN_TOP_BIT) != 0;

dataOffset = TGA_HEADER_SIZE + idLength;
if (dataOffset >= fileSize)
return Logger::error("TgaParser", "parseTgaHeader", "Invalid data offset");
return Logger::error("TgaParser", "parseHeader", "Invalid data offset");

return true;
}
Expand Down
9 changes: 3 additions & 6 deletions src/parser/imageParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,8 @@
namespace Starlet::Serializer {

bool ImageParser::parse(const std::string& path, ImageData& out) {
ImageFormat format = detectFormat(path);

std::unique_ptr<ImageParserBase> parser;
switch (format) {
switch (detectFormat(path)) {
case ImageFormat::BMP:
parser = std::make_unique<BmpParser>();
break;
Expand All @@ -30,14 +28,13 @@ bool ImageParser::parse(const std::string& path, ImageData& out) {

ImageParser::ImageFormat ImageParser::detectFormat(const std::string& path) {
size_t dotPos = path.find_last_of('.');
if (dotPos == std::string::npos || dotPos == path.length() - 1) {
if (dotPos == std::string::npos || dotPos == path.length() - 1)
return ImageFormat::UNKNOWN;
}

std::string extension = path.substr(dotPos + 1);
for (char& c : extension) c = static_cast<char>(tolower(c));

if (extension == "bmp") return ImageFormat::BMP;
if (extension == "bmp") return ImageFormat::BMP;
else if (extension == "tga") return ImageFormat::TGA;
else return ImageFormat::UNKNOWN;
}
Expand Down
20 changes: 10 additions & 10 deletions src/parser/mesh/plyParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ bool PlyParser::parse(const std::string& path, MeshData& out) {
if (!loadBinaryFile(file, path))
return false;

if (file.empty()) return Logger::error("PlyParser", "parsePlyMesh", "Input pointer is null\n");
if (file.empty()) return Logger::error("PlyParser", "parse", "Input pointer is null\n");

const unsigned char* p = file.data();
std::string errorMsg;
Expand Down Expand Up @@ -55,11 +55,11 @@ bool PlyParser::parse(const std::string& path, MeshData& out) {
out.indices.clear();
out.vertices.clear();
out.numVertices = out.numIndices = out.numTriangles = 0;
return Logger::error("PlyParser", "LoadModelFromFile", ("Failed to parse " + errorMsg + '\n').c_str());
return Logger::error("PlyParser", "parse", ("Failed to parse " + errorMsg + '\n').c_str());
}

bool PlyParser::parseHeaderLine(const unsigned char*& p, unsigned int& numVerticesOut, unsigned int& numTrianglesOut, bool& hasNormalsOut, bool& hasColoursOut, bool& hasTexCoordsOut) {
if (!p) return Logger::error("PlyParser", "parsePlyHeader", "Input pointer is null\n");
if (!p) return Logger::error("PlyParser", "parseHeaderLine", "Input pointer is null\n");
p = skipWhitespace(p);

bool hasNx = false, hasNy = false, hasNz = false;
Expand Down Expand Up @@ -92,16 +92,16 @@ bool PlyParser::parseHeaderLine(const unsigned char*& p, unsigned int& numVertic
else if (!(strncasecmp((const char*)p, "ply", 3) == 0)
&& !(strncasecmp((const char*)p, "format", 6) == 0)
&& !(strncasecmp((const char*)p, "comment", 7) == 0))
Logger::debug("parsePlyHeader", "Unknown line in PLY header: %.*s\n" + static_cast<int>(lineEnd - p), (const char*)p);
Logger::debug("plyParser", "parseHeaderLine", ("Unknown line in PLY header: %.*s\n" + std::string((const char*)p, static_cast<size_t>(lineEnd - p))).c_str());

p = nextLine;
}

return Logger::error("plyParser", "parsePlyHeader", "Failed, end of buffer reached");
return Logger::error("plyParser", "parseHeaderLine", "Failed, end of buffer reached");
}

bool PlyParser::parseElementLine(const unsigned char*& p, unsigned int& verticesOut, unsigned int& trianglesOut) {
if (!p) return Logger::error("PlyParser", "parsePlyHeader", "Input pointer is null\n");
if (!p) return Logger::error("PlyParser", "parseElementLine", "Input pointer is null\n");

p = skipWhitespace(p += 7);
if (strncmp((const char*)p, "vertex", 6) == 0 && (p[6] == ' ' || p[6] == '\t')) {
Expand All @@ -115,12 +115,12 @@ bool PlyParser::parseElementLine(const unsigned char*& p, unsigned int& vertices
return false;
}
bool PlyParser::parsePropertyLine(const unsigned char*& p, bool& hasNx, bool& hasNy, bool& hasNz, bool& hasR, bool& hasG, bool& hasB, bool& hasU, bool& hasV) {
if (!p) return Logger::error("PlyParser", "parsePlyPropertyLine", "Input pointer is null\n");
if (!p) return Logger::error("PlyParser", "parsePropertyLine", "Input pointer is null\n");
p = skipWhitespace(p += 8);

char type[32]{};
if (!parseToken(p, (unsigned char*)type, sizeof(type)))
return Logger::error("PlyParser", "parsePlyPropertyLine", "Failed to parse property type :" + std::string(type));
return Logger::error("PlyParser", "parsePropertyLine", "Failed to parse property type :" + std::string(type));

if (strcmp(type, "list") == 0) {
/*
Expand All @@ -131,14 +131,14 @@ bool PlyParser::parsePropertyLine(const unsigned char*& p, bool& hasNx, bool& ha
char property[3][32]{};
for (int i = 0; i < 3; ++i)
if (!parseToken(p, reinterpret_cast<unsigned char*>(property[i]), sizeof(property[i])))
return Logger::error("PlyParser", "parsePlyPropertyLine", "Failed to parse property list type, number: " + std::to_string(i));
return Logger::error("PlyParser", "parsePropertyLine", "Failed to parse property list type, number: " + std::to_string(i));

return true;
}

char propertyName[32]{};
if (!parseToken(p, (unsigned char*)propertyName, sizeof(propertyName)))
return Logger::error("PlyParser", "parsePlyPropertyLine", "Failed to parse property name :" + std::string(propertyName));
return Logger::error("PlyParser", "parsePropertyLine", "Failed to parse property name :" + std::string(propertyName));

if (strcmp(propertyName, "nx") == 0 || strcmp(propertyName, "normal_x") == 0) hasNx = true;
else if (strcmp(propertyName, "ny") == 0 || strcmp(propertyName, "normal_y") == 0) hasNy = true;
Expand Down
45 changes: 21 additions & 24 deletions src/parser/meshParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,33 +8,30 @@

namespace Starlet::Serializer {

bool MeshParser::parse(const std::string& path, MeshData& out) {
MeshFormat format = detectFormat(path);

std::unique_ptr<MeshParserBase> parser;
switch (format) {
case MeshFormat::PLY:
parser = std::make_unique<PlyParser>();
break;
default:
Logger::error("ImageParser", "parse", "Unsupported image format: " + path);
return false;
}

return parser->parse(path, out);
bool MeshParser::parse(const std::string& path, MeshData& out) {
std::unique_ptr<MeshParserBase> parser;
switch (detectFormat(path)) {
case MeshFormat::PLY:
parser = std::make_unique<PlyParser>();
break;
default:
Logger::error("MeshParser", "parse", "Unsupported mesh format: " + path);
return false;
}

MeshParser::MeshFormat MeshParser::detectFormat(const std::string& path) {
size_t dotPos = path.find_last_of('.');
if (dotPos == std::string::npos || dotPos == path.length() - 1) {
return MeshFormat::UNKNOWN;
}
return parser->parse(path, out);
}

std::string extension = path.substr(dotPos + 1);
for (char& c : extension) c = static_cast<char>(tolower(c));
MeshParser::MeshFormat MeshParser::detectFormat(const std::string& path) {
size_t dotPos = path.find_last_of('.');
if (dotPos == std::string::npos || dotPos == path.length() - 1)
return MeshFormat::UNKNOWN;

if (extension == "ply") return MeshFormat::PLY;
else return MeshFormat::UNKNOWN;
}
std::string extension = path.substr(dotPos + 1);
for (char& c : extension) c = static_cast<char>(tolower(c));

if (extension == "ply") return MeshFormat::PLY;
else return MeshFormat::UNKNOWN;
}

}
Loading