Skip to content

Commit ac4486a

Browse files
committed
raster save as raw/image mode, pipe clone
1 parent ec88c9d commit ac4486a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+447
-30
lines changed

python/core/core.sip

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
%Include qgsproviderregistry.sip
6464
%Include qgsrasterbandstats.sip
6565
%Include qgsrasterdataprovider.sip
66+
%Include qgsrasterinterface.sip
6667
%Include qgsrasterlayer.sip
6768
%Include qgsrasterpyramid.sip
6869
%Include qgsrasterrenderer.sip

python/core/qgsrasterdataprovider.sip

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ class QgsRasterDataProvider : QgsDataProvider
1010
{
1111
%TypeHeaderCode
1212
#include <qgsrasterdataprovider.h>
13+
#include <qgsrasterinterface.h>
1314
%End
1415

1516
public:
@@ -29,6 +30,8 @@ class QgsRasterDataProvider : QgsDataProvider
2930

3031
virtual ~QgsRasterDataProvider();
3132

33+
virtual QgsRasterInterface * clone() const = 0;
34+
3235
/**
3336
* Add the list of WMS layer names to be rendered by this server
3437
*/

python/core/qgsrasterinterface.sip

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
2+
/** Base class for processing modules.
3+
*
4+
*/
5+
6+
class QgsRasterInterface
7+
{
8+
%TypeHeaderCode
9+
#include <qgsrasterinterface.h>
10+
%End
11+
public:
12+
13+
enum DataType
14+
{
15+
/*! Unknown or unspecified type */ UnknownDataType = 0,
16+
/*! Eight bit unsigned integer */ Byte = 1,
17+
/*! Sixteen bit unsigned integer */ UInt16 = 2,
18+
/*! Sixteen bit signed integer */ Int16 = 3,
19+
/*! Thirty two bit unsigned integer */ UInt32 = 4,
20+
/*! Thirty two bit signed integer */ Int32 = 5,
21+
/*! Thirty two bit floating point */ Float32 = 6,
22+
/*! Sixty four bit floating point */ Float64 = 7,
23+
/*! Complex Int16 */ CInt16 = 8,
24+
/*! Complex Int32 */ CInt32 = 9,
25+
/*! Complex Float32 */ CFloat32 = 10,
26+
/*! Complex Float64 */ CFloat64 = 11,
27+
/*! Color, alpha, red, green, blue, 4 bytes the same as
28+
QImage::Format_ARGB32 */ ARGB32 = 12,
29+
/*! Color, alpha, red, green, blue, 4 bytes the same as
30+
QImage::Format_ARGB32_Premultiplied */ ARGB32_Premultiplied = 13,
31+
32+
TypeCount = 14 /* maximum type # + 1 */
33+
};
34+
35+
QgsRasterInterface( QgsRasterInterface * input = 0 );
36+
37+
virtual ~QgsRasterInterface();
38+
39+
int typeSize( int dataType ) const;
40+
41+
virtual QgsRasterInterface *clone() const = 0;
42+
43+
int dataTypeSize( int bandNo ) const;
44+
45+
bool typeIsNumeric( DataType type ) const;
46+
47+
bool typeIsColor( DataType type ) const;
48+
49+
virtual DataType dataType( int bandNo ) const;
50+
51+
virtual int bandCount() const;
52+
53+
virtual double noDataValue() const;
54+
55+
//void * block( int bandNo, QgsRectangle const & extent, int width, int height );
56+
57+
//virtual void * readBlock( int bandNo, QgsRectangle const & extent, int width, int height );
58+
59+
virtual bool setInput( QgsRasterInterface* input );
60+
61+
virtual bool on( );
62+
63+
virtual void setOn( bool on );
64+
65+
virtual QgsRasterInterface * srcInput();
66+
67+
QImage * createImage( int width, int height, QImage::Format format );
68+
69+
void setStatsOn( bool on );
70+
71+
double time( bool cumulative = false );
72+
};
73+

python/core/qgsrasterrenderer.sip

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class QgsRasterRenderer
2727
public:
2828
QgsRasterRenderer( QgsRasterDataProvider* provider, const QString& type );
2929
virtual ~QgsRasterRenderer();
30+
virtual QgsRasterInterface * clone() const = 0;
3031

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

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

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

@@ -123,6 +126,7 @@ class QgsSingleBandPseudoColorRenderer: QgsRasterRenderer
123126
/**Note: takes ownership of QgsRasterShader*/
124127
QgsSingleBandPseudoColorRenderer( QgsRasterDataProvider* provider, int band, QgsRasterShader* shader );
125128
~QgsSingleBandPseudoColorRenderer();
129+
QgsRasterInterface * clone();
126130

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

@@ -145,6 +149,7 @@ class QgsSingleBandGrayRenderer: QgsRasterRenderer
145149
public:
146150
QgsSingleBandGrayRenderer( QgsRasterDataProvider* provider, int grayBand );
147151
~QgsSingleBandGrayRenderer();
152+
QgsRasterInterface * clone();
148153

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

@@ -169,6 +174,7 @@ class QgsSingleBandColorDataRenderer: QgsRasterRenderer
169174
public:
170175
QgsSingleBandColorDataRenderer( QgsRasterDataProvider* provider, int band );
171176
~QgsSingleBandColorDataRenderer();
177+
QgsRasterInterface * clone();
172178

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

python/core/qgsrasterresampler.sip

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ class QgsRasterResampler
1919
public:
2020
virtual void resample( const QImage& srcImage, QImage& dstImage ) = 0;
2121
virtual QString type() const = 0;
22+
virtual QgsRasterResampler * clone() const = 0;
2223
};
2324

