Allow for bit depth inspection when reading PNGs

This commit is contained in:
Michał Janiszewski 2017-11-03 22:46:40 +01:00 committed by Michał Janiszewski
parent c7b829029c
commit ce9e6e0d85
4 changed files with 43 additions and 23 deletions

View File

@ -32,7 +32,7 @@ namespace Imaging
static void PngWarning(png_structp png_ptr, const char * b);
static void PngError(png_structp png_ptr, const char * b);
bool PngRead(uint8 * * pixels, uint32 * width, uint32 * height, bool expand, const utf8 * path)
bool PngRead(uint8 * * pixels, uint32 * width, uint32 * height, bool expand, const utf8 * path, sint32 * bitDepth)
{
png_structp png_ptr;
png_infop info_ptr;
@ -78,8 +78,8 @@ namespace Imaging
// Read header
png_uint_32 pngWidth, pngHeight;
int bitDepth, colourType, interlaceType;
png_get_IHDR(png_ptr, info_ptr, &pngWidth, &pngHeight, &bitDepth, &colourType, &interlaceType, nullptr, nullptr);
int colourType, interlaceType;
png_get_IHDR(png_ptr, info_ptr, &pngWidth, &pngHeight, bitDepth, &colourType, &interlaceType, nullptr, nullptr);
// Read pixels as 32bpp RGBA data
png_size_t rowBytes = png_get_rowbytes(png_ptr, info_ptr);
@ -102,9 +102,9 @@ namespace Imaging
}
}
}
else if (bitDepth == 8 && !expand)
else if (*bitDepth == 8 && !expand)
{
// 8-bit paletted
// 8-bit paletted or grayscale
Guard::Assert(rowBytes == pngWidth, GUARD_LINE);
for (png_uint_32 i = 0; i < pngHeight; i++)
{
@ -302,9 +302,9 @@ namespace Imaging
extern "C"
{
bool image_io_png_read(uint8 * * pixels, uint32 * width, uint32 * height, bool expand, const utf8 * path)
bool image_io_png_read(uint8 * * pixels, uint32 * width, uint32 * height, bool expand, const utf8 * path, sint32 * bitDepth)
{
return Imaging::PngRead(pixels, width, height, expand, path);
return Imaging::PngRead(pixels, width, height, expand, path, bitDepth);
}
bool image_io_png_write(const rct_drawpixelinfo * dpi, const rct_palette * palette, const utf8 * path)

View File

@ -24,7 +24,7 @@
namespace Imaging
{
bool PngRead(uint8 * * pixels, uint32 * width, uint32 * height, bool expand, const utf8 * path);
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);
}
@ -35,7 +35,7 @@ namespace Imaging
extern "C"
{
#endif
bool image_io_png_read(uint8 * * pixels, uint32 * width, uint32 * height, bool expand, const utf8 * path);
bool image_io_png_read(uint8 * * pixels, uint32 * width, uint32 * height, bool expand, const utf8 * path, sint32 * bitDepth);
bool image_io_png_write(const rct_drawpixelinfo * dpi, const rct_palette * palette, const utf8 * path);
bool image_io_png_write_32bpp(sint32 width, sint32 height, const void * pixels, const utf8 * path);
#ifdef __cplusplus

View File

@ -311,15 +311,23 @@ static bool sprite_file_import(const char *path, sint16 x_offset, sint16 y_offse
{
uint8 *pixels;
uint32 width, height;
if (!image_io_png_read(&pixels, &width, &height, !keep_palette, path))
sint32 bitDepth;
if (!image_io_png_read(&pixels, &width, &height, !keep_palette, path, &bitDepth))
{
fprintf(stderr, "Error reading PNG");
fprintf(stderr, "Error reading PNG\n");
return false;
}
if (width > 256 || height > 256)
{
fprintf(stderr, "Only images 256x256 or less are supported.");
fprintf(stderr, "Only images 256x256 or less are supported.\n");
free(pixels);
return false;
}
if (keep_palette && (bitDepth != 8))
{
fprintf(stderr, "Image is not palletted, it has bit depth of %d\n", bitDepth);
free(pixels);
return false;
}
@ -336,7 +344,8 @@ static bool sprite_file_import(const char *path, sint16 x_offset, sint16 y_offse
sint16 *rgbaSrc_orig = rgbaSrc;
if (!keep_palette)
{
for (uint32 x = 0; x < height * width * 4; x++){
for (uint32 x = 0; x < height * width * 4; x++)
{
rgbaSrc[x] = (sint16) pixels[x];
}
}
@ -380,13 +389,16 @@ static bool sprite_file_import(const char *path, sint16 x_offset, sint16 y_offse
if (mode == MODE_DITHERING)
{
if (!is_transparent_pixel(rgbaSrc) && is_changable_pixel(get_palette_index(rgbaSrc))){
if (!is_transparent_pixel(rgbaSrc) && is_changable_pixel(get_palette_index(rgbaSrc)))
{
sint16 dr = rgbaSrc[0] - (sint16)(spriteFilePalette[paletteIndex].r);
sint16 dg = rgbaSrc[1] - (sint16)(spriteFilePalette[paletteIndex].g);
sint16 db = rgbaSrc[2] - (sint16)(spriteFilePalette[paletteIndex].b);
if (x + 1 < width){
if (!is_transparent_pixel(rgbaSrc + 4) && is_changable_pixel(get_palette_index(rgbaSrc + 4))){
if (x + 1 < width)
{
if (!is_transparent_pixel(rgbaSrc + 4) && is_changable_pixel(get_palette_index(rgbaSrc + 4)))
{
// Right
rgbaSrc[4] += dr * 7 / 16;
rgbaSrc[5] += dg * 7 / 16;
@ -394,9 +406,12 @@ static bool sprite_file_import(const char *path, sint16 x_offset, sint16 y_offse
}
}
if (y + 1 < height){
if (x > 0){
if (!is_transparent_pixel(rgbaSrc + 4 * (width - 1)) && is_changable_pixel(get_palette_index(rgbaSrc + 4 * (width - 1)))){
if (y + 1 < height)
{
if (x > 0)
{
if (!is_transparent_pixel(rgbaSrc + 4 * (width - 1)) && is_changable_pixel(get_palette_index(rgbaSrc + 4 * (width - 1))))
{
// Bottom left
rgbaSrc[4 * (width - 1)] += dr * 3 / 16;
rgbaSrc[4 * (width - 1) + 1] += dg * 3 / 16;
@ -405,14 +420,17 @@ static bool sprite_file_import(const char *path, sint16 x_offset, sint16 y_offse
}
// Bottom
if (!is_transparent_pixel(rgbaSrc + 4 * width) && is_changable_pixel(get_palette_index(rgbaSrc + 4 * width))){
if (!is_transparent_pixel(rgbaSrc + 4 * width) && is_changable_pixel(get_palette_index(rgbaSrc + 4 * width)))
{
rgbaSrc[4 * width] += dr * 5 / 16;
rgbaSrc[4 * width + 1] += dg * 5 / 16;
rgbaSrc[4 * width + 2] += db * 5 / 16;
}
if (x + 1 < width){
if (!is_transparent_pixel(rgbaSrc + 4 * (width - 1)) && is_changable_pixel(get_palette_index(rgbaSrc + 4 * (width + 1)))){
if (x + 1 < width)
{
if (!is_transparent_pixel(rgbaSrc + 4 * (width - 1)) && is_changable_pixel(get_palette_index(rgbaSrc + 4 * (width + 1))))
{
// Bottom right
rgbaSrc[4 * (width + 1)] += dr * 1 / 16;
rgbaSrc[4 * (width + 1) + 1] += dg * 1 / 16;

View File

@ -790,7 +790,9 @@ bool mapgen_load_heightmap(const utf8 *path)
uint32 width, height;
if (strcicmp(extension, ".png") == 0) {
if (!image_io_png_read(&pixels, &width, &height, true, path)) {
sint32 bitDepth;
if (!image_io_png_read(&pixels, &width, &height, true, path, &bitDepth))
{
log_warning("Error reading PNG");
context_show_error(STR_HEIGHT_MAP_ERROR, STR_ERROR_READING_PNG);
return false;