Change consumers to use new imaging API

This commit is contained in:
Ted John 2018-05-08 21:41:41 +01:00
parent 766997f15c
commit ac3233b819
5 changed files with 128 additions and 82 deletions

View File

@ -233,10 +233,23 @@ static bool sprite_file_export(sint32 spriteIndex, const char *outPath)
gfx_bmp_sprite_to_buffer((uint8*)spriteFilePalette, spriteHeader->offset, pixels, spriteHeader, &dpi, spriteHeader->height, spriteHeader->width, IMAGE_TYPE_DEFAULT);
}
if (Imaging::PngWrite(&dpi, (rct_palette*)spriteFilePalette, outPath)) {
auto const pixels8 = dpi.bits;
auto const pixelsLen = (dpi.width + dpi.pitch) * dpi.height;
try
{
Image image;
image.Width = dpi.width;
image.Height = dpi.height;
image.Depth = 8;
image.Stride = dpi.width + dpi.pitch;
image.Palette = std::make_unique<rct_palette>(*((rct_palette *)&spriteFilePalette));
image.Pixels = std::vector<uint8>(pixels8, pixels8 + pixelsLen);
Imaging::WriteToFile(outPath, image, IMAGE_FORMAT::PNG);
return true;
} else {
fprintf(stderr, "Error writing PNG");
}
catch (const std::exception& e)
{
fprintf(stderr, "Unable to write png: %s", e.what());
return false;
}
}
@ -300,29 +313,34 @@ static sint32 get_palette_index(sint16 *colour)
static bool sprite_file_import(const char *path, sint16 x_offset, sint16 y_offset, bool keep_palette, rct_g1_element *outElement, uint8 **outBuffer, int *outBufferLength, sint32 mode)
{
uint8 *pixels;
uint32 width, height;
sint32 bitDepth;
if (!Imaging::PngRead(&pixels, &width, &height, !keep_palette, path, &bitDepth))
Image image;
auto format = keep_palette ? IMAGE_FORMAT::PNG : IMAGE_FORMAT::PNG_32;
try
{
fprintf(stderr, "Error reading PNG\n");
image = std::move(Imaging::ReadFromFile(path, format));
}
catch (const std::exception &e)
{
fprintf(stderr, "Error reading PNG: %s\n", e.what());
return false;
}
if (width > 256 || height > 256)
if (image.Width > 256 || image.Height > 256)
{
fprintf(stderr, "Only images 256x256 or less are supported.\n");
free(pixels);
return false;
}
if (keep_palette && (bitDepth != 8))
if (keep_palette && (image.Depth != 8))
{
fprintf(stderr, "Image is not palletted, it has bit depth of %d\n", bitDepth);
free(pixels);
fprintf(stderr, "Image is not palletted, it has bit depth of %d\n", image.Depth);
return false;
}
const auto width = image.Width;
const auto height = image.Height;
const auto pixels = image.Pixels.data();
memcpy(spriteFilePalette, CmdlineSprite::_standardPalette, 256 * 4);
uint8 *buffer = (uint8 *)malloc((height * 2) + (width * height * 16));
@ -497,7 +515,6 @@ static bool sprite_file_import(const char *path, sint16 x_offset, sint16 y_offse
}
}
}
free(pixels);
free(rgbaSrc_orig);
sint32 bufferLength = (sint32)(dst - buffer);

View File