2425
class QgsBilinearRasterResampler: QgsRasterResampler
@@ -32,6 +33,7 @@ class QgsBilinearRasterResampler: QgsRasterResampler
3233

3334
void resample( const QImage& srcImage, QImage& dstImage );
3435
QString type() const;
36+
QgsRasterResampler * clone() const;
3537
};
3638

3739
class QgsCubicRasterResampler: QgsRasterResampler
@@ -44,4 +46,5 @@ class QgsCubicRasterResampler: QgsRasterResampler
4446
~QgsCubicRasterResampler();
4547
void resample( const QImage& srcImage, QImage& dstImage );
4648
QString type() const;
49+
QgsRasterResampler * clone() const;
4750
};

src/app/qgisapp.cpp

Lines changed: 47 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3937,20 +3937,59 @@ void QgisApp::saveAsRasterFile()
39373937

39383938
QProgressDialog pd( 0, tr( "Abort..." ), 0, 0 );
39393939
pd.setWindowModality( Qt::WindowModal );
3940-
QgsRasterDataProvider* provider = rasterLayer->dataProvider();
3941-
if ( !provider )
3940+
3941+
// TODO: show error dialogs
3942+
// TODO: this code should go somewhere else, but probably not into QgsRasterFileWriter
3943+
// clone pipe/provider is not really necessary, ready for threads
3944+
QgsRasterPipe* pipe = 0;
3945+
3946+
if ( d.mode() == QgsRasterLayerSaveAsDialog::RawDataMode )
39423947
{
3943-
return;
3948+
QgsDebugMsg( "Writing raw data" );
3949+
//QgsDebugMsg( QString( "Writing raw data" ).arg( pos ) );
3950+
pipe = new QgsRasterPipe();
3951+
if ( !pipe->set( rasterLayer->dataProvider()->clone() ) )
3952+
{
3953+
QgsDebugMsg( "Cannot set pipe provider" );
3954+
return;
3955+
}
3956+
// add projector if necessary
3957+
if ( d.outputCrs() != rasterLayer->dataProvider()->crs() )
3958+
{
3959+
QgsRasterProjector * projector = new QgsRasterProjector;
3960+
projector->setCRS( rasterLayer->dataProvider()->crs(), d.outputCrs() );
3961+
if ( !pipe->set( projector ) )
3962+
{
3963+
QgsDebugMsg( "Cannot set pipe projector" );
3964+
return;
3965+
}
3966+
}
3967+
}
3968+
else // RenderedImageMode
3969+
{
3970+
// clone the whole pipe
3971+
QgsDebugMsg( "Writing rendered image" );
3972+
pipe = new QgsRasterPipe( *rasterLayer->pipe() );
3973+
QgsRasterProjector *projector = pipe->projector();
3974+
if ( !projector )
3975+
{
3976+
QgsDebugMsg( "Cannot get pipe projector" );
3977+
delete pipe;
3978+
return;
3979+
}
3980+
projector->setCRS( rasterLayer->dataProvider()->crs(), d.outputCrs() );
39443981
}
3945-
QgsRasterIterator iterator( provider );
3946-
int nRows = -1; //calculate number of rows such that pixels are squares
3947-
if ( provider->capabilities() & QgsRasterDataProvider::ExactResolution )
3982+
3983+
if ( !pipe->last() )
39483984
{
3949-
nRows = d.nRows();
3985+
delete pipe;
3986+
return;
39503987
}
3988+
QgsRasterIterator iterator( pipe->last() );
39513989
fileWriter.setCreateOptions( d.createOptions() );
39523990

