[Marble-commits] KDE/kdeedu/marble/src/lib
Bernhard Beschow
bbeschow at cs.tu-berlin.de
Fri Jul 9 14:45:01 CEST 2010
SVN commit 1147952 by beschow:
don't load invalid images into texture tiles
* please review for possible memory leaks or invalid pointer accesses
M +4 -19 TextureTile.cpp
M +10 -11 TextureTile.h
M +26 -30 TileLoader.cpp
--- trunk/KDE/kdeedu/marble/src/lib/TextureTile.cpp #1147951:1147952
@@ -22,22 +22,15 @@
namespace Marble
{
-TextureTile::TextureTile( TileId const & tileId )
+TextureTile::TextureTile( TileId const & tileId, QImage const * image )
: m_id( tileId ),
- m_state( StateEmpty ),
- m_blending( 0 ),
- m_expireSecs( std::numeric_limits<int>::max() ),
- m_image( 0 )
-{
-}
-
-TextureTile::TextureTile( TileId const & tileId, QString const & fileName )
- : m_id( tileId ),
m_state( StateExpired ),
m_blending( 0 ),
m_expireSecs( std::numeric_limits<int>::max() ),
- m_image( new QImage( fileName ))
+ m_image( image )
{
+ Q_ASSERT( image );
+ Q_ASSERT( !image->isNull() );
}
TextureTile::~TextureTile()
@@ -45,12 +38,4 @@
delete m_image;
}
-void TextureTile::setImage( QByteArray const & data )
-{
- if ( !m_image )
- m_image = new QImage( QImage::fromData( data ));
- else
- m_image->loadFromData( data );
}
-
-}
--- trunk/KDE/kdeedu/marble/src/lib/TextureTile.h #1147951:1147952
@@ -43,8 +43,7 @@
StateUptodate
};
- explicit TextureTile( TileId const & );
- TextureTile( TileId const & tileId, QString const & fileName );
+ TextureTile( TileId const & tileId, QImage const * image );
~TextureTile();
TileId const & id() const;
@@ -52,7 +51,6 @@
QDateTime const & lastModified() const;
bool isExpired() const;
QImage const * image() const;
- QImage * image();
State state() const;
Blending const * blending() const;
int byteCount() const;
@@ -61,7 +59,6 @@
Q_DISABLE_COPY( TextureTile )
void setState( State const );
- void setImage( QByteArray const & data );
void setImage( QImage * const );
void setBlending( Blending const * const );
void setStackedTileId( TileId const & );
@@ -74,7 +71,7 @@
Blending const * m_blending;
QDateTime m_lastModified;
int m_expireSecs;
- QImage * m_image;
+ QImage const * m_image;
};
@@ -105,11 +102,6 @@
return m_image;
}
-inline QImage * TextureTile::image()
-{
- return m_image;
-}
-
inline TextureTile::State TextureTile::state() const
{
return m_state;
@@ -122,8 +114,10 @@
inline int TextureTile::byteCount() const
{
+ Q_ASSERT( m_image );
+
// FIXME: once Qt 4.6 is required for Marble, use QImage::byteCount()
- return m_image ? m_image->numBytes() : 0;
+ return m_image->numBytes();
}
inline void TextureTile::setState( State const state )
@@ -133,6 +127,11 @@
inline void TextureTile::setImage( QImage * const image )
{
+ Q_ASSERT( image );
+ Q_ASSERT( !image->isNull() );
+
+ delete m_image;
+
m_image = image;
}
--- trunk/KDE/kdeedu/marble/src/lib/TileLoader.cpp #1147951:1147952
@@ -48,14 +48,14 @@
DownloadUsage const usage )
{
QString const fileName = tileFileName( tileId );
- QFileInfo const fileInfo( fileName );
- if ( fileInfo.exists() ) {
+ QImage const image( fileName );
+ if ( !image.isNull() ) {
// file is there, so create and return a tile object in any case,
// but check if an update should be triggered
GeoSceneTexture const * const textureLayer = findTextureLayer( tileId );
- QSharedPointer<TextureTile> const tile( new TextureTile( tileId, fileName ));
+ QSharedPointer<TextureTile> const tile( new TextureTile( tileId, new QImage( image ) ));
tile->setStackedTileId( stackedTileId );
- tile->setLastModified( fileInfo.lastModified() );
+ tile->setLastModified( QFileInfo( fileName ).lastModified() );
tile->setExpireSecs( textureLayer->expire() );
if ( !tile->isExpired() ) {
@@ -71,18 +71,14 @@
// tile was not locally available => trigger download and look for tiles in other levels
// for scaling
- QSharedPointer<TextureTile> const tile( new TextureTile( tileId ));
+ QImage * replacementTile = scaledLowerLevelTile( tileId );
+ QSharedPointer<TextureTile> const tile( new TextureTile( tileId, replacementTile ));
tile->setStackedTileId( stackedTileId );
+ tile->setState( TextureTile::StateScaled );
+
m_waitingForUpdate.insert( tileId, tile );
triggerDownload( tileId, usage );
- QImage * const replacementTile = scaledLowerLevelTile( tileId );
- if ( replacementTile ) {
- mDebug() << "TileLoader::loadTile" << tileId.toString() << "StateScaled";
- tile->setImage( replacementTile );
- tile->setState( TextureTile::StateScaled );
- } else {
- mDebug() << "TileLoader::loadTile" << tileId.toString() << "No tiles found";
- }
+
return tile;
}
@@ -108,19 +104,16 @@
return tile;
QString const fileName = tileFileName( tileId );
- QFileInfo const fileInfo( fileName );
- if ( fileInfo.exists() ) {
- tile = QSharedPointer<TextureTile>( new TextureTile( tileId, fileName ));
- tile->setLastModified( fileInfo.lastModified() );
+ QImage const image( fileName );
+ if ( !image.isNull() ) {
+ tile = QSharedPointer<TextureTile>( new TextureTile( tileId, new QImage( image ) ));
+ tile->setLastModified( QFileInfo( fileName ).lastModified() );
}
else {
- tile = QSharedPointer<TextureTile>( new TextureTile( tileId ));
QImage * const replacementTile = scaledLowerLevelTile( tileId );
- if ( replacementTile ) {
- tile->setImage( replacementTile );
+ tile = QSharedPointer<TextureTile>( new TextureTile( tileId, replacementTile ));
tile->setState( TextureTile::StateScaled );
}
- }
GeoSceneTexture const * const textureLayer = findTextureLayer( tileId );
tile->setExpireSecs( textureLayer->expire() );
@@ -162,7 +155,11 @@
return;
Q_ASSERT( tile );
m_waitingForUpdate.remove( id );
- tile->setImage( data );
+ QImage *image( new QImage( QImage::fromData( data ) ) );
+ if ( image->isNull() )
+ return;
+
+ tile->setImage( image );
tile->setState( TextureTile::StateUptodate );
tile->setLastModified( QDateTime::currentDateTime() );
emit tileCompleted( tile->stackedTileId(), id );
@@ -200,17 +197,15 @@
QImage * TileLoader::scaledLowerLevelTile( TileId const & id )
{
mDebug() << "TileLoader::scaledLowerLevelTile" << id.toString();
- QImage * result = 0;
- int level = id.zoomLevel() - 1;
- while ( !result && level >= 0 ) {
+
+ for ( int level = id.zoomLevel() - 1; level >= 0; --level ) {
int const deltaLevel = id.zoomLevel() - level;
TileId const replacementTileId( id.mapThemeIdHash(), level,
id.x() >> deltaLevel, id.y() >> deltaLevel );
mDebug() << "TileLoader::scaledLowerLevelTile" << "trying" << replacementTileId.toString();
QString const fileName = tileFileName( replacementTileId );
- QFileInfo const fileInfo( fileName );
- if ( fileInfo.exists() ) {
QImage const toScale( fileName );
+ if ( !toScale.isNull() ) {
// which rect to scale?
QSize const size = toScale.size();
int const restTileX = id.x() % ( 1 << deltaLevel );
@@ -222,11 +217,12 @@
mDebug() << "QImage::copy:" << startX << startY << partWidth << partHeight;
QImage const part = toScale.copy( startX, startY, partWidth, partHeight );
mDebug() << "QImage::scaled:" << toScale.size();
- result = new QImage( part.scaled( toScale.size() ));
+ return new QImage( part.scaled( toScale.size() ) );
}
- --level;
}
- return result;
+
+ Q_ASSERT_X( false, "scaled image", "level zero image missing" ); // not reached
+ return new QImage();
}
}
More information about the Marble-commits
mailing list