Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
raster save as raw/image mode, pipe clone
  • Loading branch information
blazek committed Aug 16, 2012
1 parent ec88c9d commit ac4486a
Show file tree
Hide file tree
Showing 47 changed files with 447 additions and 30 deletions.
1 change: 1 addition & 0 deletions python/core/core.sip
Expand Up @@ -63,6 +63,7 @@
%Include qgsproviderregistry.sip
%Include qgsrasterbandstats.sip
%Include qgsrasterdataprovider.sip
%Include qgsrasterinterface.sip
%Include qgsrasterlayer.sip
%Include qgsrasterpyramid.sip
%Include qgsrasterrenderer.sip
Expand Down
3 changes: 3 additions & 0 deletions python/core/qgsrasterdataprovider.sip
Expand Up @@ -10,6 +10,7 @@ class QgsRasterDataProvider : QgsDataProvider
{
%TypeHeaderCode
#include <qgsrasterdataprovider.h>
#include <qgsrasterinterface.h>
%End

public:
Expand All @@ -29,6 +30,8 @@ class QgsRasterDataProvider : QgsDataProvider

virtual ~QgsRasterDataProvider();

virtual QgsRasterInterface * clone() const = 0;

/**
* Add the list of WMS layer names to be rendered by this server
*/
Expand Down
73 changes: 73 additions & 0 deletions python/core/qgsrasterinterface.sip
@@ -0,0 +1,73 @@

/** Base class for processing modules.
*
*/

class QgsRasterInterface
{
%TypeHeaderCode
#include <qgsrasterinterface.h>
%End
public:

enum DataType
{
/*! Unknown or unspecified type */ UnknownDataType = 0,
/*! Eight bit unsigned integer */ Byte = 1,
/*! Sixteen bit unsigned integer */ UInt16 = 2,
/*! Sixteen bit signed integer */ Int16 = 3,
/*! Thirty two bit unsigned integer */ UInt32 = 4,
/*! Thirty two bit signed integer */ Int32 = 5,
/*! Thirty two bit floating point */ Float32 = 6,
/*! Sixty four bit floating point */ Float64 = 7,
/*! Complex Int16 */ CInt16 = 8,
/*! Complex Int32 */ CInt32 = 9,
/*! Complex Float32 */ CFloat32 = 10,
/*! Complex Float64 */ CFloat64 = 11,
/*! Color, alpha, red, green, blue, 4 bytes the same as
QImage::Format_ARGB32 */ ARGB32 = 12,
/*! Color, alpha, red, green, blue, 4 bytes the same as
QImage::Format_ARGB32_Premultiplied */ ARGB32_Premultiplied = 13,

TypeCount = 14 /* maximum type # + 1 */
};

QgsRasterInterface( QgsRasterInterface * input = 0 );

virtual ~QgsRasterInterface();

int typeSize( int dataType ) const;

virtual QgsRasterInterface *clone() const = 0;

int dataTypeSize( int bandNo ) const;

bool typeIsNumeric( DataType type ) const;

bool typeIsColor( DataType type ) const;

virtual DataType dataType( int bandNo ) const;

virtual int bandCount() const;

virtual double noDataValue() const;

//void * block( int bandNo, QgsRectangle const & extent, int width, int height );

//virtual void * readBlock( int bandNo, QgsRectangle const & extent, int width, int height );

virtual bool setInput( QgsRasterInterface* input );

virtual bool on( );

virtual void setOn( bool on );

virtual QgsRasterInterface * srcInput();

QImage * createImage( int width, int height, QImage::Format format );

void setStatsOn( bool on );

double time( bool cumulative = false );
};

6 changes: 6 additions & 0 deletions python/core/qgsrasterrenderer.sip
Expand Up @@ -27,6 +27,7 @@ class QgsRasterRenderer
public:
QgsRasterRenderer( QgsRasterDataProvider* provider, const QString& type );
virtual ~QgsRasterRenderer();
virtual QgsRasterInterface * clone() const = 0;

virtual QString type() const;
virtual void * readBlock( int bandNo, const QgsRectangle & extent, int width, int height );
Expand Down Expand Up @@ -63,6 +64,7 @@ class QgsPalettedRasterRenderer: QgsRasterRenderer
/**Renderer owns color array*/
QgsPalettedRasterRenderer( QgsRasterDataProvider* provider, int bandNumber, QColor* colorArray, int nColors );
~QgsPalettedRasterRenderer();
QgsRasterInterface * clone();
static QgsRasterRenderer* create( const QDomElement& elem, QgsRasterDataProvider* provider );

void * readBlock( int bandNo, const QgsRectangle & extent, int width, int height );
Expand All @@ -87,6 +89,7 @@ class QgsMultiBandColorRenderer: QgsRasterRenderer
QgsContrastEnhancement* redEnhancement = 0, QgsContrastEnhancement* greenEnhancement = 0,
QgsContrastEnhancement* blueEnhancement = 0 );
~QgsMultiBandColorRenderer();
QgsRasterInterface * clone();