3953-
fileWriter.writeRaster( &iterator, d.nColumns(), nRows, d.outputRectangle(), d.outputCrs(), &pd );
3991+
fileWriter.writeRaster( &iterator, d.nColumns(), d.nRows(), d.outputRectangle(), d.outputCrs(), &pd );
3992+
delete pipe;
39543993
}
39553994
}
39563995

src/core/qgsrasterdataprovider.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ class CORE_EXPORT QgsRasterDataProvider : public QgsDataProvider, public QgsRast
108108

109109
virtual ~QgsRasterDataProvider() {};
110110

111-
QgsRasterInterface * srcInput() { return this; }
111+
virtual QgsRasterInterface * clone() const = 0;
112112

113113
/* It makes no sense to set input on provider */
114114
bool setInput( QgsRasterInterface* input ) { Q_UNUSED( input ); return false; }

src/core/qgsrasterprojector.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,13 @@ QgsRasterProjector::QgsRasterProjector()
6666
QgsDebugMsg( "Entered" );
6767
}
6868

69+
QgsRasterInterface * QgsRasterProjector::clone() const
70+
{
71+
QgsDebugMsg( "Entered" );
72+
QgsRasterProjector * projector = new QgsRasterProjector( mSrcCRS, mDestCRS, mMaxSrcXRes, mMaxSrcYRes, mExtent );
73+
return projector;
74+
}
75+
6976
QgsRasterProjector::~QgsRasterProjector()
7077
{
7178
delete[] pHelperTop;
@@ -104,6 +111,8 @@ void QgsRasterProjector::calc()
104111
pHelperBottom = 0;
105112

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

623632
if ( !inputData ) return 0;
624633

625-
// ARGB32 only for now
626-
int pixelSize = 4;
634+
int pixelSize = mInput->typeSize( mInput->dataType( bandNo ) ) / 8;
627635

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

src/core/qgsrasterprojector.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ class CORE_EXPORT QgsRasterProjector : public QgsRasterInterface
6161
/** \brief The destructor */
6262
~QgsRasterProjector();
6363

64+
QgsRasterInterface * clone() const;
65+
6466
int bandCount() const;
6567

6668
QgsRasterInterface::DataType dataType( int bandNo ) const;

src/core/raster/qgsbilinearrasterresampler.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ QgsBilinearRasterResampler::~QgsBilinearRasterResampler()
2727
{
2828
}
2929

30+
QgsRasterResampler * QgsBilinearRasterResampler::clone() const
31+
{
32+
return new QgsBilinearRasterResampler();
33+
}
34+
3035
void QgsBilinearRasterResampler::resample( const QImage& srcImage, QImage& dstImage )
3136
{
3237
dstImage = srcImage.scaled( dstImage.width(), dstImage.height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation );

src/core/raster/qgsbilinearrasterresampler.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class CORE_EXPORT QgsBilinearRasterResampler: public QgsRasterResampler
2929

3030
void resample( const QImage& srcImage, QImage& dstImage );
3131
QString type() const { return "bilinear"; }
32+
QgsRasterResampler * clone() const;
3233
};
3334

3435
#endif // QGSBILINEARRASTERRESAMPLER_H

src/core/raster/qgscontrastenhancement.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,35 @@ QgsContrastEnhancement::QgsContrastEnhancement( QgsRasterDataType theDataType )
5252

5353
}
5454

