mirror of
https://github.com/OpenRCT2/OpenRCT2.git
synced 2025-01-23 02:41:58 -05:00
Clean up palette import
This commit is contained in:
parent
63ed6c99a5
commit
1062c3d08d
7 changed files with 44 additions and 31 deletions
|
@ -225,7 +225,8 @@ static bool SpriteImageExport(const rct_g1_element& spriteElement, const char* o
|
|||
}
|
||||
|
||||
static std::optional<ImageImporter::ImportResult> SpriteImageImport(
|
||||
const char* path, int16_t x_offset, int16_t y_offset, bool keep_palette, bool forceBmp, int32_t mode)
|
||||
const char* path, int16_t x_offset, int16_t y_offset, ImageImporter::PALETTE palette, bool forceBmp,
|
||||
ImageImporter::IMPORT_MODE mode)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -237,16 +238,15 @@ static std::optional<ImageImporter::ImportResult> SpriteImageImport(
|
|||
flags = ImageImporter::IMPORT_FLAGS::RLE;
|
||||
}
|
||||
|
||||
if (keep_palette)
|
||||
if (palette == ImageImporter::PALETTE::KEEP_INDICES)
|
||||
{
|
||||
format = IMAGE_FORMAT::PNG;
|
||||
flags = static_cast<ImageImporter::IMPORT_FLAGS>(flags | ImageImporter::IMPORT_FLAGS::KEEP_PALETTE);
|
||||
}
|
||||
|
||||
ImageImporter importer;
|
||||
auto image = Imaging::ReadFromFile(path, format);
|
||||
|
||||
return importer.Import(image, x_offset, y_offset, flags, static_cast<ImageImporter::IMPORT_MODE>(mode));
|
||||
return importer.Import(image, x_offset, y_offset, palette, flags, mode);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
|
@ -549,7 +549,8 @@ int32_t cmdline_for_sprite(const char** argv, int32_t argc)
|
|||
}
|
||||
}
|
||||
|
||||
auto importResult = SpriteImageImport(imagePath, x_offset, y_offset, false, false, gSpriteMode);
|
||||
auto importResult = SpriteImageImport(
|
||||
imagePath, x_offset, y_offset, ImageImporter::PALETTE::OPENRCT2, false, gSpriteMode);
|
||||
if (!importResult.has_value())
|
||||
return -1;
|
||||
|
||||
|
@ -625,14 +626,15 @@ int32_t cmdline_for_sprite(const char** argv, int32_t argc)
|
|||
json_t x_offset = jsonSprite["x_offset"];
|
||||
json_t y_offset = jsonSprite["y_offset"];
|
||||
|
||||
bool keep_palette = Json::GetString(jsonSprite["palette"]) == "keep";
|
||||
auto palette = (Json::GetString(jsonSprite["palette"]) == "keep") ? ImageImporter::PALETTE::KEEP_INDICES
|
||||
: ImageImporter::PALETTE::OPENRCT2;
|
||||
bool forceBmp = !jsonSprite["palette"].is_null() && Json::GetBoolean(jsonSprite["forceBmp"]);
|
||||
|
||||
auto imagePath = Path::GetAbsolute(std::string(directoryPath) + "/" + strPath);
|
||||
|
||||
auto importResult = SpriteImageImport(
|
||||
imagePath.c_str(), Json::GetNumber<int16_t>(x_offset), Json::GetNumber<int16_t>(y_offset), keep_palette,
|
||||
forceBmp, gSpriteMode);
|
||||
imagePath.c_str(), Json::GetNumber<int16_t>(x_offset), Json::GetNumber<int16_t>(y_offset), palette, forceBmp,
|
||||
gSpriteMode);
|
||||
if (importResult == std::nullopt)
|
||||
{
|
||||
fprintf(stderr, "Could not import image file: %s\nCanceling\n", imagePath.c_str());
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "common.h"
|
||||
#include "drawing/ImageImporter.h"
|
||||
|
||||
int32_t cmdline_for_sprite(const char** argv, int32_t argc);
|
||||
extern int32_t gSpriteMode;
|
||||
extern OpenRCT2::Drawing::ImageImporter::IMPORT_MODE gSpriteMode;
|
||||
|
|
|
@ -16,7 +16,9 @@
|
|||
#define SZ_CLOSEST "closest"
|
||||
#define SZ_DITHERING "dithering"
|
||||
|
||||
int32_t gSpriteMode = 0;
|
||||
using IMPORT_MODE = OpenRCT2::Drawing::ImageImporter::IMPORT_MODE;
|
||||
|
||||
IMPORT_MODE gSpriteMode = IMPORT_MODE::DEFAULT;
|
||||
|
||||
static const char* _mode;
|
||||
|
||||
|
@ -47,9 +49,9 @@ const CommandLineCommand CommandLine::SpriteCommands[]
|
|||
static exitcode_t HandleSprite(CommandLineArgEnumerator* argEnumerator)
|
||||
{
|
||||
if (String::Equals(_mode, SZ_CLOSEST, true))
|
||||
gSpriteMode = 1;
|
||||
gSpriteMode = IMPORT_MODE::CLOSEST;
|
||||
else if (String::Equals(_mode, SZ_DITHERING, true))
|
||||
gSpriteMode = 2;
|
||||
gSpriteMode = IMPORT_MODE::DITHERING;
|
||||
Memory::Free(_mode);
|
||||
|
||||
const char** argv = const_cast<const char**>(argEnumerator->GetArguments()) + argEnumerator->GetIndex() - 1;
|
||||
|
|
|
@ -21,26 +21,26 @@ using ImportResult = ImageImporter::ImportResult;
|
|||
constexpr int32_t PALETTE_TRANSPARENT = -1;
|
||||
|
||||
ImportResult ImageImporter::Import(
|
||||
const Image& image, int32_t offsetX, int32_t offsetY, IMPORT_FLAGS flags, IMPORT_MODE mode) const
|
||||
const Image& image, int32_t offsetX, int32_t offsetY, PALETTE palette, IMPORT_FLAGS flags, IMPORT_MODE mode) const
|
||||
{
|
||||
return Import(image, 0, 0, image.Width, image.Height, offsetX, offsetY, flags, mode);
|
||||
return Import(image, 0, 0, image.Width, image.Height, offsetX, offsetY, palette, flags, mode);
|
||||
}
|
||||
|
||||
ImportResult ImageImporter::Import(
|
||||
const Image& image, int32_t srcX, int32_t srcY, int32_t width, int32_t height, int32_t offsetX, int32_t offsetY,
|
||||
IMPORT_FLAGS flags, IMPORT_MODE mode) const
|
||||
PALETTE palette, IMPORT_FLAGS flags, IMPORT_MODE mode) const
|
||||
{
|
||||
if (width > 256 || height > 256)
|
||||
{
|
||||
throw std::invalid_argument("Only images 256x256 or less are supported.");
|
||||
}
|
||||
|
||||
if ((flags & IMPORT_FLAGS::KEEP_PALETTE) && image.Depth != 8)
|
||||
if (palette == PALETTE::KEEP_INDICES && image.Depth != 8)
|
||||
{
|
||||
throw std::invalid_argument("Image is not paletted, it has bit depth of " + std::to_string(image.Depth));
|
||||
}
|
||||
|
||||
auto pixels = GetPixels(image.Pixels.data(), image.Stride, srcX, srcY, width, height, flags, mode);
|
||||
auto pixels = GetPixels(image.Pixels.data(), image.Stride, srcX, srcY, width, height, palette, flags, mode);
|
||||
auto buffer = flags & IMPORT_FLAGS::RLE ? EncodeRLE(pixels.data(), width, height) : EncodeRaw(pixels.data(), width, height);
|
||||
|
||||
rct_g1_element outElement;
|
||||
|
@ -59,8 +59,8 @@ ImportResult ImageImporter::Import(
|
|||
}
|
||||
|
||||
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, IMPORT_FLAGS flags,
|
||||
IMPORT_MODE mode)
|
||||
const uint8_t* pixels, uint32_t pitch, uint32_t srcX, uint32_t srcY, uint32_t width, uint32_t height, PALETTE palette,
|
||||
IMPORT_FLAGS flags, IMPORT_MODE mode)
|
||||
{
|
||||
std::vector<int32_t> buffer;
|
||||
buffer.reserve(width * height);
|
||||
|
@ -68,13 +68,13 @@ std::vector<int32_t> ImageImporter::GetPixels(
|
|||
// A larger range is needed for proper dithering
|
||||
auto palettedSrc = pixels;
|
||||
std::unique_ptr<int16_t[]> rgbaSrcBuffer;
|
||||
if (!(flags & IMPORT_FLAGS::KEEP_PALETTE))
|
||||
if (palette != PALETTE::KEEP_INDICES)
|
||||
{
|
||||
rgbaSrcBuffer = std::make_unique<int16_t[]>(height * width * 4);
|
||||
}
|
||||
|
||||
auto rgbaSrc = rgbaSrcBuffer.get();
|
||||
if (!(flags & IMPORT_FLAGS::KEEP_PALETTE))
|
||||
if (palette != PALETTE::KEEP_INDICES)
|
||||
{
|
||||
auto src = pixels + (srcY * pitch) + (srcX * 4);
|
||||
auto dst = rgbaSrc;
|
||||
|
@ -90,7 +90,7 @@ std::vector<int32_t> ImageImporter::GetPixels(
|
|||
}
|
||||
}
|
||||
|
||||
if (flags & IMPORT_FLAGS::KEEP_PALETTE)
|
||||
if (palette == PALETTE::KEEP_INDICES)
|
||||
{
|
||||
palettedSrc += srcX + srcY * pitch;
|
||||
for (uint32_t y = 0; y < height; y++)
|
||||
|
|
|
@ -41,16 +41,22 @@ namespace OpenRCT2::Drawing
|
|||
enum IMPORT_FLAGS
|
||||
{
|
||||
NONE = 0,
|
||||
KEEP_PALETTE = 1 << 0,
|
||||
RLE = 1 << 1,
|
||||
};
|
||||
|
||||
enum class PALETTE : uint8_t
|
||||
{
|
||||
OPENRCT2,
|
||||
KEEP_INDICES,
|
||||
};
|
||||
|
||||
ImportResult Import(
|
||||
const Image& image, int32_t srcX, int32_t srcY, int32_t width, int32_t height, int32_t offsetX, int32_t offsetY,
|
||||
IMPORT_FLAGS flags = IMPORT_FLAGS::NONE, IMPORT_MODE mode = IMPORT_MODE::DEFAULT) const;
|
||||
ImportResult Import(
|
||||
const Image& image, int32_t offsetX = 0, int32_t offsetY = 0, IMPORT_FLAGS flags = IMPORT_FLAGS::NONE,
|
||||
PALETTE palette = PALETTE::OPENRCT2, IMPORT_FLAGS flags = IMPORT_FLAGS::NONE,
|
||||
IMPORT_MODE mode = IMPORT_MODE::DEFAULT) const;
|
||||
ImportResult Import(
|
||||
const Image& image, int32_t offsetX = 0, int32_t offsetY = 0, PALETTE palette = PALETTE::OPENRCT2,
|
||||
IMPORT_FLAGS flags = IMPORT_FLAGS::NONE, IMPORT_MODE mode = IMPORT_MODE::DEFAULT) const;
|
||||
|
||||
private:
|
||||
enum class PaletteIndexType : uint8_t
|
||||
|
@ -64,7 +70,7 @@ namespace OpenRCT2::Drawing
|
|||
|
||||
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,
|
||||
IMPORT_FLAGS flags, IMPORT_MODE mode);
|
||||
PALETTE palette, IMPORT_FLAGS flags, IMPORT_MODE 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);
|
||||
|
||||
|
|
|
@ -145,7 +145,8 @@ std::vector<std::unique_ptr<ImageTable::RequiredImage>> ImageTable::ParseImages(
|
|||
auto image = Imaging::ReadFromBuffer(imageData);
|
||||
|
||||
ImageImporter importer;
|
||||
auto importResult = importer.Import(image, 0, 0, ImageImporter::IMPORT_FLAGS::RLE);
|
||||
auto importResult = importer.Import(
|
||||
image, 0, 0, ImageImporter::PALETTE::OPENRCT2, ImageImporter::IMPORT_FLAGS::RLE);
|
||||
|
||||
result.push_back(std::make_unique<RequiredImage>(importResult.Element));
|
||||
}
|
||||
|
@ -179,13 +180,14 @@ std::vector<std::unique_ptr<ImageTable::RequiredImage>> ImageTable::ParseImages(
|
|||
try
|
||||
{
|
||||
auto flags = ImageImporter::IMPORT_FLAGS::NONE;
|
||||
auto palette = ImageImporter::PALETTE::OPENRCT2;
|
||||
if (!raw)
|
||||
{
|
||||
flags = static_cast<ImageImporter::IMPORT_FLAGS>(flags | ImageImporter::IMPORT_FLAGS::RLE);
|
||||
}
|
||||
if (keepPalette)
|
||||
{
|
||||
flags = static_cast<ImageImporter::IMPORT_FLAGS>(flags | ImageImporter::IMPORT_FLAGS::KEEP_PALETTE);
|
||||
palette = ImageImporter::PALETTE::KEEP_INDICES;
|
||||
}
|
||||
|
||||
auto itSource = std::find_if(
|
||||
|
@ -204,7 +206,7 @@ std::vector<std::unique_ptr<ImageTable::RequiredImage>> ImageTable::ParseImages(
|
|||
srcHeight = image.Height;
|
||||
|
||||
ImageImporter importer;
|
||||
auto importResult = importer.Import(image, srcX, srcY, srcWidth, srcHeight, x, y, flags);
|
||||
auto importResult = importer.Import(image, srcX, srcY, srcWidth, srcHeight, x, y, palette, flags);
|
||||
auto g1element = importResult.Element;
|
||||
g1element.zoomed_offset = zoomOffset;
|
||||
result.push_back(std::make_unique<RequiredImage>(g1element));
|
||||
|
|
|
@ -41,7 +41,7 @@ TEST_F(ImageImporterTests, Import_Logo)
|
|||
|
||||
ImageImporter importer;
|
||||
auto image = Imaging::ReadFromFile(logoPath, IMAGE_FORMAT::PNG_32);
|
||||
auto result = importer.Import(image, 3, 5, ImageImporter::IMPORT_FLAGS::RLE);
|
||||
auto result = importer.Import(image, 3, 5, ImageImporter::PALETTE::OPENRCT2, ImageImporter::IMPORT_FLAGS::RLE);
|
||||
|
||||
ASSERT_EQ(result.Buffer.data(), result.Element.offset);
|
||||
ASSERT_EQ(128, result.Element.width);
|
||||
|
|
Loading…
Reference in a new issue