mirror of https://github.com/OpenRCT2/OpenRCT2.git
Create import meta object, use single method for JSON parsing
This commit is contained in:
parent
eb2cda6a56
commit
c232aa9b0c
|
@ -275,6 +275,21 @@ namespace OpenRCT2::Scripting
|
|||
return unpadded;
|
||||
}
|
||||
|
||||
static ImportMode getImportModeFromPalette(const PixelDataPaletteKind& palette)
|
||||
{
|
||||
switch (palette)
|
||||
{
|
||||
case PixelDataPaletteKind::Closest:
|
||||
return ImportMode::Closest;
|
||||
case PixelDataPaletteKind::Dither:
|
||||
return ImportMode::Dithering;
|
||||
case PixelDataPaletteKind::None:
|
||||
case PixelDataPaletteKind::Keep:
|
||||
default:
|
||||
return ImportMode::Default;
|
||||
}
|
||||
}
|
||||
|
||||
static std::vector<uint8_t> GetBufferFromPixelData(duk_context* ctx, PixelData& pixelData)
|
||||
{
|
||||
std::vector<uint8_t> imageData;
|
||||
|
@ -303,18 +318,14 @@ namespace OpenRCT2::Scripting
|
|||
case PixelDataKind::Png:
|
||||
{
|
||||
auto imageFormat = pixelData.Palette == PixelDataPaletteKind::Keep ? IMAGE_FORMAT::PNG : IMAGE_FORMAT::PNG_32;
|
||||
auto palette = pixelData.Palette == PixelDataPaletteKind::Keep ? ImageImporter::Palette::KeepIndices
|
||||
: ImageImporter::Palette::OpenRCT2;
|
||||
auto importMode = ImageImporter::ImportMode::Default;
|
||||
if (pixelData.Palette == PixelDataPaletteKind::Closest)
|
||||
importMode = ImageImporter::ImportMode::Closest;
|
||||
else if (pixelData.Palette == PixelDataPaletteKind::Dither)
|
||||
importMode = ImageImporter::ImportMode::Dithering;
|
||||
auto palette = pixelData.Palette == PixelDataPaletteKind::Keep ? Palette::KeepIndices : Palette::OpenRCT2;
|
||||
auto importMode = getImportModeFromPalette(pixelData.Palette);
|
||||
auto pngData = DukGetDataFromBufferLikeObject(pixelData.Data);
|
||||
auto image = Imaging::ReadFromBuffer(pngData, imageFormat);
|
||||
ImageImportMeta meta = { { 0, 0 }, palette, ImportFlags::RLE, importMode };
|
||||
|
||||
ImageImporter importer;
|
||||
auto importResult = importer.Import(image, 0, 0, palette, ImageImporter::ImportFlags::RLE, importMode);
|
||||
auto importResult = importer.Import(image, meta);
|
||||
|
||||
pixelData.Type = PixelDataKind::Rle;
|
||||
pixelData.Width = importResult.Element.width;
|
||||
|
|
|
@ -225,21 +225,12 @@ static bool SpriteImageExport(const G1Element& spriteElement, u8string_view outP
|
|||
}
|
||||
}
|
||||
|
||||
static std::optional<ImageImporter::ImportResult> SpriteImageImport(
|
||||
const char* path, int16_t x_offset, int16_t y_offset, ImageImporter::Palette palette, bool forceBmp,
|
||||
ImageImporter::ImportMode mode)
|
||||
static std::optional<ImageImporter::ImportResult> SpriteImageImport(u8string_view path, ImageImportMeta meta)
|
||||
{
|
||||
try
|
||||
{
|
||||
auto format = IMAGE_FORMAT::PNG_32;
|
||||
auto flags = ImageImporter::ImportFlags::None;
|
||||
|
||||
if (!forceBmp)
|
||||
{
|
||||
flags = ImageImporter::ImportFlags::RLE;
|
||||
}
|
||||
|
||||
if (palette == ImageImporter::Palette::KeepIndices)
|
||||
if (meta.palette == Palette::KeepIndices)
|
||||
{
|
||||
format = IMAGE_FORMAT::PNG;
|
||||
}
|
||||
|
@ -247,7 +238,7 @@ static std::optional<ImageImporter::ImportResult> SpriteImageImport(
|
|||
ImageImporter importer;
|
||||
auto image = Imaging::ReadFromFile(path, format);
|
||||
|
||||
return importer.Import(image, x_offset, y_offset, palette, flags, mode);
|
||||
return importer.Import(image, meta);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
|
@ -483,21 +474,21 @@ int32_t CommandLineForSprite(const char** argv, int32_t argc)
|
|||
|
||||
const utf8* spriteFilePath = argv[1];
|
||||
const utf8* imagePath = argv[2];
|
||||
int16_t x_offset = 0;
|
||||
int16_t y_offset = 0;
|
||||
int16_t xOffset = 0;
|
||||
int16_t yOffset = 0;
|
||||
|
||||
if (argc == 5)
|
||||
{
|
||||
char* endptr;
|
||||
|
||||
x_offset = strtol(argv[3], &endptr, 0);
|
||||
xOffset = strtol(argv[3], &endptr, 0);
|
||||
if (*endptr != 0)
|
||||
{
|
||||
fprintf(stderr, "X offset must be an integer\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
y_offset = strtol(argv[4], &endptr, 0);
|
||||
yOffset = strtol(argv[4], &endptr, 0);
|
||||
if (*endptr != 0)
|
||||
{
|
||||
fprintf(stderr, "Y offset must be an integer\n");
|
||||
|
@ -505,8 +496,8 @@ int32_t CommandLineForSprite(const char** argv, int32_t argc)
|
|||
}
|
||||
}
|
||||
|
||||
auto importResult = SpriteImageImport(
|
||||
imagePath, x_offset, y_offset, ImageImporter::Palette::OpenRCT2, false, gSpriteMode);
|
||||
ImageImportMeta meta = { { xOffset, yOffset }, Palette::OpenRCT2, ImportFlags::RLE, gSpriteMode };
|
||||
auto importResult = SpriteImageImport(imagePath, meta);
|
||||
if (!importResult.has_value())
|
||||
return -1;
|
||||
|
||||
|
@ -579,18 +570,12 @@ int32_t CommandLineForSprite(const char** argv, int32_t argc)
|
|||
}
|
||||
std::string strPath = Json::GetString(path);
|
||||
|
||||
json_t x_offset = jsonSprite["x"];
|
||||
json_t y_offset = jsonSprite["y"];
|
||||
|
||||
auto palette = (Json::GetString(jsonSprite["palette"]) == "keep") ? ImageImporter::Palette::KeepIndices
|
||||
: ImageImporter::Palette::OpenRCT2;
|
||||
bool forceBmp = !jsonSprite["palette"].is_null() && Json::GetString(jsonSprite["format"]) == "raw";
|
||||
auto meta = createImageImportMetaFromJson(jsonSprite);
|
||||
meta.importMode = gSpriteMode;
|
||||
|
||||
auto imagePath = Path::GetAbsolute(Path::Combine(directoryPath, strPath));
|
||||
|
||||
auto importResult = SpriteImageImport(
|
||||
imagePath.c_str(), Json::GetNumber<int16_t>(x_offset), Json::GetNumber<int16_t>(y_offset), palette, forceBmp,
|
||||
gSpriteMode);
|
||||
auto importResult = SpriteImageImport(imagePath, meta);
|
||||
if (importResult == std::nullopt)
|
||||
{
|
||||
fprintf(stderr, "Could not import image file: %s\nCanceling\n", imagePath.c_str());
|
||||
|
|
|
@ -13,4 +13,4 @@
|
|||
#include "drawing/ImageImporter.h"
|
||||
|
||||
int32_t CommandLineForSprite(const char** argv, int32_t argc);
|
||||
extern OpenRCT2::Drawing::ImageImporter::ImportMode gSpriteMode;
|
||||
extern OpenRCT2::Drawing::ImportMode gSpriteMode;
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#define SZ_CLOSEST "closest"
|
||||
#define SZ_DITHERING "dithering"
|
||||
|
||||
using ImportMode = OpenRCT2::Drawing::ImageImporter::ImportMode;
|
||||
using ImportMode = OpenRCT2::Drawing::ImportMode;
|
||||
|
||||
ImportMode gSpriteMode = ImportMode::Default;
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "ImageImporter.h"
|
||||
|
||||
#include "../core/Imaging.h"
|
||||
#include "../core/Json.hpp"
|
||||
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
|
@ -20,36 +21,35 @@ using ImportResult = ImageImporter::ImportResult;
|
|||
|
||||
constexpr int32_t PALETTE_TRANSPARENT = -1;
|
||||
|
||||
ImportResult ImageImporter::Import(
|
||||
const Image& image, int32_t offsetX, int32_t offsetY, Palette palette, ImportFlags flags, ImportMode mode) const
|
||||
ImportResult ImageImporter::Import(const Image& image, ImageImportMeta& meta) const
|
||||
{
|
||||
return Import(image, 0, 0, image.Width, image.Height, offsetX, offsetY, palette, flags, mode);
|
||||
}
|
||||
if (meta.srcSize.width == 0)
|
||||
meta.srcSize.width = image.Width;
|
||||
|
||||
ImportResult ImageImporter::Import(
|
||||
const Image& image, int32_t srcX, int32_t srcY, int32_t width, int32_t height, int32_t offsetX, int32_t offsetY,
|
||||
Palette palette, ImportFlags flags, ImportMode mode) const
|
||||
{
|
||||
if (width > 256 || height > 256)
|
||||
if (meta.srcSize.height == 0)
|
||||
meta.srcSize.height = image.Height;
|
||||
|
||||
if (meta.srcSize.width > 256 || meta.srcSize.height > 256)
|
||||
{
|
||||
throw std::invalid_argument("Only images 256x256 or less are supported.");
|
||||
}
|
||||
|
||||
if (palette == Palette::KeepIndices && image.Depth != 8)
|
||||
if (meta.palette == Palette::KeepIndices && image.Depth != 8)
|
||||
{
|
||||
throw std::invalid_argument("Image is not paletted, it has bit depth of " + std::to_string(image.Depth));
|
||||
}
|
||||
const bool isRLE = meta.importFlags & ImportFlags::RLE;
|
||||
|
||||
auto pixels = GetPixels(image.Pixels.data(), image.Stride, srcX, srcY, width, height, palette, flags, mode);
|
||||
auto buffer = flags & ImportFlags::RLE ? EncodeRLE(pixels.data(), width, height) : EncodeRaw(pixels.data(), width, height);
|
||||
auto pixels = GetPixels(image, meta);
|
||||
auto buffer = isRLE ? EncodeRLE(pixels.data(), meta.srcSize) : EncodeRaw(pixels.data(), meta.srcSize);
|
||||
|
||||
G1Element outElement;
|
||||
outElement.width = width;
|
||||
outElement.height = height;
|
||||
outElement.flags = (flags & ImportFlags::RLE ? G1_FLAG_RLE_COMPRESSION : G1_FLAG_HAS_TRANSPARENCY);
|
||||
outElement.x_offset = offsetX;
|
||||
outElement.y_offset = offsetY;
|
||||
outElement.zoomed_offset = 0;
|
||||
outElement.width = meta.srcSize.width;
|
||||
outElement.height = meta.srcSize.height;
|
||||
outElement.flags = isRLE ? G1_FLAG_RLE_COMPRESSION : G1_FLAG_HAS_TRANSPARENCY;
|
||||
outElement.x_offset = meta.offset.x;
|
||||
outElement.y_offset = meta.offset.y;
|
||||
outElement.zoomed_offset = meta.zoomedOffset;
|
||||
|
||||
ImportResult result;
|
||||
result.Element = outElement;
|
||||
|
@ -58,44 +58,43 @@ ImportResult ImageImporter::Import(
|
|||
return result;
|
||||
}
|
||||
|
||||
std::vector<int32_t> ImageImporter::GetPixels(
|
||||
const uint8_t* pixels, uint32_t pitch, uint32_t srcX, uint32_t srcY, uint32_t width, uint32_t height, Palette palette,
|
||||
ImportFlags flags, ImportMode mode)
|
||||
std::vector<int32_t> ImageImporter::GetPixels(const Image& image, const ImageImportMeta& meta)
|
||||
{
|
||||
const uint8_t* pixels = image.Pixels.data();
|
||||
std::vector<int32_t> buffer;
|
||||
buffer.reserve(width * height);
|
||||
buffer.reserve(meta.srcSize.width * meta.srcSize.height);
|
||||
|
||||
// A larger range is needed for proper dithering
|
||||
auto palettedSrc = pixels;
|
||||
std::unique_ptr<int16_t[]> rgbaSrcBuffer;
|
||||
if (palette != Palette::KeepIndices)
|
||||
if (meta.palette != Palette::KeepIndices)
|
||||
{
|
||||
rgbaSrcBuffer = std::make_unique<int16_t[]>(height * width * 4);
|
||||
rgbaSrcBuffer = std::make_unique<int16_t[]>(meta.srcSize.height * meta.srcSize.width * 4);
|
||||
}
|
||||
|
||||
auto rgbaSrc = rgbaSrcBuffer.get();
|
||||
if (palette != Palette::KeepIndices)
|
||||
if (meta.palette != Palette::KeepIndices)
|
||||
{
|
||||
auto src = pixels + (srcY * pitch) + (srcX * 4);
|
||||
auto src = pixels + (meta.srcOffset.y * image.Stride) + (meta.srcOffset.x * 4);
|
||||
auto dst = rgbaSrc;
|
||||
for (uint32_t y = 0; y < height; y++)
|
||||
for (auto y = 0; y < meta.srcSize.height; y++)
|
||||
{
|
||||
for (uint32_t x = 0; x < width * 4; x++)
|
||||
for (auto x = 0; x < meta.srcSize.width * 4; x++)
|
||||
{
|
||||
*dst = static_cast<int16_t>(*src);
|
||||
src++;
|
||||
dst++;
|
||||
}
|
||||
src += (pitch - (width * 4));
|
||||
src += (image.Stride - (meta.srcSize.width * 4));
|
||||
}
|
||||
}
|
||||
|
||||
if (palette == Palette::KeepIndices)
|
||||
if (meta.palette == Palette::KeepIndices)
|
||||
{
|
||||
palettedSrc += srcX + srcY * pitch;
|
||||
for (uint32_t y = 0; y < height; y++)
|
||||
palettedSrc += meta.srcOffset.x + meta.srcOffset.y * image.Stride;
|
||||
for (auto y = 0; y < meta.srcSize.height; y++)
|
||||
{
|
||||
for (uint32_t x = 0; x < width; x++)
|
||||
for (auto x = 0; x < meta.srcSize.width; x++)
|
||||
{
|
||||
int32_t paletteIndex = *palettedSrc;
|
||||
// The 1st index is always transparent
|
||||
|
@ -106,16 +105,17 @@ std::vector<int32_t> ImageImporter::GetPixels(
|
|||
palettedSrc += 1;
|
||||
buffer.push_back(paletteIndex);
|
||||
}
|
||||
palettedSrc += (pitch - width);
|
||||
palettedSrc += (image.Stride - meta.srcSize.width);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (uint32_t y = 0; y < height; y++)
|
||||
for (auto y = 0; y < meta.srcSize.height; y++)
|
||||
{
|
||||
for (uint32_t x = 0; x < width; x++)
|
||||
for (auto x = 0; x < meta.srcSize.width; x++)
|
||||
{
|
||||
auto paletteIndex = CalculatePaletteIndex(mode, rgbaSrc, x, y, width, height);
|
||||
auto paletteIndex = CalculatePaletteIndex(
|
||||
meta.importMode, rgbaSrc, x, y, meta.srcSize.width, meta.srcSize.height);
|
||||
rgbaSrc += 4;
|
||||
buffer.push_back(paletteIndex);
|
||||
}
|
||||
|
@ -125,11 +125,11 @@ std::vector<int32_t> ImageImporter::GetPixels(
|
|||
return buffer;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> ImageImporter::EncodeRaw(const int32_t* pixels, uint32_t width, uint32_t height)
|
||||
std::vector<uint8_t> ImageImporter::EncodeRaw(const int32_t* pixels, ScreenSize size)
|
||||
{
|
||||
auto bufferLength = width * height;
|
||||
auto bufferLength = size.width * size.height;
|
||||
std::vector<uint8_t> buffer(bufferLength);
|
||||
for (size_t i = 0; i < bufferLength; i++)
|
||||
for (auto i = 0; i < bufferLength; i++)
|
||||
{
|
||||
auto p = pixels[i];
|
||||
buffer[i] = (p == PALETTE_TRANSPARENT ? 0 : static_cast<uint8_t>(p));
|
||||
|
@ -137,7 +137,7 @@ std::vector<uint8_t> ImageImporter::EncodeRaw(const int32_t* pixels, uint32_t wi
|
|||
return buffer;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> ImageImporter::EncodeRLE(const int32_t* pixels, uint32_t width, uint32_t height)
|
||||
std::vector<uint8_t> ImageImporter::EncodeRLE(const int32_t* pixels, ScreenSize size)
|
||||
{
|
||||
struct RLECode
|
||||
{
|
||||
|
@ -146,12 +146,12 @@ std::vector<uint8_t> ImageImporter::EncodeRLE(const int32_t* pixels, uint32_t wi
|
|||
};
|
||||
|
||||
auto src = pixels;
|
||||
std::vector<uint8_t> buffer((height * 2) + (width * height * 16));
|
||||
std::vector<uint8_t> buffer((size.height * 2) + (size.width * size.height * 16));
|
||||
|
||||
std::fill_n(buffer.data(), (height * 2) + (width * height * 16), 0x00);
|
||||
std::fill_n(buffer.data(), (size.height * 2) + (size.width * size.height * 16), 0x00);
|
||||
auto yOffsets = reinterpret_cast<uint16_t*>(buffer.data());
|
||||
auto dst = buffer.data() + (height * 2);
|
||||
for (uint32_t y = 0; y < height; y++)
|
||||
auto dst = buffer.data() + (size.height * 2);
|
||||
for (auto y = 0; y < size.height; y++)
|
||||
{
|
||||
yOffsets[y] = static_cast<uint16_t>(dst - buffer.data());
|
||||
|
||||
|
@ -162,7 +162,7 @@ std::vector<uint8_t> ImageImporter::EncodeRLE(const int32_t* pixels, uint32_t wi
|
|||
auto startX = 0;
|
||||
auto npixels = 0;
|
||||
bool pushRun = false;
|
||||
for (uint32_t x = 0; x < width; x++)
|
||||
for (auto x = 0; x < size.width; x++)
|
||||
{
|
||||
int32_t paletteIndex = *src++;
|
||||
if (paletteIndex == PALETTE_TRANSPARENT)
|
||||
|
@ -184,7 +184,7 @@ std::vector<uint8_t> ImageImporter::EncodeRLE(const int32_t* pixels, uint32_t wi
|
|||
npixels++;
|
||||
*dst++ = static_cast<uint8_t>(paletteIndex);
|
||||
}
|
||||
if (npixels == 127 || x == width - 1)
|
||||
if (npixels == 127 || x == size.width - 1)
|
||||
{
|
||||
pushRun = true;
|
||||
}
|
||||
|
@ -197,7 +197,7 @@ std::vector<uint8_t> ImageImporter::EncodeRLE(const int32_t* pixels, uint32_t wi
|
|||
currentCode->NumPixels = npixels;
|
||||
currentCode->OffsetX = startX;
|
||||
|
||||
if (x == width - 1)
|
||||
if (x == size.width - 1)
|
||||
{
|
||||
currentCode->NumPixels |= 0x80;
|
||||
}
|
||||
|
@ -381,3 +381,26 @@ int32_t ImageImporter::GetClosestPaletteIndex(const GamePalette& palette, const
|
|||
}
|
||||
return bestMatch;
|
||||
}
|
||||
|
||||
namespace OpenRCT2::Drawing
|
||||
{
|
||||
ImageImportMeta createImageImportMetaFromJson(json_t& input)
|
||||
{
|
||||
auto xOffset = Json::GetNumber<int16_t>(input["x"]);
|
||||
auto yOffset = Json::GetNumber<int16_t>(input["y"]);
|
||||
auto keepPalette = Json::GetString(input["palette"]) == "keep";
|
||||
auto palette = keepPalette ? Palette::KeepIndices : Palette::OpenRCT2;
|
||||
|
||||
auto raw = Json::GetString(input["format"]) == "raw";
|
||||
auto flags = raw ? ImportFlags::None : ImportFlags::RLE;
|
||||
|
||||
auto srcX = Json::GetNumber<int16_t>(input["srcX"]);
|
||||
auto srcY = Json::GetNumber<int16_t>(input["srcY"]);
|
||||
auto srcWidth = Json::GetNumber<int16_t>(input["srcWidth"]);
|
||||
auto srcHeight = Json::GetNumber<int16_t>(input["srcHeight"]);
|
||||
auto zoomedOffset = Json::GetNumber<int32_t>(input["zoom"]);
|
||||
|
||||
return ImageImportMeta{ { xOffset, yOffset }, palette, flags, ImportMode::Default, { srcX, srcY },
|
||||
{ srcWidth, srcHeight }, zoomedOffset };
|
||||
};
|
||||
} // namespace OpenRCT2::Drawing
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "../core/Imaging.h"
|
||||
#include "../core/JsonFwd.hpp"
|
||||
#include "Drawing.h"
|
||||
|
||||
#include <string_view>
|
||||
|
@ -19,6 +20,36 @@ struct Image;
|
|||
|
||||
namespace OpenRCT2::Drawing
|
||||
{
|
||||
enum class ImportMode : uint8_t
|
||||
{
|
||||
Default,
|
||||
Closest,
|
||||
Dithering,
|
||||
};
|
||||
|
||||
enum ImportFlags : uint8_t
|
||||
{
|
||||
None = 0,
|
||||
RLE = 1 << 1,
|
||||
};
|
||||
|
||||
enum class Palette : uint8_t
|
||||
{
|
||||
OpenRCT2,
|
||||
KeepIndices,
|
||||
};
|
||||
|
||||
struct ImageImportMeta
|
||||
{
|
||||
ScreenCoordsXY offset{};
|
||||
Palette palette = Palette::OpenRCT2;
|
||||
ImportFlags importFlags = ImportFlags::RLE;
|
||||
ImportMode importMode = ImportMode::Default;
|
||||
ScreenCoordsXY srcOffset{};
|
||||
ScreenSize srcSize{};
|
||||
int32_t zoomedOffset{};
|
||||
};
|
||||
|
||||
/**
|
||||
* Imports images to the internal RCT G1 format.
|
||||
*/
|
||||
|
@ -31,32 +62,7 @@ namespace OpenRCT2::Drawing
|
|||
std::vector<uint8_t> Buffer;
|
||||
};
|
||||
|
||||
enum class ImportMode : uint8_t
|
||||
{
|
||||
Default,
|
||||
Closest,
|
||||
Dithering,
|
||||
};
|
||||
|
||||
enum ImportFlags : uint8_t
|
||||
{
|
||||
None = 0,
|
||||
RLE = 1 << 1,
|
||||
};
|
||||
|
||||
enum class Palette : uint8_t
|
||||
{
|
||||
OpenRCT2,
|
||||
KeepIndices,
|
||||
};
|
||||
|
||||
ImportResult Import(
|
||||
const Image& image, int32_t srcX, int32_t srcY, int32_t width, int32_t height, int32_t offsetX, int32_t offsetY,
|
||||
Palette palette = Palette::OpenRCT2, ImportFlags flags = ImportFlags::None,
|
||||
ImportMode mode = ImportMode::Default) const;
|
||||
ImportResult Import(
|
||||
const Image& image, int32_t offsetX = 0, int32_t offsetY = 0, Palette palette = Palette::OpenRCT2,
|
||||
ImportFlags flags = ImportFlags::None, ImportMode mode = ImportMode::Default) const;
|
||||
ImportResult Import(const Image& image, ImageImportMeta& meta) const;
|
||||
|
||||
private:
|
||||
enum class PaletteIndexType : uint8_t
|
||||
|
@ -68,11 +74,9 @@ namespace OpenRCT2::Drawing
|
|||
Special,
|
||||
};
|
||||
|
||||
static std::vector<int32_t> GetPixels(
|
||||
const uint8_t* pixels, uint32_t pitch, uint32_t srcX, uint32_t srcY, uint32_t width, uint32_t height,
|
||||
Palette palette, ImportFlags flags, ImportMode mode);
|
||||
static std::vector<uint8_t> EncodeRaw(const int32_t* pixels, uint32_t width, uint32_t height);
|
||||
static std::vector<uint8_t> EncodeRLE(const int32_t* pixels, uint32_t width, uint32_t height);
|
||||
static std::vector<int32_t> GetPixels(const Image& image, const ImageImportMeta& meta);
|
||||
static std::vector<uint8_t> EncodeRaw(const int32_t* pixels, ScreenSize size);
|
||||
static std::vector<uint8_t> EncodeRLE(const int32_t* pixels, ScreenSize size);
|
||||
|
||||
static int32_t CalculatePaletteIndex(
|
||||
ImportMode mode, int16_t* rgbaSrc, int32_t x, int32_t y, int32_t width, int32_t height);
|
||||
|
@ -83,6 +87,9 @@ namespace OpenRCT2::Drawing
|
|||
static PaletteIndexType GetPaletteIndexType(int32_t paletteIndex);
|
||||
static int32_t GetClosestPaletteIndex(const GamePalette& palette, const int16_t* colour);
|
||||
};
|
||||
|
||||
// Note: jsonSprite is deliberately left non-const: json_t behaviour changes when const.
|
||||
ImageImportMeta createImageImportMetaFromJson(json_t& input);
|
||||
} // namespace OpenRCT2::Drawing
|
||||
|
||||
constexpr GamePalette StandardPalette = { {
|
||||
|
|
|
@ -161,9 +161,10 @@ std::vector<std::unique_ptr<ImageTable::RequiredImage>> ImageTable::ParseImages(
|
|||
{
|
||||
auto imageData = context->GetData(s);
|
||||
auto image = Imaging::ReadFromBuffer(imageData);
|
||||
auto meta = ImageImportMeta{};
|
||||
|
||||
ImageImporter importer;
|
||||
auto importResult = importer.Import(image, 0, 0, ImageImporter::Palette::OpenRCT2, ImageImporter::ImportFlags::RLE);
|
||||
auto importResult = importer.Import(image, meta);
|
||||
|
||||
result.push_back(std::make_unique<RequiredImage>(importResult.Element));
|
||||
}
|
||||
|
@ -183,30 +184,11 @@ std::vector<std::unique_ptr<ImageTable::RequiredImage>> ImageTable::ParseImages(
|
|||
Guard::Assert(el.is_object(), "ImageTable::ParseImages expects parameter el to be object");
|
||||
|
||||
auto path = Json::GetString(el["path"]);
|
||||
auto x = Json::GetNumber<int16_t>(el["x"]);
|
||||
auto y = Json::GetNumber<int16_t>(el["y"]);
|
||||
auto srcX = Json::GetNumber<int16_t>(el["srcX"]);
|
||||
auto srcY = Json::GetNumber<int16_t>(el["srcY"]);
|
||||
auto srcWidth = Json::GetNumber<int16_t>(el["srcWidth"]);
|
||||
auto srcHeight = Json::GetNumber<int16_t>(el["srcHeight"]);
|
||||
auto raw = Json::GetString(el["format"]) == "raw";
|
||||
auto keepPalette = Json::GetString(el["palette"]) == "keep";
|
||||
auto zoomOffset = Json::GetNumber<int32_t>(el["zoom"]);
|
||||
auto meta = createImageImportMetaFromJson(el);
|
||||
|
||||
std::vector<std::unique_ptr<RequiredImage>> result;
|
||||
try
|
||||
{
|
||||
auto flags = ImageImporter::ImportFlags::None;
|
||||
auto palette = ImageImporter::Palette::OpenRCT2;
|
||||
if (!raw)
|
||||
{
|
||||
flags = static_cast<ImageImporter::ImportFlags>(flags | ImageImporter::ImportFlags::RLE);
|
||||
}
|
||||
if (keepPalette)
|
||||
{
|
||||
palette = ImageImporter::Palette::KeepIndices;
|
||||
}
|
||||
|
||||
auto itSource = std::find_if(
|
||||
imageSources.begin(), imageSources.end(),
|
||||
[&path](const std::pair<std::string, Image>& item) { return item.first == path; });
|
||||
|
@ -216,16 +198,9 @@ std::vector<std::unique_ptr<ImageTable::RequiredImage>> ImageTable::ParseImages(
|
|||
}
|
||||
auto& image = itSource->second;
|
||||
|
||||
if (srcWidth == 0)
|
||||
srcWidth = image.Width;
|
||||
|
||||
if (srcHeight == 0)
|
||||
srcHeight = image.Height;
|
||||
|
||||
ImageImporter importer;
|
||||
auto importResult = importer.Import(image, srcX, srcY, srcWidth, srcHeight, x, y, palette, flags);
|
||||
auto importResult = importer.Import(image, meta);
|
||||
auto g1element = importResult.Element;
|
||||
g1element.zoomed_offset = zoomOffset;
|
||||
result.push_back(std::make_unique<RequiredImage>(g1element));
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
|
|
|
@ -41,7 +41,8 @@ TEST_F(ImageImporterTests, Import_Logo)
|
|||
|
||||
ImageImporter importer;
|
||||
auto image = Imaging::ReadFromFile(logoPath, IMAGE_FORMAT::PNG_32);
|
||||
auto result = importer.Import(image, 3, 5, ImageImporter::Palette::OpenRCT2, ImageImporter::ImportFlags::RLE);
|
||||
auto meta = ImageImportMeta{ .offset = { 3, 5 } };
|
||||
auto result = importer.Import(image, meta);
|
||||
|
||||
ASSERT_EQ(result.Buffer.data(), result.Element.offset);
|
||||
ASSERT_EQ(128, result.Element.width);
|
||||
|
|
Loading…
Reference in New Issue