static QgsRasterRenderer* create( const QDomElement& elem, QgsRasterDataProvider* provider );

Expand Down Expand Up @@ -123,6 +126,7 @@ class QgsSingleBandPseudoColorRenderer: QgsRasterRenderer
/**Note: takes ownership of QgsRasterShader*/
QgsSingleBandPseudoColorRenderer( QgsRasterDataProvider* provider, int band, QgsRasterShader* shader );
~QgsSingleBandPseudoColorRenderer();
QgsRasterInterface * clone();

static QgsRasterRenderer* create( const QDomElement& elem, QgsRasterDataProvider* provider );

Expand All @@ -145,6 +149,7 @@ class QgsSingleBandGrayRenderer: QgsRasterRenderer
public:
QgsSingleBandGrayRenderer( QgsRasterDataProvider* provider, int grayBand );
~QgsSingleBandGrayRenderer();
QgsRasterInterface * clone();

static QgsRasterRenderer* create( const QDomElement& elem, QgsRasterDataProvider* provider );

Expand All @@ -169,6 +174,7 @@ class QgsSingleBandColorDataRenderer: QgsRasterRenderer
public:
QgsSingleBandColorDataRenderer( QgsRasterDataProvider* provider, int band );
~QgsSingleBandColorDataRenderer();
QgsRasterInterface * clone();

static QgsRasterRenderer* create( const QDomElement& elem, QgsRasterDataProvider* provider );

Expand Down
3 changes: 3 additions & 0 deletions python/core/qgsrasterresampler.sip
Expand Up @@ -19,6 +19,7 @@ class QgsRasterResampler
public:
virtual void resample( const QImage& srcImage, QImage& dstImage ) = 0;
virtual QString type() const = 0;
virtual QgsRasterResampler * clone() const = 0;
};

class QgsBilinearRasterResampler: QgsRasterResampler
Expand All @@ -32,6 +33,7 @@ class QgsBilinearRasterResampler: QgsRasterResampler

void resample( const QImage& srcImage, QImage& dstImage );
QString type() const;
QgsRasterResampler * clone() const;
};

class QgsCubicRasterResampler: QgsRasterResampler
Expand All @@ -44,4 +46,5 @@ class QgsCubicRasterResampler: QgsRasterResampler
~QgsCubicRasterResampler();
void resample( const QImage& srcImage, QImage& dstImage );
QString type() const;
QgsRasterResampler * clone() const;
};
55 changes: 47 additions & 8 deletions src/app/qgisapp.cpp
Expand Up @@ -3937,20 +3937,59 @@ void QgisApp::saveAsRasterFile()

QProgressDialog pd( 0, tr( "Abort..." ), 0, 0 );
pd.setWindowModality( Qt::WindowModal );
QgsRasterDataProvider* provider = rasterLayer->dataProvider();
if ( !provider )

// TODO: show error dialogs
// TODO: this code should go somewhere else, but probably not into QgsRasterFileWriter
// clone pipe/provider is not really necessary, ready for threads
QgsRasterPipe* pipe = 0;

if ( d.mode() == QgsRasterLayerSaveAsDialog::RawDataMode )
{
return;
QgsDebugMsg( "Writing raw data" );
//QgsDebugMsg( QString( "Writing raw data" ).arg( pos ) );
pipe = new QgsRasterPipe();
if ( !pipe->set( rasterLayer->dataProvider()->clone() ) )
{
QgsDebugMsg( "Cannot set pipe provider" );
return;
}
// add projector if necessary
if ( d.outputCrs() != rasterLayer->dataProvider()->crs() )
{
QgsRasterProjector * projector = new QgsRasterProjector;
projector->setCRS( rasterLayer->dataProvider()->crs(), d.outputCrs() );
if ( !pipe->set( projector ) )
{
QgsDebugMsg( "Cannot set pipe projector" );
return;
}
}
}
else // RenderedImageMode
{
// clone the whole pipe
QgsDebugMsg( "Writing rendered image" );
pipe = new QgsRasterPipe( *rasterLayer->pipe() );
QgsRasterProjector *projector = pipe->projector();
if ( !projector )
{
QgsDebugMsg( "Cannot get pipe projector" );
delete pipe;
return;
}
projector->setCRS( rasterLayer->dataProvider()->crs(), d.outputCrs() );
}
QgsRasterIterator iterator( provider );
int nRows = -1; //calculate number of rows such that pixels are squares
if ( provider->capabilities() & QgsRasterDataProvider::ExactResolution )