@ -277,7 +277,7 @@ namespace Imaging
}
}
static IMAGE_FORMAT GetImageFormatFromPath(const std::string_view& path)
IMAGE_FORMAT GetImageFormatFromPath(const std::string_view& path)
{
if (String::EndsWith(path, ".png", true))
{

View File

@ -49,11 +49,8 @@ struct Image
namespace Imaging
{
IMAGE_FORMAT GetImageFormatFromPath(const std::string_view& path);
Image ReadFromFile(const std::string_view& path, IMAGE_FORMAT format = IMAGE_FORMAT::AUTOMATIC);
Image ReadFromBuffer(const std::vector<uint8>& buffer, IMAGE_FORMAT format = IMAGE_FORMAT::AUTOMATIC);
void WriteToFile(const std::string_view& path, const Image& image, IMAGE_FORMAT format = IMAGE_FORMAT::AUTOMATIC);
bool PngRead(uint8 * * pixels, uint32 * width, uint32 * height, bool expand, const utf8 * path, sint32 * bitDepth);
bool PngWrite(const rct_drawpixelinfo * dpi, const rct_palette * palette, const utf8 * path);
bool PngWrite32bpp(sint32 width, sint32 height, const void * pixels, const utf8 * path);
}

View File

@ -41,6 +41,29 @@ using namespace OpenRCT2;
uint8 gScreenshotCountdown = 0;
static bool WriteDpiToFile(const std::string_view& path, const rct_drawpixelinfo * dpi, const rct_palette& palette)
{
auto const pixels8 = dpi->bits;
auto const pixelsLen = (dpi->width + dpi->pitch) * dpi->height;
try
{
Image image;
image.Width = dpi->width;
image.Height = dpi->height;
image.Depth = 8;
image.Stride = dpi->width + dpi->pitch;
image.Palette = std::make_unique<rct_palette>(palette);
image.Pixels = std::vector<uint8>(pixels8, pixels8 + pixelsLen);
Imaging::WriteToFile(path, image, IMAGE_FORMAT::PNG);
return true;
}
catch (const std::exception& e)
{
log_error("Unable to write png: %s", e.what());
return false;
}
}
/**
*
* rct2: 0x006E3AEC
@ -153,9 +176,12 @@ sint32 screenshot_dump_png(rct_drawpixelinfo *dpi)
rct_palette renderedPalette;
screenshot_get_rendered_palette(&renderedPalette);
if (Imaging::PngWrite(dpi, &renderedPalette, path)) {
if (WriteDpiToFile(path, dpi, renderedPalette))
{
return index;
} else {
}
else
{
return -1;
}
}
@ -169,9 +195,23 @@ sint32 screenshot_dump_png_32bpp(sint32 width, sint32 height, const void *pixels
return -1;
}
if (Imaging::PngWrite32bpp(width, height, pixels, path)) {
const auto pixels8 = (const uint8 *)pixels;
const auto pixelsLen = width * 4 * height;
try
{
Image image;
image.Width = width;
image.Height = height;
image.Depth = 32;
image.Stride = width * 4;
image.Pixels = std::vector<uint8>(pixels8, pixels8 + pixelsLen);
Imaging::WriteToFile(path, image, IMAGE_FORMAT::PNG_32);
return index;
} else {
}
catch (const std::exception &e)
{
log_error("Unable to save screenshot: %s", e.what());
return -1;
}
}
@ -259,7 +299,7 @@ void screenshot_giant()
rct_palette renderedPalette;
screenshot_get_rendered_palette(&renderedPalette);
Imaging::PngWrite(&dpi, &renderedPalette, path);
WriteDpiToFile(path, &dpi, renderedPalette);
free(dpi.bits);
@ -576,7 +616,7 @@ sint32 cmdline_for_screenshot(const char * * argv, sint32 argc, ScreenshotOption
rct_palette renderedPalette;
screenshot_get_rendered_palette(&renderedPalette);
Imaging::PngWrite(&dpi, &renderedPalette, outputPath);
WriteDpiToFile(outputPath, &dpi, renderedPalette);
free(dpi.bits);
drawing_engine_dispose();

View File

@ -647,75 +647,67 @@ static void mapgen_simplex(mapgen_settings * settings)
bool mapgen_load_heightmap(const utf8 * path)
{
const char * extension = path_get_extension(path);
uint8 * pixels;
size_t pitch;
uint32 numChannels;
uint32 width, height;
if (String::Equals(extension, ".png", false))
auto format = Imaging::GetImageFormatFromPath(path);
if (format == IMAGE_FORMAT::PNG)
{
sint32 bitDepth;
if (!Imaging::PngRead(&pixels, &width, &height, true, path, &bitDepth))
// Promote to 32-bit
format = IMAGE_FORMAT::PNG_32;
}
try
{
auto image = Imaging::ReadFromFile(path, format);
if (image.Width != image.Height)
{
log_warning("Error reading PNG");
context_show_error(STR_HEIGHT_MAP_ERROR, STR_ERROR_READING_PNG);
context_show_error(STR_HEIGHT_MAP_ERROR, STR_ERROR_WIDTH_AND_HEIGHT_DO_NOT_MATCH);
return false;
}
numChannels = 4;
pitch = width * numChannels;
}
else if (strcicmp(extension, ".bmp") == 0)
{
if (!context_read_bmp((void **) &pixels, &width, &height, path))
auto size = image.Width;
if (image.Width > MAXIMUM_MAP_SIZE_PRACTICAL)
{
// ReadBMP contains context_show_error calls
return false;
context_show_error(STR_HEIGHT_MAP_ERROR, STR_ERROR_HEIHGT_MAP_TOO_BIG);
size = std::min<uint32>(image.Height, MAXIMUM_MAP_SIZE_PRACTICAL);
}
numChannels = 4;
pitch = width * numChannels;
}
else
{
openrct2_assert(false, "A file with an invalid file extension was selected.");
return false;
}
// Allocate memory for the height map values, one byte pixel
delete[] _heightMapData.mono_bitmap;
_heightMapData.mono_bitmap = new uint8[size * size];
_heightMapData.width = size;
_heightMapData.height = size;
if (width != height)
{
context_show_error(STR_HEIGHT_MAP_ERROR, STR_ERROR_WIDTH_AND_HEIGHT_DO_NOT_MATCH);
free(pixels);
return false;
}
if (width > MAXIMUM_MAP_SIZE_PRACTICAL)
{
context_show_error(STR_HEIGHT_MAP_ERROR, STR_ERROR_HEIHGT_MAP_TOO_BIG);
width = height = Math::Min(height, (uint32)MAXIMUM_MAP_SIZE_PRACTICAL);
}
// Allocate memory for the height map values, one byte pixel
delete[] _heightMapData.mono_bitmap;
_heightMapData.mono_bitmap = new uint8[width * height];
_heightMapData.width = width;
_heightMapData.height = height;
// Copy average RGB value to mono bitmap
for (uint32 x = 0; x < _heightMapData.width; x++)
{
for (uint32 y = 0; y < _heightMapData.height; y++)
// Copy average RGB value to mono bitmap
constexpr auto numChannels = 4;
const auto pitch = image.Stride;
const auto pixels = image.Pixels.data();
for (uint32 x = 0; x < _heightMapData.width; x++)
{
const uint8 red = pixels[x * numChannels + y * pitch];
const uint8 green = pixels[x * numChannels + y * pitch + 1];
const uint8 blue = pixels[x * numChannels + y * pitch + 2];
_heightMapData.mono_bitmap[x + y * _heightMapData.width] = (red + green + blue) / 3;
for (uint32 y = 0; y < _heightMapData.height; y++)
{
const auto red = pixels[x * numChannels + y * pitch];
const auto green = pixels[x * numChannels + y * pitch + 1];
const auto blue = pixels[x * numChannels + y * pitch + 2];
_heightMapData.mono_bitmap[x + y * _heightMapData.width] = (red + green + blue) / 3;
}
}
return true;
}
catch (const std::exception& e)
{
switch (format)
{
case IMAGE_FORMAT::BITMAP:
context_show_error(STR_HEIGHT_MAP_ERROR, STR_ERROR_READING_BITMAP);
break;
case IMAGE_FORMAT::PNG_32:
context_show_error(STR_HEIGHT_MAP_ERROR, STR_ERROR_READING_PNG);
break;
default:
log_error("Unable to load height map image: %s", e.what());
break;
}
return false;
}
free(pixels);
return true;
}
/**