aboutsummaryrefslogtreecommitdiff
path: root/image
diff options
context:
space:
mode:
authoryinsimei2017-07-05 19:19:51 +0200
committerEugene Sandulenko2017-07-13 18:27:45 +0200
commit791aedf7a5c347fdfad901ae2054a4c81ef72ca5 (patch)
tree3005914fe6f4b32b6be72790f963e9e0feb29c9d /image
parent874d03f79be2df77db72767e05bc7b019a8a961e (diff)
downloadscummvm-rg350-791aedf7a5c347fdfad901ae2054a4c81ef72ca5.tar.gz
scummvm-rg350-791aedf7a5c347fdfad901ae2054a4c81ef72ca5.tar.bz2
scummvm-rg350-791aedf7a5c347fdfad901ae2054a4c81ef72ca5.zip
Image: extend writePng for 4-byte pixelFormat
Diffstat (limited to 'image')
-rw-r--r--image/png.cpp47
1 files changed, 38 insertions, 9 deletions
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<const uint8 *> 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<uint8 **>(&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;