diff options
Diffstat (limited to 'engines/sword25/gfx/image')
-rw-r--r-- | engines/sword25/gfx/image/imgloader.cpp | 85 | ||||
-rw-r--r-- | engines/sword25/gfx/image/imgloader.h (renamed from engines/sword25/gfx/image/pngloader.h) | 39 | ||||
-rw-r--r-- | engines/sword25/gfx/image/pngloader.cpp | 245 | ||||
-rw-r--r-- | engines/sword25/gfx/image/renderedimage.cpp | 52 | ||||
-rw-r--r-- | engines/sword25/gfx/image/swimage.cpp | 12 |
5 files changed, 102 insertions, 331 deletions
diff --git a/engines/sword25/gfx/image/imgloader.cpp b/engines/sword25/gfx/image/imgloader.cpp new file mode 100644 index 0000000000..1df0fba70c --- /dev/null +++ b/engines/sword25/gfx/image/imgloader.cpp @@ -0,0 +1,85 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* + * This code is based on Broken Sword 2.5 engine + * + * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer + * + * Licensed under GNU GPL v2 + * + */ + +#include "common/memstream.h" +#include "sword25/gfx/image/image.h" +#include "sword25/gfx/image/imgloader.h" +#include "graphics/pixelformat.h" +#include "graphics/png.h" + +namespace Sword25 { + +bool ImgLoader::decodePNGImage(const byte *fileDataPtr, uint fileSize, byte *&uncompressedDataPtr, int &width, int &height, int &pitch) { + Common::MemoryReadStream *fileStr = new Common::MemoryReadStream(fileDataPtr, fileSize, DisposeAfterUse::NO); + Graphics::PNG *png = new Graphics::PNG(); + if (!png->read(fileStr)) // the fileStr pointer, and thus pFileData will be deleted after this is done + error("Error while reading PNG image"); + + Graphics::PixelFormat format = Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24); + Graphics::Surface *pngSurface = png->getSurface(format); + + width = pngSurface->w; + height = pngSurface->h; + uncompressedDataPtr = new byte[pngSurface->pitch * pngSurface->h]; + memcpy(uncompressedDataPtr, (byte *)pngSurface->pixels, pngSurface->pitch * pngSurface->h); + pngSurface->free(); + + delete pngSurface; + delete png; + + // Signal success + return true; +} + +bool ImgLoader::decodeThumbnailImage(const byte *pFileData, uint fileSize, byte *&pUncompressedData, int &width, int &height, int &pitch) { + const byte *src = pFileData + 4; // skip header + width = READ_LE_UINT16(src); src += 2; + height = READ_LE_UINT16(src); src += 2; + src++; // version, ignored for now + pitch = width * 4; + + uint32 totalSize = pitch * height; + pUncompressedData = new byte[totalSize]; + uint32 *dst = (uint32 *)pUncompressedData; // treat as uint32, for pixelformat output + const Graphics::PixelFormat format = Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24); + byte r, g, b; + + for (uint32 i = 0; i < totalSize / 4; i++) { + r = *src++; + g = *src++; + b = *src++; + *dst++ = format.RGBToColor(r, g, b); + } + + return true; +} + +} // End of namespace Sword25 diff --git a/engines/sword25/gfx/image/pngloader.h b/engines/sword25/gfx/image/imgloader.h index 6b5f65ff57..735ab9203c 100644 --- a/engines/sword25/gfx/image/pngloader.h +++ b/engines/sword25/gfx/image/imgloader.h @@ -29,30 +29,22 @@ * */ -#ifndef SWORD25_PNGLOADER2_H -#define SWORD25_PNGLOADER2_H +#ifndef SWORD25_IMGLOADER_H +#define SWORD25_IMGLOADER_H #include "sword25/kernel/common.h" #include "sword25/gfx/graphicengine.h" namespace Sword25 { -// Define to use ScummVM's PNG decoder, instead of libpng -#define USE_INTERNAL_PNG_DECODER - /** * Class for loading PNG files, and PNG data embedded into savegames. * * Originally written by Malte Thiesen. */ -class PNGLoader { +class ImgLoader { protected: - PNGLoader() {} // Protected constructor to prevent instances - - static bool doDecodeImage(const byte *fileDataPtr, uint fileSize, byte *&uncompressedDataPtr, int &width, int &height, int &pitch); -#ifndef USE_INTERNAL_PNG_DECODER - static bool doImageProperties(const byte *fileDataPtr, uint fileSize, int &width, int &height); -#endif + ImgLoader() {} // Protected constructor to prevent instances public: @@ -70,28 +62,15 @@ public: * @remark This function does not free the image buffer passed to it, * it is the callers responsibility to do so. */ - static bool decodeImage(const byte *pFileData, uint fileSize, + static bool decodePNGImage(const byte *pFileData, uint fileSize, byte *&pUncompressedData, int &width, int &height, int &pitch); -#ifndef USE_INTERNAL_PNG_DECODER - /** - * Extract the properties of an image. - * @param[in] fileDatePtr pointer to the image data - * @param[in] fileSize size of the image data in bytes - * @param[out] width if successful, this is set to the width of the image - * @param[out] height if successful, this is set to the height of the image - * @return returns true if extraction of the properties was successful, false in case of an error - * - * @remark This function does not free the image buffer passed to it, - * it is the callers responsibility to do so. - */ - static bool imageProperties(const byte *fileDatePtr, uint fileSize, - int &width, - int &height); -#endif - + static bool decodeThumbnailImage(const byte *pFileData, uint fileSize, + byte *&pUncompressedData, + int &width, int &height, + int &pitch); }; } // End of namespace Sword25 diff --git a/engines/sword25/gfx/image/pngloader.cpp b/engines/sword25/gfx/image/pngloader.cpp deleted file mode 100644 index 6f370d8861..0000000000 --- a/engines/sword25/gfx/image/pngloader.cpp +++ /dev/null @@ -1,245 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -/* - * This code is based on Broken Sword 2.5 engine - * - * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer - * - * Licensed under GNU GPL v2 - * - */ - -#ifndef USE_INTERNAL_PNG_DECODER -// Disable symbol overrides so that we can use png.h -#define FORBIDDEN_SYMBOL_ALLOW_ALL -#endif - -#include "common/memstream.h" -#include "sword25/gfx/image/image.h" -#include "sword25/gfx/image/pngloader.h" -#ifndef USE_INTERNAL_PNG_DECODER -#include <png.h> -#else -#include "graphics/pixelformat.h" -#include "graphics/png.h" -#endif - -namespace Sword25 { - -#ifndef USE_INTERNAL_PNG_DECODER -static void png_user_read_data(png_structp png_ptr, png_bytep data, png_size_t length) { - const byte **ref = (const byte **)png_get_io_ptr(png_ptr); - memcpy(data, *ref, length); - *ref += length; -} - -static bool doIsCorrectImageFormat(const byte *fileDataPtr, uint fileSize) { - return (fileSize > 8) && png_check_sig(const_cast<byte *>(fileDataPtr), 8); -} -#endif - -bool PNGLoader::doDecodeImage(const byte *fileDataPtr, uint fileSize, byte *&uncompressedDataPtr, int &width, int &height, int &pitch) { -#ifndef USE_INTERNAL_PNG_DECODER - png_structp png_ptr = NULL; - png_infop info_ptr = NULL; - - int bitDepth; - int colorType; - int interlaceType; - int i; - - // Check for valid PNG signature - if (!doIsCorrectImageFormat(fileDataPtr, fileSize)) { - error("png_check_sig failed"); - } - - // Create both PNG structures - png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - if (!png_ptr) { - error("Could not create libpng read struct."); - } - - info_ptr = png_create_info_struct(png_ptr); - if (!info_ptr) { - error("Could not create libpng info struct."); - } - - // Use alternative reading function - const byte **ref = &fileDataPtr; - png_set_read_fn(png_ptr, (void *)ref, png_user_read_data); - - // Read PNG header - png_read_info(png_ptr, info_ptr); - - // Read out PNG informations - - png_uint_32 w, h; - png_get_IHDR(png_ptr, info_ptr, &w, &h, &bitDepth, &colorType, &interlaceType, NULL, NULL); - width = w; - height = h; - - // Calculate pitch of output image - pitch = GraphicEngine::calcPitch(GraphicEngine::CF_ARGB32, width); - - // Allocate memory for the final image data. - // To keep memory framentation low this happens before allocating memory for temporary image data. - uncompressedDataPtr = new byte[pitch * height]; - if (!uncompressedDataPtr) { - error("Could not allocate memory for output image."); - } - - // Images of all color formates will be transformed into ARGB images - if (bitDepth == 16) - png_set_strip_16(png_ptr); - if (colorType == PNG_COLOR_TYPE_PALETTE) - png_set_expand(png_ptr); - if (bitDepth < 8) - png_set_expand(png_ptr); - if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) - png_set_expand(png_ptr); - if (colorType == PNG_COLOR_TYPE_GRAY || - colorType == PNG_COLOR_TYPE_GRAY_ALPHA) - png_set_gray_to_rgb(png_ptr); - - png_set_bgr(png_ptr); - - if (colorType != PNG_COLOR_TYPE_RGB_ALPHA) - png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER); - - // After the transformations have been registered, the image data is read again. - png_read_update_info(png_ptr, info_ptr); - png_get_IHDR(png_ptr, info_ptr, &w, &h, &bitDepth, &colorType, NULL, NULL, NULL); - width = w; - height = h; - - if (interlaceType == PNG_INTERLACE_NONE) { - // PNGs without interlacing can simply be read row by row. - for (i = 0; i < height; i++) { - png_read_row(png_ptr, uncompressedDataPtr + i * pitch, NULL); - } - } else { - // PNGs with interlacing require us to allocate an auxillary - // buffer with pointers to all row starts. - - // Allocate row pointer buffer - png_bytep *pRowPtr = new png_bytep[height]; - if (!pRowPtr) { - error("Could not allocate memory for row pointers."); - } - - // Initialize row pointers - for (i = 0; i < height; i++) - pRowPtr[i] = uncompressedDataPtr + i * pitch; - - // Read image data - png_read_image(png_ptr, pRowPtr); - - // Free row pointer buffer - delete[] pRowPtr; - } - - // Read additional data at the end. - png_read_end(png_ptr, NULL); - - // Destroy libpng structures - png_destroy_read_struct(&png_ptr, &info_ptr, NULL); -#else - Common::MemoryReadStream *fileStr = new Common::MemoryReadStream(fileDataPtr, fileSize, DisposeAfterUse::NO); - Graphics::PNG *png = new Graphics::PNG(); - if (!png->read(fileStr)) // the fileStr pointer, and thus pFileData will be deleted after this is done - error("Error while reading PNG image"); - - Graphics::PixelFormat format = Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24); - Graphics::Surface *pngSurface = png->getSurface(format); - - width = pngSurface->w; - height = pngSurface->h; - uncompressedDataPtr = new byte[pngSurface->pitch * pngSurface->h]; - memcpy(uncompressedDataPtr, (byte *)pngSurface->pixels, pngSurface->pitch * pngSurface->h); - pngSurface->free(); - - delete pngSurface; - delete png; - -#endif - // Signal success - return true; -} - -bool PNGLoader::decodeImage(const byte *fileDataPtr, uint fileSize, byte *&uncompressedDataPtr, int &width, int &height, int &pitch) { - return doDecodeImage(fileDataPtr, fileSize, uncompressedDataPtr, width, height, pitch); -} - -#ifndef USE_INTERNAL_PNG_DECODER -bool PNGLoader::doImageProperties(const byte *fileDataPtr, uint fileSize, int &width, int &height) { - // Check for valid PNG signature - if (!doIsCorrectImageFormat(fileDataPtr, fileSize)) - return false; - - png_structp png_ptr = NULL; - png_infop info_ptr = NULL; - - // Create both PNG structures - png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - if (!png_ptr) { - error("Could not create libpng read struct."); - } - - info_ptr = png_create_info_struct(png_ptr); - if (!info_ptr) { - error("Could not create libpng info struct."); - } - - // Use alternative reading function - const byte **ref = &fileDataPtr; - png_set_read_fn(png_ptr, (void *)ref, png_user_read_data); - - // Read PNG Header - png_read_info(png_ptr, info_ptr); - - // Read out PNG informations - int bitDepth; - int colorType; - png_uint_32 w, h; - png_get_IHDR(png_ptr, info_ptr, &w, &h, &bitDepth, &colorType, NULL, NULL, NULL); - - width = w; - height = h; - - // Destroy libpng structures - png_destroy_read_struct(&png_ptr, &info_ptr, NULL); - - return true; - -} - -bool PNGLoader::imageProperties(const byte *fileDataPtr, uint fileSize, int &width, int &height) { - return doImageProperties(fileDataPtr, fileSize, width, height); -} - -#else - // We don't need to read the image properties here... -#endif - - -} // End of namespace Sword25 diff --git a/engines/sword25/gfx/image/renderedimage.cpp b/engines/sword25/gfx/image/renderedimage.cpp index 23bf2623ad..a9c9de4f0c 100644 --- a/engines/sword25/gfx/image/renderedimage.cpp +++ b/engines/sword25/gfx/image/renderedimage.cpp @@ -35,21 +35,13 @@ #include "common/savefile.h" #include "sword25/package/packagemanager.h" -#include "sword25/gfx/image/pngloader.h" +#include "sword25/gfx/image/imgloader.h" #include "sword25/gfx/image/renderedimage.h" #include "common/system.h" namespace Sword25 { -// Duplicated from kernel/persistenceservice.cpp -static Common::String generateSavegameFilename(uint slotID) { - char buffer[100]; - // NOTE: This is hardcoded to sword25 - snprintf(buffer, 100, "%s.%.3d", "sword25", slotID); - return Common::String(buffer); -} - // ----------------------------------------------------------------------------- // CONSTRUCTION / DESTRUCTION // ----------------------------------------------------------------------------- @@ -74,8 +66,9 @@ static Common::String loadString(Common::SeekableReadStream &in, uint maxSize = static byte *readSavegameThumbnail(const Common::String &filename, uint &fileSize, bool &isPNG) { byte *pFileData; Common::SaveFileManager *sfm = g_system->getSavefileManager(); - int slotNum = atoi(filename.c_str() + filename.size() - 3); - Common::InSaveFile *file = sfm->openForLoading(generateSavegameFilename(slotNum)); + Common::InSaveFile *file = sfm->openForLoading(lastPathComponent(filename, '/')); + if (!file) + error("Save file \"%s\" could not be loaded.", filename.c_str()); // Seek to the actual PNG image loadString(*file); // Marker (BS25SAVEGAME) @@ -100,30 +93,6 @@ static byte *readSavegameThumbnail(const Common::String &filename, uint &fileSiz return pFileData; } -// TODO: Move this method into a more generic image loading class, together with the PNG reading code -static bool decodeThumbnail(const byte *pFileData, uint fileSize, byte *&pUncompressedData, int &width, int &height, int &pitch) { - const byte *src = pFileData + 4; // skip header - width = READ_LE_UINT16(src); src += 2; - height = READ_LE_UINT16(src); src += 2; - src++; // version, ignored for now - pitch = width * 4; - - uint32 totalSize = pitch * height; - pUncompressedData = new byte[totalSize]; - uint32 *dst = (uint32 *)pUncompressedData; // treat as uint32, for pixelformat output - const Graphics::PixelFormat format = Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24); - byte r, g, b; - - for (uint32 i = 0; i < totalSize / 4; i++) { - r = *src++; - g = *src++; - b = *src++; - *dst++ = format.RGBToColor(r, g, b); - } - - return true; -} - RenderedImage::RenderedImage(const Common::String &filename, bool &result) : _data(0), _width(0), @@ -152,21 +121,12 @@ RenderedImage::RenderedImage(const Common::String &filename, bool &result) : return; } -#ifndef USE_INTERNAL_PNG_DECODER - // Determine image properties - if (!PNGLoader::imageProperties(pFileData, fileSize, _width, _height)) { - error("Could not read image properties."); - delete[] pFileData; - return; - } -#endif - // Uncompress the image int pitch; if (isPNG) - result = PNGLoader::decodeImage(pFileData, fileSize, _data, _width, _height, pitch); + result = ImgLoader::decodePNGImage(pFileData, fileSize, _data, _width, _height, pitch); else - result = decodeThumbnail(pFileData, fileSize, _data, _width, _height, pitch); + result = ImgLoader::decodeThumbnailImage(pFileData, fileSize, _data, _width, _height, pitch); if (!result) { error("Could not decode image."); diff --git a/engines/sword25/gfx/image/swimage.cpp b/engines/sword25/gfx/image/swimage.cpp index 92d47368b2..0b9cc11df2 100644 --- a/engines/sword25/gfx/image/swimage.cpp +++ b/engines/sword25/gfx/image/swimage.cpp @@ -30,7 +30,7 @@ */ #include "sword25/package/packagemanager.h" -#include "sword25/gfx/image/pngloader.h" +#include "sword25/gfx/image/imgloader.h" #include "sword25/gfx/image/swimage.h" namespace Sword25 { @@ -53,18 +53,10 @@ SWImage::SWImage(const Common::String &filename, bool &result) : return; } -#ifndef USE_INTERNAL_PNG_DECODER - // Determine image properties - if (!PNGLoader::imageProperties(pFileData, fileSize, _width, _height)) { - error("Could not read image properties."); - return; - } -#endif - // Uncompress the image int pitch; byte *pUncompressedData; - if (!PNGLoader::decodeImage(pFileData, fileSize, pUncompressedData, _width, _height, pitch)) { + if (!ImgLoader::decodePNGImage(pFileData, fileSize, pUncompressedData, _width, _height, pitch)) { error("Could not decode image."); return; } |