aboutsummaryrefslogtreecommitdiff
path: root/src/openvic-simulation/utility
diff options
context:
space:
mode:
author CptAlanSmith <123112708+CptAlanSmith@users.noreply.github.com>2023-09-25 23:21:59 +0200
committer GitHub <noreply@github.com>2023-09-25 23:21:59 +0200
commit63e462fceff981f79bcbae53e8d90fc59733e8c2 (patch)
tree403b586b3bc3f69f42a2362a273e77415ebf1d22 /src/openvic-simulation/utility
parent127ca294056817bc5814ef5516b29a67ff3fa3bb (diff)
parent932b43953d623557236a31b30899b706307260ed (diff)
Merge pull request #33 from OpenVicProject/terrain-types
Terrain types
Diffstat (limited to 'src/openvic-simulation/utility')
-rw-r--r--src/openvic-simulation/utility/BMP.cpp93
-rw-r--r--src/openvic-simulation/utility/BMP.hpp17
2 files changed, 89 insertions, 21 deletions
diff --git a/src/openvic-simulation/utility/BMP.cpp b/src/openvic-simulation/utility/BMP.cpp
index 531870b..2fa9417 100644
--- a/src/openvic-simulation/utility/BMP.cpp
+++ b/src/openvic-simulation/utility/BMP.cpp
@@ -11,13 +11,12 @@ BMP::~BMP() {
close();
}
-bool BMP::open(char const* filepath) {
+bool BMP::open(fs::path const& filepath) {
reset();
- errno = 0;
- file = fopen(filepath, "rb");
- if (file == nullptr || errno != 0) {
- Logger::error("Failed to open BMP file \"", filepath, "\" (errno = ", errno, ")");
- file = nullptr;
+ file.open(filepath, std::ios::binary);
+ if (file.fail()) {
+ Logger::error("Failed to open BMP file \"", filepath, "\"");
+ close();
return false;
}
return true;
@@ -28,15 +27,17 @@ bool BMP::read_header() {
Logger::error("BMP header already validated!");
return false;
}
- if (file == nullptr) {
+ if (!file.is_open()) {
Logger::error("Cannot read BMP header before opening a file");
return false;
}
- if (fseek(file, 0, SEEK_SET) != 0) {
+ file.seekg(0, std::ios::beg);
+ if (file.fail()) {
Logger::error("Failed to move to the beginning of the BMP file!");
return false;
}
- if (fread(&header, sizeof(header), 1, file) != 1) {
+ file.read(reinterpret_cast<char*>(&header), sizeof(header));
+ if (file.fail()) {
Logger::error("Failed to read BMP header!");
return false;
}
@@ -117,7 +118,11 @@ bool BMP::read_header() {
}
bool BMP::read_palette() {
- if (file == nullptr) {
+ if (palette_read) {
+ Logger::error("BMP palette already read!");
+ return false;
+ }
+ if (!file.is_open()) {
Logger::error("Cannot read BMP palette before opening a file");
return false;
}
@@ -129,24 +134,25 @@ bool BMP::read_palette() {
Logger::error("Cannot read BMP palette - header indicates this file doesn't have one");
return false;
}
- if (fseek(file, sizeof(header), SEEK_SET) != 0) {
+ file.seekg(sizeof(header), std::ios::beg);
+ if (file.fail()) {
Logger::error("Failed to move to the palette in the BMP file!");
return false;
}
palette.resize(palette_size);
- if (fread(palette.data(), palette_size * PALETTE_COLOUR_SIZE, 1, file) != 1) {
+ file.read(reinterpret_cast<char*>(palette.data()), palette_size * PALETTE_COLOUR_SIZE);
+ if (file.fail()) {
Logger::error("Failed to read BMP header!");
palette.clear();
return false;
}
- return true;
+ palette_read = true;
+ return palette_read;
}
void BMP::close() {
- if (file != nullptr) {
- if (fclose(file) != 0)
- Logger::error("Failed to close BMP!");
- file = nullptr;
+ if (file.is_open()) {
+ file.close();
}
}
@@ -156,8 +162,61 @@ void BMP::reset() {
header_validated = false;
palette_size = 0;
palette.clear();
+ pixel_data.clear();
+}
+
+int32_t BMP::get_width() const {
+ return header.width_px;
+}
+
+int32_t BMP::get_height() const {
+ return header.height_px;
+}
+
+uint16_t BMP::get_bits_per_pixel() const {
+ return header.bits_per_pixel;
}
std::vector<colour_t> const& BMP::get_palette() const {
+ if (!palette_read) {
+ Logger::warning("Trying to get BMP palette before loading");
+ }
return palette;
}
+
+bool BMP::read_pixel_data() {
+ if (pixel_data_read) {
+ Logger::error("BMP pixel data already read!");
+ return false;
+ }
+ if (!file.is_open()) {
+ Logger::error("Cannot read BMP pixel data before opening a file");
+ return false;
+ }
+ if (!header_validated) {
+ Logger::error("Cannot read pixel data before BMP header is validated!");
+ return false;
+ }
+ file.seekg(header.offset, std::ios::beg);
+ if (file.fail()) {
+ Logger::error("Failed to move to the pixel data in the BMP file!");
+ return false;
+ }
+ const size_t pixel_data_size = get_width() * get_height() * header.bits_per_pixel / 8;
+ pixel_data.resize(pixel_data_size);
+ file.read(reinterpret_cast<char*>(pixel_data.data()), pixel_data_size);
+ if (file.fail()) {
+ Logger::error("Failed to read BMP pixel data!");
+ pixel_data.clear();
+ return false;
+ }
+ pixel_data_read = true;
+ return pixel_data_read;
+}
+
+std::vector<uint8_t> const& BMP::get_pixel_data() const {
+ if (!pixel_data_read) {
+ Logger::warning("Trying to get BMP pixel data before loading");
+ }
+ return pixel_data;
+}
diff --git a/src/openvic-simulation/utility/BMP.hpp b/src/openvic-simulation/utility/BMP.hpp
index f04b41a..c08ac99 100644
--- a/src/openvic-simulation/utility/BMP.hpp
+++ b/src/openvic-simulation/utility/BMP.hpp
@@ -1,11 +1,14 @@
#pragma once
-#include <cstdio>
+#include <filesystem>
+#include <fstream>
#include <vector>
#include "openvic-simulation/types/Colour.hpp"
namespace OpenVic {
+ namespace fs = std::filesystem;
+
class BMP {
#pragma pack(push)
#pragma pack(1)
@@ -29,10 +32,11 @@ namespace OpenVic {
} header;
#pragma pack(pop)
- FILE* file = nullptr;
- bool header_validated = false;
+ std::ifstream file;
+ bool header_validated = false, palette_read = false, pixel_data_read = false;
uint32_t palette_size = 0;
std::vector<colour_t> palette;
+ std::vector<uint8_t> pixel_data;
public:
static constexpr uint32_t PALETTE_COLOUR_SIZE = sizeof(colour_t);
@@ -40,12 +44,17 @@ namespace OpenVic {
BMP() = default;
~BMP();
- bool open(char const* filepath);
+ bool open(fs::path const& filepath);
bool read_header();
bool read_palette();
+ bool read_pixel_data();
void close();
void reset();
+ int32_t get_width() const;
+ int32_t get_height() const;
+ uint16_t get_bits_per_pixel() const;
std::vector<colour_t> const& get_palette() const;
+ std::vector<uint8_t> const& get_pixel_data() const;
};
}