if ( !pipe->last() )
{
nRows = d.nRows();
delete pipe;
return;
}
QgsRasterIterator iterator( pipe->last() );
fileWriter.setCreateOptions( d.createOptions() );

fileWriter.writeRaster( &iterator, d.nColumns(), nRows, d.outputRectangle(), d.outputCrs(), &pd );
fileWriter.writeRaster( &iterator, d.nColumns(), d.nRows(), d.outputRectangle(), d.outputCrs(), &pd );
delete pipe;
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/core/qgsrasterdataprovider.h
Expand Up @@ -108,7 +108,7 @@ class CORE_EXPORT QgsRasterDataProvider : public QgsDataProvider, public QgsRast

virtual ~QgsRasterDataProvider() {};

QgsRasterInterface * srcInput() { return this; }
virtual QgsRasterInterface * clone() const = 0;

/* It makes no sense to set input on provider */
bool setInput( QgsRasterInterface* input ) { Q_UNUSED( input ); return false; }
Expand Down
12 changes: 10 additions & 2 deletions src/core/qgsrasterprojector.cpp
Expand Up @@ -66,6 +66,13 @@ QgsRasterProjector::QgsRasterProjector()
QgsDebugMsg( "Entered" );
}

QgsRasterInterface * QgsRasterProjector::clone() const
{
QgsDebugMsg( "Entered" );
QgsRasterProjector * projector = new QgsRasterProjector( mSrcCRS, mDestCRS, mMaxSrcXRes, mMaxSrcYRes, mExtent );
return projector;
}