55+
QgsContrastEnhancement::QgsContrastEnhancement( const QgsContrastEnhancement& ce )
56+
{
57+
mLookupTable = 0;
58+
mEnhancementDirty = ce.mEnhancementDirty;
59+
mContrastEnhancementAlgorithm = ce.mContrastEnhancementAlgorithm;
60+
mRasterDataType = ce.mRasterDataType;
61+
62+
mMinimumValue = ce.mMinimumValue;
63+
mMaximumValue = ce.mMaximumValue;
64+
mRasterDataTypeRange = ce.mRasterDataTypeRange;
65+
66+
mLookupTableOffset = ce.mLookupTableOffset;
67+
68+
mContrastEnhancementFunction = new QgsContrastEnhancementFunction( mRasterDataType, mMinimumValue, mMaximumValue );
69+
70+
//If the data type is larger than 16-bit do not generate a lookup table
71+
if ( mRasterDataTypeRange <= 65535.0 )
72+
{
73+
mLookupTable = new int[static_cast <int>( mRasterDataTypeRange+1 )];
74+
if ( !ce.mEnhancementDirty )
75+
{
76+
for ( int myIterator = 0; myIterator <= mRasterDataTypeRange; myIterator++ )
77+
{
78+
mLookupTable[myIterator] = ce.mLookupTable[myIterator];
79+
}
80+
}
81+
}
82+
}
83+
5584
QgsContrastEnhancement::~QgsContrastEnhancement()
5685
{
5786
}

src/core/raster/qgscontrastenhancement.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ class CORE_EXPORT QgsContrastEnhancement
7373
};
7474

7575
QgsContrastEnhancement( QgsContrastEnhancement::QgsRasterDataType theDatatype = QGS_Byte );
76+
QgsContrastEnhancement( const QgsContrastEnhancement& ce );
7677
~QgsContrastEnhancement();
7778

7879
/*

src/core/raster/qgscontrastenhancementfunction.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,13 @@ QgsContrastEnhancementFunction::QgsContrastEnhancementFunction( QgsContrastEnhan
2626
mMinimumMaximumRange = mMaximumValue - mMinimumValue;
2727
}
2828

29+
QgsContrastEnhancementFunction::QgsContrastEnhancementFunction( const QgsContrastEnhancementFunction& f )
30+
{
31+
mQgsRasterDataType = f.mQgsRasterDataType;
32+
mMaximumValue = f.mMaximumValue;
33+
mMinimumValue = f.mMinimumValue;
34+
mMinimumMaximumRange = f.mMinimumMaximumRange;
35+
}
2936

3037
int QgsContrastEnhancementFunction::enhance( double theValue )
3138
{

src/core/raster/qgscontrastenhancementfunction.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class CORE_EXPORT QgsContrastEnhancementFunction
3232

3333
public:
3434
QgsContrastEnhancementFunction( QgsContrastEnhancement::QgsRasterDataType, double, double );
35+
QgsContrastEnhancementFunction( const QgsContrastEnhancementFunction& f );
3536
virtual ~QgsContrastEnhancementFunction() {}
3637

3738
/** \brief A customizable method that takes in a double and returns a int between 0 and 255 */

src/core/raster/qgscubicrasterresampler.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ QgsCubicRasterResampler::~QgsCubicRasterResampler()
2727
{
2828
}
2929

30+
QgsRasterResampler * QgsCubicRasterResampler::clone() const
31+
{
32+
return new QgsCubicRasterResampler();
33+
}
34+
3035
void QgsCubicRasterResampler::resample( const QImage& srcImage, QImage& dstImage )
3136
{
3237
int nCols = srcImage.width();

src/core/raster/qgscubicrasterresampler.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class CORE_EXPORT QgsCubicRasterResampler: public QgsRasterResampler
2626
public:
2727
QgsCubicRasterResampler();
2828
~QgsCubicRasterResampler();
29+
QgsRasterResampler * clone() const;
2930
void resample( const QImage& srcImage, QImage& dstImage );
3031
QString type() const { return "cubic"; }
3132

0 commit comments

Comments
 (0)