From 9d7a0a167d556741142e9d2032fff1f2f85ae54b Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Wed, 31 Dec 2025 12:25:11 +0100 Subject: [PATCH] Move importing JSON palettes to ImageImporter --- src/openrct2/drawing/ImageImporter.cpp | 48 ++++++++++++++++++++++++++ src/openrct2/drawing/ImageImporter.h | 7 ++++ src/openrct2/object/WaterObject.cpp | 42 +++------------------- src/openrct2/object/WaterObject.h | 1 - 4 files changed, 59 insertions(+), 39 deletions(-) diff --git a/src/openrct2/drawing/ImageImporter.cpp b/src/openrct2/drawing/ImageImporter.cpp index 658c4686d2..7370f2c469 100644 --- a/src/openrct2/drawing/ImageImporter.cpp +++ b/src/openrct2/drawing/ImageImporter.cpp @@ -9,6 +9,7 @@ #include "ImageImporter.h" +#include "../core/Guard.hpp" #include "../core/Imaging.h" #include "../core/Json.hpp" @@ -59,6 +60,53 @@ namespace OpenRCT2::Drawing return result; } + PaletteImportResult ImageImporter::importJSONPalette(json_t& jPalette) const + { + Guard::Assert(jPalette.is_object(), "ImageImporter::importJSONPalette expects parameter jPalette to be object"); + + auto jColours = jPalette["colours"]; + auto numColours = jColours.size(); + + std::vector buffer; + buffer.reserve(numColours); + + for (auto& jColour : jColours) + { + BGRColour colour{}; + if (jColour.is_string()) + { + colour = parseJSONPaletteColour(Json::GetString(jColour)); + } + buffer.push_back(colour); + } + + G1Palette outElement = {}; + outElement.numColours = static_cast(numColours); + outElement.startIndex = Json::GetNumber(jPalette["index"]); + outElement.flags = { G1Flag::isPalette }; + + PaletteImportResult result; + result.element = outElement; + result.buffer = std::move(buffer); + result.element.palette = result.buffer.data(); + return result; + } + + BGRColour ImageImporter::parseJSONPaletteColour(const std::string& s) const + { + uint8_t r = 0; + uint8_t g = 0; + uint8_t b = 0; + if (s[0] == '#' && s.size() == 7) + { + // Expect #RRGGBB + r = std::stoul(s.substr(1, 2), nullptr, 16) & 0xFF; + g = std::stoul(s.substr(3, 2), nullptr, 16) & 0xFF; + b = std::stoul(s.substr(5, 2), nullptr, 16) & 0xFF; + } + return { b, g, r }; + } + std::vector ImageImporter::GetPixels(const Image& image, const ImageImportMeta& meta) { const uint8_t* pixels = image.Pixels.data(); diff --git a/src/openrct2/drawing/ImageImporter.h b/src/openrct2/drawing/ImageImporter.h index af581b3c4b..5285f4a951 100644 --- a/src/openrct2/drawing/ImageImporter.h +++ b/src/openrct2/drawing/ImageImporter.h @@ -57,6 +57,11 @@ namespace OpenRCT2::Drawing G1Element Element{}; std::vector Buffer; }; + struct PaletteImportResult + { + G1Palette element{}; + std::vector buffer; + }; /** * Imports images to the internal RCT G1 format. @@ -65,6 +70,7 @@ namespace OpenRCT2::Drawing { public: ImageImportResult Import(const Image& image, ImageImportMeta& meta) const; + PaletteImportResult importJSONPalette(json_t& jPalette) const; private: enum class PaletteIndexType : uint8_t @@ -88,6 +94,7 @@ namespace OpenRCT2::Drawing static bool IsChangablePixel(int32_t paletteIndex); static PaletteIndexType GetPaletteIndexType(int32_t paletteIndex); static int32_t GetClosestPaletteIndex(const GamePalette& palette, const int16_t* colour); + BGRColour parseJSONPaletteColour(const std::string& s) const; }; // Note: jsonSprite is deliberately left non-const: json_t behaviour changes when const. diff --git a/src/openrct2/object/WaterObject.cpp b/src/openrct2/object/WaterObject.cpp index bce5be6c32..cf1141da4f 100644 --- a/src/openrct2/object/WaterObject.cpp +++ b/src/openrct2/object/WaterObject.cpp @@ -15,6 +15,7 @@ #include "../core/IStream.hpp" #include "../core/Json.hpp" #include "../drawing/Drawing.h" +#include "../drawing/ImageImporter.h" #include "../localisation/Formatter.h" #include "../localisation/Language.h" #include "../localisation/StringIds.h" @@ -101,45 +102,10 @@ namespace OpenRCT2 void WaterObject::ReadJsonPalette(json_t& jPalette) { - Guard::Assert(jPalette.is_object(), "WaterObject::ReadJsonPalette expects parameter jPalette to be object"); - - auto jColours = jPalette["colours"]; - auto numColours = jColours.size(); - - // This pointer gets memcopied in ImageTable::AddImage so it's fine for the unique_ptr to go out of scope - auto data = std::make_unique(numColours); - size_t dataIndex = 0; - - for (auto& jColour : jColours) - { - if (jColour.is_string()) - { - data[dataIndex] = ParseColour(Json::GetString(jColour)); - } - dataIndex++; - } - - G1Palette g1 = {}; - g1.palette = data.get(); - g1.numColours = static_cast(numColours); - g1.startIndex = Json::GetNumber(jPalette["index"]); + auto importer = Drawing::ImageImporter(); + const auto importResult = importer.importJSONPalette(jPalette); auto& imageTable = GetImageTable(); - imageTable.addPalette(g1); - } - - Drawing::BGRColour WaterObject::ParseColour(const std::string& s) const - { - uint8_t r = 0; - uint8_t g = 0; - uint8_t b = 0; - if (s[0] == '#' && s.size() == 7) - { - // Expect #RRGGBB - r = std::stoul(s.substr(1, 2), nullptr, 16) & 0xFF; - g = std::stoul(s.substr(3, 2), nullptr, 16) & 0xFF; - b = std::stoul(s.substr(5, 2), nullptr, 16) & 0xFF; - } - return { b, g, r }; + imageTable.addPalette(importResult.element); } } // namespace OpenRCT2 diff --git a/src/openrct2/object/WaterObject.h b/src/openrct2/object/WaterObject.h index ae737c1fc7..4aa380b879 100644 --- a/src/openrct2/object/WaterObject.h +++ b/src/openrct2/object/WaterObject.h @@ -36,6 +36,5 @@ namespace OpenRCT2 private: void ReadJsonPalette(json_t& jPalette); - Drawing::BGRColour ParseColour(const std::string& s) const; }; } // namespace OpenRCT2