QgsRasterProjector::~QgsRasterProjector()
{
delete[] pHelperTop;
Expand Down Expand Up @@ -104,6 +111,8 @@ void QgsRasterProjector::calc()
pHelperBottom = 0;

// Get max source resolution if possible
mMaxSrcXRes = 0;
mMaxSrcYRes = 0;
if ( mInput )
{
QgsRasterDataProvider *provider = dynamic_cast<QgsRasterDataProvider*>( mInput->srcInput() );
Expand Down Expand Up @@ -622,8 +631,7 @@ void * QgsRasterProjector::readBlock( int bandNo, QgsRectangle const & extent,

if ( !inputData ) return 0;

// ARGB32 only for now
int pixelSize = 4;
int pixelSize = mInput->typeSize( mInput->dataType( bandNo ) ) / 8;

int inputSize = pixelSize * srcCols() * srcRows();

Expand Down
2 changes: 2 additions & 0 deletions src/core/qgsrasterprojector.h
Expand Up @@ -61,6 +61,8 @@ class CORE_EXPORT QgsRasterProjector : public QgsRasterInterface
/** \brief The destructor */
~QgsRasterProjector();

QgsRasterInterface * clone() const;

int bandCount() const;

QgsRasterInterface::DataType dataType( int bandNo ) const;
Expand Down
5 changes: 5 additions & 0 deletions src/core/raster/qgsbilinearrasterresampler.cpp
Expand Up @@ -27,6 +27,11 @@ QgsBilinearRasterResampler::~QgsBilinearRasterResampler()
{
}

QgsRasterResampler * QgsBilinearRasterResampler::clone() const
{
return new QgsBilinearRasterResampler();
}

void QgsBilinearRasterResampler::resample( const QImage& srcImage, QImage& dstImage )
{
dstImage = srcImage.scaled( dstImage.width(), dstImage.height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
Expand Down
1 change: 1 addition & 0 deletions src/core/raster/qgsbilinearrasterresampler.h
Expand Up @@ -29,6 +29,7 @@ class CORE_EXPORT QgsBilinearRasterResampler: public QgsRasterResampler

void resample( const QImage& srcImage, QImage& dstImage );
QString type() const { return "bilinear"; }
QgsRasterResampler * clone() const;
};

#endif // QGSBILINEARRASTERRESAMPLER_H
29 changes: 29 additions & 0 deletions src/core/raster/qgscontrastenhancement.cpp
Expand Up @@ -52,6 +52,35 @@ QgsContrastEnhancement::QgsContrastEnhancement( QgsRasterDataType theDataType )

}

QgsContrastEnhancement::QgsContrastEnhancement( const QgsContrastEnhancement& ce )
{
mLookupTable = 0;
mEnhancementDirty = ce.mEnhancementDirty;
mContrastEnhancementAlgorithm = ce.mContrastEnhancementAlgorithm;
mRasterDataType = ce.mRasterDataType;

mMinimumValue = ce.mMinimumValue;
mMaximumValue = ce.mMaximumValue;
mRasterDataTypeRange = ce.mRasterDataTypeRange;

mLookupTableOffset = ce.mLookupTableOffset;

mContrastEnhancementFunction = new QgsContrastEnhancementFunction( mRasterDataType, mMinimumValue, mMaximumValue );

//If the data type is larger than 16-bit do not generate a lookup table
if ( mRasterDataTypeRange <= 65535.0 )
{
mLookupTable = new int[static_cast <int>( mRasterDataTypeRange+1 )];
if ( !ce.mEnhancementDirty )
{
for ( int myIterator = 0; myIterator <= mRasterDataTypeRange; myIterator++ )
{
mLookupTable[myIterator] = ce.mLookupTable[myIterator];
}
}
}
}

QgsContrastEnhancement::~QgsContrastEnhancement()
{
}
Expand Down
1 change: 1 addition & 0 deletions src/core/raster/qgscontrastenhancement.h
Expand Up @@ -73,6 +73,7 @@ class CORE_EXPORT QgsContrastEnhancement
};

QgsContrastEnhancement( QgsContrastEnhancement::QgsRasterDataType theDatatype = QGS_Byte );
QgsContrastEnhancement( const QgsContrastEnhancement& ce );
~QgsContrastEnhancement();

/*
Expand Down
7 changes: 7 additions & 0 deletions src/core/raster/qgscontrastenhancementfunction.cpp
Expand Up @@ -26,6 +26,13 @@ QgsContrastEnhancementFunction::QgsContrastEnhancementFunction( QgsContrastEnhan
mMinimumMaximumRange = mMaximumValue - mMinimumValue;
}

QgsContrastEnhancementFunction::QgsContrastEnhancementFunction( const QgsContrastEnhancementFunction& f )
{
mQgsRasterDataType = f.mQgsRasterDataType;
mMaximumValue = f.mMaximumValue;
mMinimumValue = f.mMinimumValue;
mMinimumMaximumRange = f.mMinimumMaximumRange;
}

int QgsContrastEnhancementFunction::enhance( double theValue )
{
Expand Down
1 change: 1 addition & 0 deletions src/core/raster/qgscontrastenhancementfunction.h
Expand Up @@ -32,6 +32,7 @@ class CORE_EXPORT QgsContrastEnhancementFunction

public:
QgsContrastEnhancementFunction( QgsContrastEnhancement::QgsRasterDataType, double, double );
QgsContrastEnhancementFunction( const QgsContrastEnhancementFunction& f );
virtual ~QgsContrastEnhancementFunction() {}

/** \brief A customizable method that takes in a double and returns a int between 0 and 255 */
Expand Down
5 changes: 5 additions & 0 deletions src/core/raster/qgscubicrasterresampler.cpp
Expand Up @@ -27,6 +27,11 @@ QgsCubicRasterResampler::~QgsCubicRasterResampler()
{
}

QgsRasterResampler * QgsCubicRasterResampler::clone() const
{
return new QgsCubicRasterResampler();
}

void QgsCubicRasterResampler::resample( const QImage& srcImage, QImage& dstImage )
{
int nCols = srcImage.width();
Expand Down
1 change: 1 addition & 0 deletions src/core/raster/qgscubicrasterresampler.h
Expand Up @@ -26,6 +26,7 @@ class CORE_EXPORT QgsCubicRasterResampler: public QgsRasterResampler
public:
QgsCubicRasterResampler();
~QgsCubicRasterResampler();
QgsRasterResampler * clone() const;
void resample( const QImage& srcImage, QImage& dstImage );
QString type() const { return "cubic"; }

Expand Down

0 comments on commit ac4486a

Please sign in to comment.