SWORD25: Merge classes PNGLoader, ImageLoader and ImageLoaderManager

This looses some flexibility when it comes to supporting other image
formats. But since the game does not use other image formats, this seems
rather irrelevant, compared to how much simpler the code now is.

svn-id: r53755
This commit is contained in:
Max Horn 2010-10-24 01:32:15 +00:00
parent 1e16d576ca
commit 7cc8811a5c
9 changed files with 56 additions and 345 deletions

View File

@ -35,7 +35,6 @@
#include "sword25/gfx/bitmapresource.h"
#include "sword25/kernel/kernel.h"
#include "sword25/gfx/graphicengine.h"
#include "sword25/gfx/image/imageloader.h"
#include "sword25/package/packagemanager.h"
namespace Sword25 {

View File

@ -1,106 +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.
*
* $URL$
* $Id$
*
*/
/*
* 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 "sword25/gfx/image/imageloader.h"
#include "sword25/gfx/image/pngloader.h"
DECLARE_SINGLETON(Sword25::ImageLoaderManager)
namespace Sword25 {
#define BS_LOG_PREFIX "IMAGELOADER"
bool ImageLoaderManager::loadImage(const byte *pFileData, uint fileSize,
GraphicEngine::COLOR_FORMATS colorFormat,
byte *&pUncompressedData,
int &width, int &height,
int &pitch) {
// Find a suitable ImageLoader and decode the image
ImageLoader *pLoader = findSuitableImageLoader(pFileData, fileSize);
if (pLoader) {
return pLoader->decodeImage(pFileData, fileSize,
colorFormat,
pUncompressedData,
width, height,
pitch);
}
return false;
}
bool ImageLoaderManager::extractImageProperties(const byte *pFileData, uint fileSize,
GraphicEngine::COLOR_FORMATS &colorFormat,
int &width, int &height) {
// Find a suitable ImageLoader and extra the image properties
ImageLoader *pLoader = findSuitableImageLoader(pFileData, fileSize);
if (pLoader) {
return pLoader->imageProperties(pFileData, fileSize,
colorFormat,
width, height);
}
return false;
}
ImageLoaderManager::ImageLoaderManager() {
_imageLoaderList.push_back(new PNGLoader());
}
ImageLoaderManager::~ImageLoaderManager() {
while (!_imageLoaderList.empty()) {
delete _imageLoaderList.back();
_imageLoaderList.pop_back();
}
}
ImageLoader *ImageLoaderManager::findSuitableImageLoader(const byte *pFileData, uint fileSize) {
// Iterate over all registered ImageLoader instances until we find
// one that supports the image.
Common::List<ImageLoader *>::iterator iter = _imageLoaderList.begin();
for (; iter != _imageLoaderList.end(); ++iter) {
if ((*iter)->isCorrectImageFormat(pFileData, fileSize)) {
return (*iter);
}
}
// No suitable ImageLoader was found :-(
BS_LOG_ERRORLN("Could not find suitable image loader for image data.");
return NULL;
}
} // End of namespace Sword25

View File

@ -1,200 +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.
*
* $URL$
* $Id$
*
*/
/*
* This code is based on Broken Sword 2.5 engine
*
* Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
*
* Licensed under GNU GPL v2
*
*/
/*
ImageLoader
--------------
Autor: Malte Thiesen
*/
#ifndef SWORD25_IMAGELOADER_H
#define SWORD25_IMAGELOADER_H
#include "common/singleton.h"
#include "common/list.h"
#include "sword25/kernel/common.h"
#include "sword25/gfx/graphicengine.h"
namespace Sword25 {
/**
* This interface is implemented by classes for loading various image file formats.
* Adding support for new formats requires subclassing this, and implementing all
* three pure virtual methods. In addition, ImageLoaderManager needs to be taught
* about the new loader class.
*
* Note that an implementation must be able to convert any input to format GraphicEngine::CF_ARGB32
*/
class ImageLoader {
protected:
friend class ImageLoaderManager;
// Make the default constructor protected to ensure that only the
// ImageLoaderManager can create instances of ImageLoader subclasses.
ImageLoader() {}
virtual ~ImageLoader() {}
/**
@brief Gibt an, ob der #ImageLoader ein Bild lesen kann.
@param pFileData ein Pointer auf die kompletten Daten des Bildes.
@param FileSize die Größe der Daten in Byte.
@return Gibt true zurück, wenn der #ImageLoader das Bild lesen kann, ansonsten false.
@remark Diese Methode muss von allen ImageLoader Klassen implementiert werden.
*/
virtual bool isCorrectImageFormat(const byte *pFileData, uint fileSize) = 0;
/**
@brief Lädt eine Bilddatei.
@param pFileData ein Pointer auf die Bilddaten.
@param FileSize die Größe der Bilddaten in Byte.
@param ColorFormat gibt das gewünschte Farbformat an, in das die Bilddaten konvertiert werden sollen.<br>
Folgende Farbformate werden unterstützt:
- GraphicEngine::CF_ARGB32
@param pUncompressedData nach erfolgreichen Laden zeigt dieser Pointer auf die enpackten und konvertierten Bilddaten.
@param Width gibt nach erfolgreichen Laden die Breite des geladenen Bildes an.
@param Height gibt nach erfolgreichen Laden die Höhe des geladenen Bildes an.
@param Pitch gibt nach erfolgreichen Laden die Länge einer Bildzeile in Byte an.
@return Gibt false zurück, falls das Laden fehlgeschlagen ist.
@remark Die Größe der Ausgabedaten in Bytes kann wie folgt berechnet werden: Pitch * Height.
@remark Es darf nicht vergessen werden, die Ausgabedaten nach erfolgter Benutzung mit delete freizugeben.
@remark Diese Methode muss von allen ImageLoader Klassen implementiert werden.
*/
virtual bool decodeImage(const byte *pFileData, uint fileSize,
GraphicEngine::COLOR_FORMATS colorFormat,
byte *&pUncompressedData,
int &width, int &height,
int &pitch) = 0;
/**
@brief Liest die Bildeigenschaften aus.
@param pFileData ein Pointer auf die Bilddaten.
@param FileSize die Größe des Bilddaten in Byte.
@param ColorFormat enthält nach einem erfolgreichem Aufruf das Farbformat des Bildes.
@param Width enthält nach einem erfolgreichem Aufruf die Breite des Bildes in Pixeln.
@param Height enthält nach einem erfolgreichem Aufruf die Höhe des Bildes in Pixeln.
@return Gibt false zurück, wenn die Bildeigenschaften nicht ausgelesen werden konnten.
@remark Es darf nicht vergessen werden, die Ausgabedaten nach erfolgter Benutzung mit delete freizugeben.
@remark Diese Methode muss von allen ImageLoader Klassen implementiert werden.
*/
virtual bool imageProperties(const byte *pFileData, uint fileSize,
GraphicEngine::COLOR_FORMATS &colorFormat,
int &width, int &height) = 0;
};
class ImageLoaderManager : public Common::Singleton<ImageLoaderManager> {
public:
/**
* Create instances of various ImageLoader subclasses and keep them
* in an internal list. These are then later used when loading images
* via this manager.
*
* @note To add support for additional ImageManagers, you need to modify
* this method.
*/
ImageLoaderManager();
/**
* Destroy any ImageLoader subclasses instances kept by this manager.
*/
~ImageLoaderManager();
//@{
/** @name Methods for loading */
/**
@brief Lädt eine Bilddatei.
Diese Methode kann sämtliche unterstütztem Bildformate lesen. Die Methode erkennt selbstständing um welches Dateiformat es sich
bei der vorliegenden Datei handelt.<br>
Bisher wird nur PNG unterstützt.
@param pFileData ein Pointer auf die Bilddaten.
@param FileSize die Größe der Bilddaten in Byte.
@param ColorFormat gibt das gewünschte Farbformat an, in das die Bilddaten konvertiert werden sollen.<br>
Folgende Farbformate werden unterstützt:
- GraphicEngine::CF_ARGB32
@param pUncompressedData nach erfolgreichen Laden zeigt dieser Pointer auf die enpackten und konvertierten Bilddaten.
@param Width gibt nach erfolgreichen Laden die Breite des geladenen Bildes an.
@param Height gibt nach erfolgreichen Laden die Höhe des geladenen Bildes an.
@param Pitch gibt nach erfolgreichen Laden die Länge einer Bildzeile in Byte an.
@return Gibt false zurück, falls das Laden fehlgeschlagen ist.
@remark Die Größe der Ausgabedaten in Bytes kann wie folgt berechnet werden: Pitch * Height.
@remark Es darf nicht vergessen werden, die Ausgabedaten nach erfolgter Benutzung mit delete freizugeben.
*/
bool loadImage(const byte *pFileData, uint fileSize,
GraphicEngine::COLOR_FORMATS colorFormat,
byte *&pUncompressedData,
int &width, int &height,
int &pitch);
/**
@brief Liest die Bildeigenschaften eines Bildes aus.
@param pFileData ein Pointer auf die Bilddaten.
@param FileSize die Größe des Bilddaten in Byte.
@param ColorFormat enthält nach einem erfolgreichem Aufruf das Farbformat des Bildes.
@param Width enthält nach einem erfolgreichem Aufruf die Breite des Bildes in Pixeln.
@param Height enthält nach einem erfolgreichem Aufruf die Höhe des Bildes in Pixeln.
@return Gibt false zurück, wenn die Bildeigenschaften nicht ausgelesen werden konnten.
@remark Es darf nicht vergessen werden, die Ausgabedaten nach erfolgter Benutzung mit delete freizugeben.
*/
bool extractImageProperties(const byte *pFileData, uint fileSize,
GraphicEngine::COLOR_FORMATS &colorFormat,
int &width, int &height);
//@}
private:
/**
* Finds an ImageLoader instances capable of decoding the given
* image data.
* @return pointer to a suitable ImageLoader, or NULL if none has been be found
*/
ImageLoader *findSuitableImageLoader(const byte *pFileData, uint fileSize);
Common::List<ImageLoader *> _imageLoaderList; ///< List of ImageLoader instances
};
/** Shortcut for accessing the image loader manager. */
#define ImageMan ImageLoaderManager::instance()
} // End of namespace Sword25
#endif

View File

@ -41,8 +41,6 @@ namespace Sword25 {
#define BS_LOG_PREFIX "PNGLOADER"
namespace {
/**
* Load a NULL-terminated string from the given stream.
*/
@ -66,7 +64,8 @@ static Common::String loadString(Common::ReadStream &in, uint maxSize = 999) {
* @return offset to image data if fileDataPtr contains a savegame; 0 otherwise
*/
static uint findEmbeddedPNG(const byte *fileDataPtr, uint fileSize) {
assert(fileSize >= 100);
if (fileSize < 100)
return 0;
if (memcmp(fileDataPtr, "BS25SAVEGAME", 12))
return 0;
@ -86,7 +85,6 @@ static uint findEmbeddedPNG(const byte *fileDataPtr, uint fileSize) {
// Return the offset of where the thumbnail starts
return static_cast<uint>(stream.pos() + compressedGamedataSize);
}
}
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);
@ -112,7 +110,7 @@ bool PNGLoader::doDecodeImage(const byte *fileDataPtr, uint fileSize, GraphicEn
}
// PNG Signatur überprüfen
if (!png_check_sig(reinterpret_cast<png_bytep>(const_cast<byte *>(fileDataPtr)), 8)) {
if (!doIsCorrectImageFormat(fileDataPtr, fileSize)) {
error("png_check_sig failed");
}
@ -293,10 +291,7 @@ bool PNGLoader::imageProperties(const byte *fileDataPtr, uint fileSize, GraphicE
}
bool PNGLoader::doIsCorrectImageFormat(const byte *fileDataPtr, uint fileSize) {
if (fileSize > 8)
return png_check_sig(const_cast<byte *>(fileDataPtr), 8) ? true : false;
else
return false;
return (fileSize > 8) && png_check_sig(const_cast<byte *>(fileDataPtr), 8);
}
bool PNGLoader::isCorrectImageFormat(const byte *fileDataPtr, uint fileSize) {

View File

@ -32,41 +32,67 @@
*
*/
/*
PNGLoader
------------
ImageLoader-Klasse zum Laden von PNG-Dateien
Autor: Malte Thiesen
*/
#ifndef SWORD25_PNGLOADER2_H
#define SWORD25_PNGLOADER2_H
// Includes
#include "sword25/kernel/common.h"
#include "sword25/gfx/image/imageloader.h"
#include "sword25/gfx/graphicengine.h"
namespace Sword25 {
// Klassendefinition
class PNGLoader : public ImageLoader {
friend class ImageLoaderManager;
public:
// Alle virtuellen Methoden von BS_ImageLoader sind hier als static-Methode implementiert, damit sie von BS_B25SLoader aufgerufen werden können.
// Die virtuellen Methoden rufen diese Methoden auf.
/**
* Class for loading PNG files, and PNG data embedded into savegames.
*
* Originally written by Malte Thiesen.
*/
class PNGLoader {
protected:
PNGLoader() {} // Protected constructor to prevent instances
static bool doIsCorrectImageFormat(const byte *fileDataPtr, uint fileSize);
static bool doDecodeImage(const byte *fileDataPtr, uint fileSize, GraphicEngine::COLOR_FORMATS colorFormat, byte *&uncompressedDataPtr, int &width, int &height, int &pitch);
static bool doImageProperties(const byte *fileDataPtr, uint fileSize, GraphicEngine::COLOR_FORMATS &colorFormat, int &width, int &height);
protected:
bool decodeImage(const byte *pFileData, uint fileSize,
public:
static bool isCorrectImageFormat(const byte *fileDataPtr, uint fileSize);
/**
* Decode an image.
* @param[in] fileDatePtr pointer to the image data
* @param[in] fileSize size of the image data in bytes
* @param[in] colorFormat the color format to which the the data should be decoded
* @param[out] pUncompressedData if successful, this is set to a pointer containing the decoded image data
* @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
* @param[out] pitch if successful, this is set to the number of bytes per scanline in the image
* @return false in case of an error
*
* @remark The size of the output data equals pitch * height.
* @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,
GraphicEngine::COLOR_FORMATS colorFormat,
byte *&pUncompressedData,
int &width, int &height,
int &pitch);
bool isCorrectImageFormat(const byte *fileDataPtr, uint fileSize);
bool imageProperties(const byte *fileDatePtr, uint fileSize, GraphicEngine::COLOR_FORMATS &colorFormat, int &width, int &height);
/**
* 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] colorFormat if successful, this is set to the color format of the image
* @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,
GraphicEngine::COLOR_FORMATS &colorFormat,
int &width,
int &height);
};
} // End of namespace Sword25

View File

@ -37,7 +37,7 @@
// -----------------------------------------------------------------------------
#include "sword25/package/packagemanager.h"
#include "sword25/gfx/image/imageloader.h"
#include "sword25/gfx/image/pngloader.h"
#include "sword25/gfx/image/renderedimage.h"
#include "common/system.h"
@ -72,14 +72,14 @@ RenderedImage::RenderedImage(const Common::String &filename, bool &result) :
// Bildeigenschaften bestimmen
GraphicEngine::COLOR_FORMATS colorFormat;
int pitch;
if (!ImageMan.extractImageProperties(pFileData, fileSize, colorFormat, _width, _height)) {
if (!PNGLoader::imageProperties(pFileData, fileSize, colorFormat, _width, _height)) {
BS_LOG_ERRORLN("Could not read image properties.");
delete[] pFileData;
return;
}
// Das Bild dekomprimieren
if (!ImageMan.loadImage(pFileData, fileSize, GraphicEngine::CF_ARGB32, _data, _width, _height, pitch)) {
if (!PNGLoader::decodeImage(pFileData, fileSize, GraphicEngine::CF_ARGB32, _data, _width, _height, pitch)) {
BS_LOG_ERRORLN("Could not decode image.");
delete[] pFileData;
return;

View File

@ -33,7 +33,7 @@
*/
#include "sword25/package/packagemanager.h"
#include "sword25/gfx/image/imageloader.h"
#include "sword25/gfx/image/pngloader.h"
#include "sword25/gfx/image/swimage.h"
namespace Sword25 {
@ -61,14 +61,14 @@ SWImage::SWImage(const Common::String &filename, bool &result) :
// Bildeigenschaften bestimmen
GraphicEngine::COLOR_FORMATS colorFormat;
int pitch;
if (!ImageMan.extractImageProperties(pFileData, fileSize, colorFormat, _width, _height)) {
if (!PNGLoader::imageProperties(pFileData, fileSize, colorFormat, _width, _height)) {
BS_LOG_ERRORLN("Could not read image properties.");
return;
}
// Das Bild dekomprimieren
byte *pUncompressedData;
if (!ImageMan.loadImage(pFileData, fileSize, GraphicEngine::CF_ARGB32, pUncompressedData, _width, _height, pitch)) {
if (!PNGLoader::decodeImage(pFileData, fileSize, GraphicEngine::CF_ARGB32, pUncompressedData, _width, _height, pitch)) {
BS_LOG_ERRORLN("Could not decode image.");
return;
}

View File

@ -26,7 +26,6 @@ MODULE_OBJS := \
gfx/text.o \
gfx/timedrenderobject.o \
gfx/image/art.o \
gfx/image/imageloader.o \
gfx/image/pngloader.o \
gfx/image/renderedimage.o \
gfx/image/swimage.o \

View File

@ -45,7 +45,6 @@
#include "sword25/gfx/animationtemplateregistry.h" // Needed so we can destroy the singleton
#include "sword25/gfx/renderobjectregistry.h" // Needed so we can destroy the singleton
#include "sword25/math/regionregistry.h" // Needed so we can destroy the singleton
#include "sword25/gfx/image/imageloader.h" // Needed so we can destroy the singleton
namespace Sword25 {
@ -138,7 +137,6 @@ bool Sword25Engine::appEnd() {
// The kernel is shutdown, and un-initialises all subsystems
Kernel::deleteInstance();
ImageLoaderManager::destroy();
AnimationTemplateRegistry::destroy();
RenderObjectRegistry::destroy();
RegionRegistry::destroy();