From 791aedf7a5c347fdfad901ae2054a4c81ef72ca5 Mon Sep 17 00:00:00 2001 From: yinsimei Date: Wed, 5 Jul 2017 19:19:51 +0200 Subject: Image: extend writePng for 4-byte pixelFormat --- image/png.cpp | 47 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 9 deletions(-) (limited to 'image/png.cpp') diff --git a/image/png.cpp b/image/png.cpp index e11f0459d2..fc0daf99b5 100644 --- a/image/png.cpp +++ b/image/png.cpp @@ -249,13 +249,35 @@ bool PNGDecoder::loadStream(Common::SeekableReadStream &stream) { bool writePNG(Common::WriteStream &out, const Graphics::Surface &input, const bool bottomUp) { #ifdef USE_PNG - const Graphics::PixelFormat requiredFormat(3, 8, 8, 8, 0, 16, 8, 0, 0); + const Graphics::PixelFormat requiredFormat_3byte(3, 8, 8, 8, 0, 16, 8, 0, 0); + const Graphics::PixelFormat requiredFormat_4byte(4, 8, 8, 8, 8, 16, 8, 0, 24); - if (input.format != requiredFormat) { - warning("Cannot currently write PNG with pixel format other than %s", requiredFormat.toString().c_str()); + if (input.format.bytesPerPixel == 3) { + if (input.format != requiredFormat_3byte) { + warning("Cannot currently write PNG with 3-byte pixel format other than %s", requiredFormat_3byte.toString().c_str()); + return false; + } + } else if (input.format.bytesPerPixel != 4) { + warning("Cannot currently write PNG with pixel format of bpp other than 3, 4"); return false; } + int colorType; + Graphics::Surface *tmp = NULL; + const Graphics::Surface *surface; + + if (input.format == requiredFormat_3byte) { + surface = &input; + colorType = PNG_COLOR_TYPE_RGB; + } else { + if (input.format == requiredFormat_4byte) { + surface = &input; + } else { + surface = tmp = input.convertTo(requiredFormat_4byte); + } + colorType = PNG_COLOR_TYPE_RGB_ALPHA; + } + png_structp pngPtr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!pngPtr) { return false; @@ -276,23 +298,30 @@ bool writePNG(Common::WriteStream &out, const Graphics::Surface &input, const bo png_set_write_fn(pngPtr, &out, pngWriteToStream, pngFlushStream); - png_set_IHDR(pngPtr, infoPtr, input.w, input.h, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + png_set_IHDR(pngPtr, infoPtr, surface->w, surface->h, 8, colorType, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); Common::Array rows; - rows.reserve(input.h); + rows.reserve(surface->h); if (bottomUp) { - for (uint y = input.h; y-- > 0;) { - rows.push_back((const uint8 *)input.getBasePtr(0, y)); + for (uint y = surface->h; y-- > 0;) { + rows.push_back((const uint8 *)surface->getBasePtr(0, y)); } } else { - for (uint y = 0; y < input.h; ++y) { - rows.push_back((const uint8 *)input.getBasePtr(0, y)); + for (uint y = 0; y < surface->h; ++y) { + rows.push_back((const uint8 *)surface->getBasePtr(0, y)); } } png_set_rows(pngPtr, infoPtr, const_cast(&rows.front())); png_write_png(pngPtr, infoPtr, 0, NULL); png_destroy_write_struct(&pngPtr, &infoPtr); + + // free tmp surface + if (tmp) { + tmp->free(); + delete tmp; + } + return true; #else return false; -- cgit v1.2.3