Skip to content
9 changes: 5 additions & 4 deletions src/ImageDataWebP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@
#include "ImageDataWebP.hpp"

#include <cmath>
#include <format>
#include <future>
#include <thread>
#include <vector>

namespace jngl {

ImageDataWebP::ImageDataWebP(std::string filename, FILE* file, double scaleFactor)
: filename(std::move(filename)) {
ImageDataWebP::ImageDataWebP(std::string_view filename, FILE* file, double scaleFactor)
: filename(filename) {
if (fseek(file, 0, SEEK_END) != 0) {
throw std::runtime_error("Error reading " + this->filename);
}
Expand All @@ -22,11 +23,11 @@ ImageDataWebP::ImageDataWebP(std::string filename, FILE* file, double scaleFacto

std::vector<uint8_t> buf(filesize);
if (!fread(buf.data(), filesize, 1, file)) {
throw std::runtime_error(std::string("Couldn't open WebP file. (" + this->filename + ")"));
throw std::runtime_error(std::format("Couldn't open WebP file. ({})", filename));
}

if (!WebPGetInfo(buf.data(), filesize, &imgWidth, &imgHeight)) {
throw std::runtime_error(std::string("Invalid WebP file. (" + this->filename + ")"));
throw std::runtime_error(std::format("Invalid WebP file. ({})", filename));
}

WebPInitDecoderConfig(&config);
Expand Down
2 changes: 1 addition & 1 deletion src/ImageDataWebP.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace jngl {

class ImageDataWebP : public ImageData {
public:
ImageDataWebP(std::string filename, FILE*, double scaleFactor);
ImageDataWebP(std::string_view filename, FILE*, double scaleFactor);
~ImageDataWebP() override;
ImageDataWebP(const ImageDataWebP&) = delete;
ImageDataWebP& operator=(const ImageDataWebP&) = delete;
Expand Down
48 changes: 24 additions & 24 deletions src/jngl/sprite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#if __cplusplus < 202002L
#include <boost/algorithm/string/predicate.hpp>
#endif
#include <format>
#include <cstddef>
#include <cstring>
#include <sstream>
Expand Down Expand Up @@ -66,7 +67,7 @@ Sprite::Sprite(const uint8_t* const bytes, const size_t width, const size_t heig
setCenter(0, 0);
}

Sprite::Sprite(const std::string& filename, LoadType loadType)
Sprite::Sprite(std::string_view filename, LoadType loadType)
: texture(TextureCache::handle().get(filename)) {
if (texture) {
width = texture->getPreciseWidth();
Expand All @@ -78,7 +79,7 @@ Sprite::Sprite(const std::string& filename, LoadType loadType)
if (!halfLoad) {
internal::debug("Creating sprite {}...", filename);
}
auto fullFilename = pathPrefix + filename;
auto fullFilename = std::format("{}{}", pathPrefix, filename);
const char* extensions[] = {
#ifndef NOWEBP
".webp",
Expand All @@ -88,7 +89,7 @@ Sprite::Sprite(const std::string& filename, LoadType loadType)
#endif
".bmp"
};
std::function<Finally(Sprite*, std::string, FILE*, bool)> functions[] = {
std::function<Finally(Sprite*, std::string_view, FILE*, bool)> functions[] = {
#ifndef NOWEBP
&Sprite::LoadWebP,
#endif
Expand All @@ -98,7 +99,7 @@ Sprite::Sprite(const std::string& filename, LoadType loadType)
&Sprite::LoadBMP
};
const size_t size = sizeof(extensions) / sizeof(extensions[0]);
std::function<Finally(Sprite*, std::string, FILE*, bool)> loadFunction;
std::function<Finally(Sprite*, std::string_view, FILE*, bool)> loadFunction;
for (size_t i = 0; i < size; ++i) {
#if __cplusplus < 202002L
if (boost::algorithm::ends_with(fullFilename, extensions[i])) {
Expand Down Expand Up @@ -314,30 +315,30 @@ const Shader& Sprite::vertexShader() {
}

#ifndef NOPNG
Finally Sprite::LoadPNG(const std::string& filename, FILE* const fp, const bool halfLoad) {
Finally Sprite::LoadPNG(std::string_view filename, FILE* const fp, const bool halfLoad) {
const unsigned int PNG_BYTES_TO_CHECK = 4;
png_byte buf[PNG_BYTES_TO_CHECK];

// Read in some of the signature bytes
if (fread(buf, 1, PNG_BYTES_TO_CHECK, fp) != PNG_BYTES_TO_CHECK ||
png_sig_cmp(buf, static_cast<png_size_t>(0), PNG_BYTES_TO_CHECK) != 0) {
throw std::runtime_error(std::string("Error reading signature bytes. (" + filename + ")"));
throw std::runtime_error(std::format("Error reading signature bytes. ({})", filename));
}

png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
if (!png_ptr) {
throw std::runtime_error(std::string("libpng error while reading (" + filename + ")"));
throw std::runtime_error(std::format("libpng error while reading ({})", filename));
}

png_infop info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr) {
throw std::runtime_error(std::string("libpng error while reading (" + filename + ")"));
throw std::runtime_error(std::format("libpng error while reading ({})", filename));
}

if (setjmp(png_jmpbuf(png_ptr))) {
// Free all of the memory associated with the png_ptr and info_ptr
png_destroy_read_struct(&png_ptr, &info_ptr, nullptr);
throw std::runtime_error(std::string("Error reading file. (" + filename + ")"));
throw std::runtime_error(std::format("Error reading file. ({})", filename));
}
png_init_io(png_ptr, fp);
png_set_sig_bytes(png_ptr, PNG_BYTES_TO_CHECK);
Expand All @@ -359,8 +360,7 @@ Finally Sprite::LoadPNG(const std::string& filename, FILE* const fp, const bool
format = GL_RGBA;
break;
default:
throw std::runtime_error(
std::string("Unsupported number of channels. (" + filename + ")"));
throw std::runtime_error(std::format("Unsupported number of channels. ({})", filename));
}

Finally freePng([&png_ptr, &info_ptr]() {
Expand All @@ -382,22 +382,22 @@ void Sprite::cleanUpRowPointers(std::vector<unsigned char*>& buf) {
}
}

Finally Sprite::LoadBMP(const std::string& filename, FILE* const fp, const bool halfLoad) {
Finally Sprite::LoadBMP(std::string_view filename, FILE* const fp, const bool halfLoad) {
if (fseek(fp, 10, SEEK_SET) != 0) {
throw std::runtime_error(std::string("Error seeking file. (" + filename + ")"));
throw std::runtime_error(std::format("Error seeking file. ({})", filename));
}
BMPHeader header{};
if (!fread(&header, sizeof(header), 1, fp)) {
throw std::runtime_error(std::string("Error reading file. (" + filename + ")"));
throw std::runtime_error(std::format("Error reading file. ({})", filename));
}
if (header.headerSize != 40) {
throw std::runtime_error(std::string("Unsupported header size. (" + filename + ")"));
throw std::runtime_error(std::format("Unsupported header size. ({})", filename));
}
if (header.bpp != 24) {
throw std::runtime_error(std::string("Bpp not supported. (" + filename + ")"));
throw std::runtime_error(std::format("Bpp not supported. ({})", filename));
}
if (header.compression != 0) {
throw std::runtime_error(std::string("Compression not supported. (" + filename + ")"));
throw std::runtime_error(std::format("Compression not supported. ({})", filename));
}
if (header.dataSize == 0) {
header.dataSize = header.width * header.height * 3;
Expand All @@ -413,21 +413,21 @@ Finally Sprite::LoadBMP(const std::string& filename, FILE* const fp, const bool
for (int i = 0; i < header.height; ++i) {
if (fseek(fp, header.dataOffset + static_cast<long>(i) * header.width * 3, SEEK_SET) !=
0) {
throw std::runtime_error(std::string("Error reading file. (" + filename + ")"));
throw std::runtime_error(std::format("Error reading file. ({})", filename));
}
if (!fread(buf[i], static_cast<size_t>(header.width) * 3, 1, fp)) {
throw std::runtime_error(std::string("Error reading data. (" + filename + ")"));
throw std::runtime_error(std::format("Error reading data. ({})", filename));
}
}
} else { // "bottom-up"-Bitmap
for (int i = header.height - 1; i >= 0; --i) {
if (fseek(fp, header.dataOffset + static_cast<long>(i) * header.width * 3, SEEK_SET) !=
0) {
throw std::runtime_error(std::string("Error reading file. (" + filename + ")"));
throw std::runtime_error(std::format("Error reading file. ({})", filename));
}
if (!fread(buf[(header.height - 1) - i], static_cast<size_t>(header.width) * 3, 1,
fp)) {
throw std::runtime_error(std::string("Error reading data. (" + filename + ")"));
throw std::runtime_error(std::format("Error reading data. ({})", filename));
}
}
}
Expand All @@ -437,7 +437,7 @@ Finally Sprite::LoadBMP(const std::string& filename, FILE* const fp, const bool
return Finally(nullptr);
}
#ifndef NOWEBP
Finally Sprite::LoadWebP(const std::string& filename, FILE* file, const bool halfLoad) {
Finally Sprite::LoadWebP(std::string_view filename, FILE* file, const bool halfLoad) {
auto imageData = std::make_shared<ImageDataWebP>(filename, file, getScaleFactor());
width = static_cast<float>(imageData->getImageWidth() * getScaleFactor());
height = static_cast<float>(imageData->getImageHeight() * getScaleFactor());
Expand All @@ -448,15 +448,15 @@ Finally Sprite::LoadWebP(const std::string& filename, FILE* file, const bool hal
}
#endif

void Sprite::loadTexture(const int scaledWidth, const int scaledHeight, const std::string& filename,
void Sprite::loadTexture(const int scaledWidth, const int scaledHeight, std::string_view filename,
const bool halfLoad, const unsigned int format,
const unsigned char* const* const rowPointers,
const unsigned char* const data) {
if (!pWindow) {
if (halfLoad) {
return;
}
throw std::runtime_error(std::string("Window hasn't been created yet. (" + filename + ")"));
throw std::runtime_error(std::format("Window hasn't been created yet. ({})", filename));
}
texture = std::make_shared<Texture>(width, height, scaledWidth, scaledHeight, rowPointers,
format, data);
Expand Down
13 changes: 7 additions & 6 deletions src/jngl/sprite.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "Vec2.hpp"

#include <future>
#include <string_view>
#include <optional>
#include <vector>

Expand Down Expand Up @@ -56,7 +57,7 @@ class Sprite : public Drawable {
Sprite(const uint8_t* bytes, size_t width, size_t height);

/// \deprecated Use Loader instead
explicit Sprite(const std::string& filename, LoadType loadType = LoadType::NORMAL);
explicit Sprite(std::string_view filename, LoadType loadType = LoadType::NORMAL);

/// Does nothing
void step() override;
Expand Down Expand Up @@ -228,10 +229,10 @@ class Sprite : public Drawable {

private:
static void cleanUpRowPointers(std::vector<unsigned char*>& buf);
void loadTexture(int scaledWidth, int scaledHeight, const std::string& filename, bool halfLoad,
void loadTexture(int scaledWidth, int scaledHeight, std::string_view filename, bool halfLoad,
unsigned int format, const unsigned char* const* rowPointers,
const unsigned char* data = nullptr);
Finally LoadPNG(const std::string& filename, FILE* fp, bool halfLoad);
Finally LoadPNG(std::string_view filename, FILE* fp, bool halfLoad);
struct BMPHeader {
unsigned int dataOffset;
unsigned int headerSize;
Expand All @@ -242,15 +243,15 @@ class Sprite : public Drawable {
unsigned int compression;
unsigned int dataSize;
};
Finally LoadBMP(const std::string& filename, FILE* fp, bool halfLoad);
Finally LoadBMP(std::string_view filename, FILE* fp, bool halfLoad);
#ifndef NOWEBP
Finally LoadWebP(const std::string& filename, FILE* file, bool halfLoad);
Finally LoadWebP(std::string_view filename, FILE* file, bool halfLoad);
#endif

std::shared_ptr<Texture> texture;
};

void draw(const std::string& filename, double x, double y);
void draw(std::string_view filename, double x, double y);

template <class Vect> void draw(const std::string& filename, Vect pos) {
draw(filename, pos.x, pos.y);
Expand Down
6 changes: 3 additions & 3 deletions src/spriteimpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ void setSpriteAlpha(unsigned char alpha) {
gSpriteColor.setAlpha(Alpha::u8(alpha));
}

std::unordered_map<std::string, std::shared_ptr<Sprite>> sprites_;
std::unordered_map<std::string_view, std::shared_ptr<Sprite>> sprites_;

// halfLoad is used, if we only want to find out the width or height of an image. Load won't throw
// an exception then
Sprite& GetSprite(const std::string& filename, const Sprite::LoadType loadType) {
Sprite& GetSprite(std::string_view filename, const Sprite::LoadType loadType) {
auto it = sprites_.find(filename);
if (it == sprites_.end()) { // texture hasn't been loaded yet?
if (loadType != Sprite::LoadType::HALF) {
Expand All @@ -64,7 +64,7 @@ Sprite& GetSprite(const std::string& filename, const Sprite::LoadType loadType)
return *(it->second);
}

void draw(const std::string& filename, double x, double y) {
void draw(std::string_view filename, double x, double y) {
auto& s = GetSprite(filename);
s.setPos(x, y);
s.draw();
Expand Down
2 changes: 1 addition & 1 deletion src/spriteimpl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
namespace jngl {

Finally loadSprite(const std::string&);
Sprite& GetSprite(const std::string& filename, Sprite::LoadType loadType = Sprite::LoadType::NORMAL);
Sprite& GetSprite(std::string_view filename, Sprite::LoadType loadType = Sprite::LoadType::NORMAL);

extern Rgba gSpriteColor;
extern Rgba gShapeColor;
Expand Down