091223_qgis_raster.diff

Improved patch. Also fetches the WMS layers in several parts - Marco Hugentobler, 2009-12-23 03:53 AM

Download (22.4 KB)

View differences:

src/app/composer/qgscomposer.cpp (working copy)
574 574
  int width = ( int )( mComposition->printResolution() * mComposition->paperWidth() / 25.4 );
575 575
  int height = ( int )( mComposition-> printResolution() * mComposition->paperHeight() / 25.4 );
576 576

  
577
  int memuse = width * height * 3 / 1000000;  // pixmap + image
577
  int memuse = width * height * 4 / 1000000;  // pixmap + image
578 578
  QgsDebugMsg( QString( "Image %1 x %2" ).arg( width ).arg( height ) );
579 579
  QgsDebugMsg( QString( "memuse = %1" ).arg( memuse ) );
580 580

  
src/core/raster/qgsrasterlayer.cpp (working copy)
22 22
#include "qgsmaptopixel.h"
23 23
#include "qgsproviderregistry.h"
24 24
#include "qgsrasterbandstats.h"
25
#include "qgsrasterimagebuffer.h"
25 26
#include "qgsrasterlayer.h"
26 27
#include "qgsrasterpyramid.h"
27 28
#include "qgsrectangle.h"
......
1578 1579

  
1579 1580
    mDataProvider->setDpi( rendererContext.rasterScaleFactor() * 25.4 * rendererContext.scaleFactor() );
1580 1581

  
1581
    QImage* image =
1582
      mDataProvider->draw(
1583
        myRasterExtent,
1584
        // Below should calculate to the actual pixel size of the
1585
        // part of the layer that's visible.
1586
        static_cast<int>( fabs(( myRasterViewPort->clippedXMax -  myRasterViewPort->clippedXMin )
1587
                               / theQgsMapToPixel.mapUnitsPerPixel() * mGeoTransform[1] ) + 1 ),
1588
        static_cast<int>( fabs(( myRasterViewPort->clippedYMax -  myRasterViewPort->clippedYMin )
1589
                               / theQgsMapToPixel.mapUnitsPerPixel() * mGeoTransform[5] ) + 1 )
1590
//                         myRasterViewPort->drawableAreaXDim,
1591
//                         myRasterViewPort->drawableAreaYDim
1592
      );
1582
    //fetch image in several parts if it is too memory consuming
1583
    //also some WMS servers have a pixel limit, so it's better to make several requests
1584
    int totalPixelWidth = fabs(( myRasterViewPort->clippedXMax -  myRasterViewPort->clippedXMin )
1585
                               / theQgsMapToPixel.mapUnitsPerPixel() * mGeoTransform[1] ) + 1;
1586
    int totalPixelHeight = fabs(( myRasterViewPort->clippedYMax -  myRasterViewPort->clippedYMin )
1587
                               / theQgsMapToPixel.mapUnitsPerPixel() * mGeoTransform[5] ) + 1;
1588
    int numParts = totalPixelWidth * totalPixelHeight / 2000000 + 1.0;
1589
    int numRowsPerPart = totalPixelHeight / numParts + 1.0;
1593 1590

  
1594
    if ( !image )
1591

  
1592
    int currentPixelOffsetY = 0; //top y-coordinate of current raster part
1593
    //the width of a WMS image part
1594
    int pixelWidth = (myRasterExtent.xMaximum() - myRasterExtent.xMinimum()) / theQgsMapToPixel.mapUnitsPerPixel();
1595
    for(int i = 0; i < numParts; ++i)
1595 1596
    {
1596
      // An error occurred.
1597
      mErrorCaption = mDataProvider->lastErrorTitle();
1598
      mError        = mDataProvider->lastError();
1597
      //fetch a small overlap of 2 pixels between two adjacent tiles to avoid white stripes
1598
      QgsRectangle rasterPartRect(myRasterExtent.xMinimum(), myRasterExtent.yMaximum() - (currentPixelOffsetY + numRowsPerPart + 2) * theQgsMapToPixel.mapUnitsPerPixel(), \
1599
                                  myRasterExtent.xMaximum(), myRasterExtent.yMaximum() - currentPixelOffsetY * theQgsMapToPixel.mapUnitsPerPixel());
1599 1600

  
1600
      delete myRasterViewPort;
1601
      return FALSE;
1602
    }
1601
      int pixelHeight = rasterPartRect.height() / theQgsMapToPixel.mapUnitsPerPixel();
1602
      QImage* image = mDataProvider->draw(rasterPartRect, pixelWidth, pixelHeight);
1603 1603

  
1604
    QgsDebugMsg( "Done mDataProvider->draw." );
1605
    QgsDebugMsg( "image stats: " );
1604
      if ( !image )
1605
      {
1606
        // An error occurred.
1607
        mErrorCaption = mDataProvider->lastErrorTitle();
1608
        mError        = mDataProvider->lastError();
1606 1609

  
1607
    QgsDebugMsg( QString( "depth=%1" ).arg( image->depth() ) );
1608
    QgsDebugMsg( QString( "bytes=%1" ).arg( image->numBytes() ) );
1609
    QgsDebugMsg( QString( "width=%1" ).arg( image->width() ) );
1610
    QgsDebugMsg( QString( "height=%1" ).arg( image->height() ) );
1610
        delete myRasterViewPort;
1611
        return FALSE;
1612
      }
1611 1613

  
1612
    QgsDebugMsg( "Want to theQPainter->drawImage with" );
1614
      QgsDebugMsg( "Done mDataProvider->draw." );
1615
      QgsDebugMsg( "image stats: " );
1613 1616

  
1614
    QgsDebugMsg( QString( "origin x: %1" ).arg( myRasterViewPort->topLeftPoint.x() ) );
1615
    QgsDebugMsg( QString( "(int)origin x: %1" ).arg( static_cast<int>( myRasterViewPort->topLeftPoint.x() ) ) );
1616
    QgsDebugMsg( QString( "origin y: %1" ).arg( myRasterViewPort->topLeftPoint.y() ) );
1617
    QgsDebugMsg( QString( "(int)origin y: %1" ).arg( static_cast<int>( myRasterViewPort->topLeftPoint.y() ) ) );
1617
      QgsDebugMsg( QString( "depth=%1" ).arg( image->depth() ) );
1618
      QgsDebugMsg( QString( "bytes=%1" ).arg( image->numBytes() ) );
1619
      QgsDebugMsg( QString( "width=%1" ).arg( image->width() ) );
1620
      QgsDebugMsg( QString( "height=%1" ).arg( image->height() ) );
1618 1621

  
1619
    //Set the transparency for the whole layer
1620
    //QImage::setAlphaChannel does not work quite as expected so set each pixel individually
1621
    //Currently this is only done for WMS images, which should be small enough not to impact performance
1622
      QgsDebugMsg( "Want to theQPainter->drawImage with" );
1622 1623

  
1623
    if ( mTransparencyLevel != 255 ) //improve performance if layer transparency not altered
1624
    {
1625
      QImage* transparentImageCopy = new QImage( *image ); //copy image if there is user transparency
1626
      image = transparentImageCopy;
1627
      int myWidth = image->width();
1628
      int myHeight = image->height();
1629
      QRgb myRgb;
1630
      int newTransparency;
1631
      for ( int myHeightRunner = 0; myHeightRunner < myHeight; myHeightRunner++ )
1624
      QgsDebugMsg( QString( "origin x: %1" ).arg( myRasterViewPort->topLeftPoint.x() ) );
1625
      QgsDebugMsg( QString( "(int)origin x: %1" ).arg( static_cast<int>( myRasterViewPort->topLeftPoint.x() ) ) );
1626
      QgsDebugMsg( QString( "origin y: %1" ).arg( myRasterViewPort->topLeftPoint.y() ) );
1627
      QgsDebugMsg( QString( "(int)origin y: %1" ).arg( static_cast<int>( myRasterViewPort->topLeftPoint.y() ) ) );
1628

  
1629
      //Set the transparency for the whole layer
1630
      //QImage::setAlphaChannel does not work quite as expected so set each pixel individually
1631
      //Currently this is only done for WMS images, which should be small enough not to impact performance
1632

  
1633
      if ( mTransparencyLevel != 255 ) //improve performance if layer transparency not altered
1632 1634
      {
1633
        QRgb* myLineBuffer = ( QRgb* ) transparentImageCopy->scanLine( myHeightRunner );
1634
        for ( int myWidthRunner = 0; myWidthRunner < myWidth; myWidthRunner++ )
1635
        QImage* transparentImageCopy = new QImage( *image ); //copy image if there is user transparency
1636
        image = transparentImageCopy;
1637
        int myWidth = image->width();
1638
        int myHeight = image->height();
1639
        QRgb myRgb;
1640
        int newTransparency;
1641
        for ( int myHeightRunner = 0; myHeightRunner < myHeight; myHeightRunner++ )
1635 1642
        {
1636
          myRgb = image->pixel( myWidthRunner, myHeightRunner );
1637
          //combine transparency from WMS and layer transparency
1638
          newTransparency = ( double ) mTransparencyLevel / 255.0 * ( double )( qAlpha( myRgb ) );
1639
          myLineBuffer[ myWidthRunner ] = qRgba( qRed( myRgb ), qGreen( myRgb ), qBlue( myRgb ), newTransparency );
1643
          QRgb* myLineBuffer = ( QRgb* ) transparentImageCopy->scanLine( myHeightRunner );
1644
          for ( int myWidthRunner = 0; myWidthRunner < myWidth; myWidthRunner++ )
1645
          {
1646
            myRgb = image->pixel( myWidthRunner, myHeightRunner );
1647
            //combine transparency from WMS and layer transparency
1648
            newTransparency = ( double ) mTransparencyLevel / 255.0 * ( double )( qAlpha( myRgb ) );
1649
            myLineBuffer[ myWidthRunner ] = qRgba( qRed( myRgb ), qGreen( myRgb ), qBlue( myRgb ), newTransparency );
1650
          }
1640 1651
        }
1641 1652
      }
1642
    }
1643 1653

  
1644
    // Since GDAL's RasterIO can't handle floating point, we have to round to
1645
    // the nearest pixel.  Add 0.5 to get rounding instead of truncation
1646
    // out of static_cast<int>.
1647
    theQPainter->drawImage( static_cast<int>(
1648
                              myRasterViewPort->topLeftPoint.x()
1649
                              + 0.5    // try simulating rounding instead of truncation, to avoid off-by-one errors
1650
                              // TODO: Check for rigorous correctness
1651
                            ),
1652
                            static_cast<int>(
1653
                              myRasterViewPort->topLeftPoint.y()
1654
                              + 0.5    // try simulating rounding instead of truncation, to avoid off-by-one errors
1655
                              // TODO: Check for rigorous correctness
1656
                            ),
1657
                            *image );
1654
      theQPainter->drawImage(myRasterViewPort->topLeftPoint.x(), myRasterViewPort->topLeftPoint.y() + currentPixelOffsetY, *image);
1655
      currentPixelOffsetY += numRowsPerPart;
1658 1656

  
1659
    if ( mTransparencyLevel != 255 )
1660
    {
1661
      delete image;
1657
          if ( mTransparencyLevel != 255 )
1658
      {
1659
        delete image;
1660
      }
1661

  
1662
      emit statusChanged( tr( "%1 retrieved using %2" ).arg( name() ).arg( mProviderKey ) );
1662 1663
    }
1663

  
1664
    emit statusChanged( tr( "%1 retrieved using %2" ).arg( name() ).arg( mProviderKey ) );
1665 1664
  }
1666 1665
  else
1667 1666
  {
......
2917 2916

  
2918 2917
  // Only do this for the non-provider (hard-coded GDAL) scenario...
2919 2918
  // Maybe WMS can do this differently using QImage::numColors and QImage::color()
2920
  if ( mProviderKey.isEmpty() && hasBand( "Palette" ) && theBandNumber > 0 ) //dont tr() this its a gdal word!
2919
  if ( mProviderKey.isEmpty() && hasBand( "Palette" ) && theBandNumber > 0 ) //don't tr() this its a gdal word!
2921 2920
  {
2922 2921
    QgsDebugMsg( "....found paletted image" );
2923 2922
    QgsColorRampShader myShader;
......
2977 2976
  GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, theBandNo );
2978 2977
  QgsRasterBandStats myRasterBandStats = bandStatistics( theBandNo );
2979 2978
  //calculate the histogram for this band
2980
  //we assume that it only needs to be calculated if the lenght of the histogram
2979
  //we assume that it only needs to be calculated if the length of the histogram
2981 2980
  //vector is not equal to the number of bins
2982 2981
  //i.e if the histogram has never previously been generated or the user has
2983 2982
  //selected a new number of bins.
......
3786 3785
  {
3787 3786
    QgsColorRampShader* myColorRampShader = ( QgsColorRampShader* ) mRasterShader->rasterShaderFunction();
3788 3787

  
3789
    //TODO: Remove the customColorRampType check and following if() in v2.0, added for compatability with older ( bugged ) project files
3788
    //TODO: Remove the customColorRampType check and following if() in v2.0, added for compatibility with older ( bugged ) project files
3790 3789
    QDomNode customColorRampTypeNode = customColorRampNode.namedItem( "customColorRampType" );
3791 3790
    QDomNode colorRampTypeNode = customColorRampNode.namedItem( "colorRampType" );
3792 3791
    QString myRampType = "";
......
4505 4504

  
4506 4505
  GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, theBandNo );
4507 4506
  GDALDataType myDataType = GDALGetRasterDataType( myGdalBand );
4507
  QgsRasterImageBuffer imageBuffer( myGdalBand, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
4508
  imageBuffer.reset();
4509

  
4510
  QRgb* imageScanLine = 0;
4511
  void* rasterScanLine = 0;
4512

  
4513
  QRgb myDefaultColor = qRgba( 255, 255, 255, 0 );
4514
  double myPixelValue = 0.0;
4515
  int myRedValue = 0;
4516
  int myGreenValue = 0;
4517
  int myBlueValue = 0;
4518
  int myAlphaValue = 0;
4519

  
4520
  while( imageBuffer.nextScanLine( &imageScanLine, &rasterScanLine ) )
4521
  {
4522
    for( int i = 0; i < theRasterViewPort->drawableAreaXDim; ++i )
4523
    {
4524
        myRedValue = 0; myGreenValue = 0; myBlueValue = 0;
4525
        myPixelValue = readValue( rasterScanLine, ( GDALDataType )myDataType, i);
4526

  
4527
        if ( mValidNoDataValue && ( fabs( myPixelValue - mNoDataValue ) <= TINY_VALUE || myPixelValue != myPixelValue ) )
4528
        {
4529
            imageScanLine[ i ] = myDefaultColor;
4530
            continue;
4531
        }
4532

  
4533
        myAlphaValue = mRasterTransparency.alphaValue( myPixelValue, mTransparencyLevel );
4534
        if ( 0 == myAlphaValue )
4535
        {
4536
            imageScanLine[ i ] = myDefaultColor;
4537
            continue;
4538
        }
4539

  
4540
        if ( !mRasterShader->shade( myPixelValue, &myRedValue, &myGreenValue, &myBlueValue ) )
4541
        {
4542
            imageScanLine[ i ] = myDefaultColor;
4543
            continue;
4544
        }
4545

  
4546
        if ( mInvertColor )
4547
        {
4548
            //Invert flag, flip blue and read
4549
            imageScanLine[ i ] = qRgba( myBlueValue, myGreenValue, myRedValue, myAlphaValue );
4550
        }
4551
        else
4552
        {
4553
            //Normal
4554
            imageScanLine[ i ] = qRgba( myRedValue, myGreenValue, myBlueValue, myAlphaValue );
4555
        }
4556
    }
4557
  }
4558

  
4559
#if 0
4560

  
4561

  
4508 4562
  void *myGdalScanData = readData( myGdalBand, theRasterViewPort );
4509 4563

  
4510 4564
  /* Check for out of memory error */
......
4568 4622
  CPLFree( myGdalScanData );
4569 4623

  
4570 4624
  paintImageToCanvas( theQPainter, theRasterViewPort, theQgsMapToPixel, &myQImage );
4625
#endif //0
4571 4626
}
4572 4627

  
4573 4628
/**
......
5314 5369
    mRasterType = Multiband;
5315 5370
  }
5316 5371
  //TODO hasBand is really obsolete and only used in the Palette instance, change to new function hasPalette(int)
5317
  else if ( hasBand( "Palette" ) ) //dont tr() this its a gdal word!
5372
  else if ( hasBand( "Palette" ) ) //don't tr() this its a gdal word!
5318 5373
  {
5319 5374
    mRasterType = Palette;
5320 5375
  }
src/core/raster/qgsrasterimagebuffer.cpp (revision 0)
1
/***************************************************************************
2
    qgsrasterimagebuffer.cpp
3
    ------------------------
4
    begin                : December 2009
5
    copyright            : (C) 2009 by Marco Hugentobler
6
    email                : marco at hugis dot net
7
 ***************************************************************************
8
 *                                                                         *
9
 *   This program is free software; you can redistribute it and/or modify  *
10
 *   it under the terms of the GNU General Public License as published by  *
11
 *   the Free Software Foundation; either version 2 of the License, or     *
12
 *   (at your option) any later version.                                   *
13
 *                                                                         *
14
 ***************************************************************************/
15

  
16
#include "qgsrasterimagebuffer.h"
17
#include "qgsmaptopixel.h"
18
#include "qgsrasterviewport.h"
19
#include <QImage>
20
#include <QPainter>
21
#include <gdal.h>
22
#include "cpl_conv.h"
23

  
24
#ifndef Q_OS_MACX
25
#include <cmath>
26
#else
27
#include <math.h>
28
#endif
29

  
30

  
31
QgsRasterImageBuffer::QgsRasterImageBuffer(GDALRasterBandH rasterBand, QPainter* p, QgsRasterViewPort* viewPort, const QgsMapToPixel* mapToPixel, double* geoTransform): \
32
mRasterBand(rasterBand), mPainter(p), mViewPort(viewPort), mMapToPixel(mapToPixel), mValid(false), mCurrentImage(0), mCurrentGDALData(0), mGeoTransform(geoTransform)
33
{
34

  
35
}
36

  
37
QgsRasterImageBuffer::~QgsRasterImageBuffer()
38
{
39
    delete mCurrentImage;
40
    CPLFree(mCurrentGDALData);
41
}
42

  
43
void QgsRasterImageBuffer::reset()
44
{
45
    if( mRasterBand && mPainter && mViewPort && mMapToPixel )
46
    {
47
        mValid = true;
48
    }
49
    else
50
    {
51
        mValid = false;
52
        return;
53
    }
54

  
55
    //decide on the partition of the image
56

  
57
    int pixels = mViewPort->drawableAreaXDim * mViewPort->drawableAreaYDim;
58
    int mNumPartImages = std::max(pixels / 50000000.0, 1.0);
59
    mNumRasterRowsPerPart = (double)mViewPort->clippedHeight / (double)mNumPartImages + 0.5;
60

  
61
    mCurrentPartRasterMin = -1;
62
    mCurrentPartRasterMax = -1;
63
    mCurrentPartImageRow = 0;
64
    mNumCurrentImageRows = 0;
65

  
66
    createNextPartImage();
67
}
68

  
69
bool QgsRasterImageBuffer::nextScanLine(QRgb** imageScanLine, void** rasterScanLine)
70
{
71
    if(!mValid)
72
    {
73
        return false;
74
    }
75

  
76
    if( !mCurrentGDALData || ! mCurrentImage )
77
    {
78
        return false;
79
    }
80

  
81
    if(mCurrentPartImageRow >= (mNumCurrentImageRows))
82
    {
83
        if(!createNextPartImage())
84
        {
85
            return false;
86
        }
87
    }
88

  
89
    *imageScanLine = ( QRgb* )(mCurrentImage->scanLine(mCurrentPartImageRow));
90
    GDALDataType type = GDALGetRasterDataType( mRasterBand );
91
    int size = GDALGetDataTypeSize( type ) / 8;
92
    *rasterScanLine = mCurrentGDALData + mCurrentPartImageRow * mViewPort->drawableAreaXDim * size;
93

  
94
    ++mCurrentPartImageRow;
95
    ++mCurrentRow;
96
    return true;
97
}
98

  
99
bool QgsRasterImageBuffer::createNextPartImage()
100
{
101
    //draw the last image if mCurrentImage if it exists
102
    if(mCurrentImage)
103
    {
104
        double xLeft = mViewPort->topLeftPoint.x();
105
        double yTop = mViewPort->topLeftPoint.y() + fabs(mGeoTransform[5]) * mCurrentPartRasterMin / mMapToPixel->mapUnitsPerPixel();
106
        mPainter->drawImage(QPointF(xLeft, yTop), *mCurrentImage);
107
    }
108

  
109
    delete mCurrentImage; mCurrentImage = 0;
110
    CPLFree(mCurrentGDALData); mCurrentGDALData = 0;
111

  
112
    if(mCurrentPartRasterMax >= mViewPort->clippedHeight)
113
    {
114
        return false; //already at the end...
115
    }
116

  
117
    mCurrentPartRasterMin = mCurrentPartRasterMax + 1;
118
    mCurrentPartRasterMax = mCurrentPartRasterMin + mNumRasterRowsPerPart;
119
    if(mCurrentPartRasterMax > mViewPort->clippedHeight)
120
    {
121
        mCurrentPartRasterMax = mViewPort->clippedHeight;
122
    }
123
    mCurrentRow = mCurrentPartRasterMin;
124
    mCurrentPartImageRow = 0;
125

  
126
    //read GDAL image data
127
    GDALDataType type = GDALGetRasterDataType( mRasterBand );
128
    int size = GDALGetDataTypeSize( type ) / 8;
129
    int xSize = mViewPort->drawableAreaXDim;
130

  
131
    //make the raster tiles overlap at least 2 pixels to avoid white stripes
132
    int overlapRows = 0;
133
    overlapRows = mMapToPixel->mapUnitsPerPixel() / fabs(mGeoTransform[5]) + 2;
134
    if(mCurrentPartRasterMax + overlapRows >= mViewPort->clippedHeight)
135
    {
136
      overlapRows = 0;
137
    }
138
    int rasterYSize = mCurrentPartRasterMax - mCurrentPartRasterMin + overlapRows;
139

  
140
    int ySize = fabs(( (rasterYSize) / mMapToPixel->mapUnitsPerPixel() * mGeoTransform[5] ) ) + 0.5;
141
    if(ySize == 0)
142
    {
143
      return false;
144
    }
145
    mNumCurrentImageRows = ySize;
146
    mCurrentGDALData = VSIMalloc(size * xSize * ySize);
147
    CPLErr myErr = GDALRasterIO( mRasterBand, GF_Read, mViewPort->rectXOffset, \
148
                       mViewPort->rectYOffset + mCurrentRow, mViewPort->clippedWidth, rasterYSize, \
149
                       mCurrentGDALData, xSize, ySize, type, 0, 0);
150

  
151
    if ( myErr != CPLE_None )
152
    {
153
        CPLFree(mCurrentGDALData);
154
        mCurrentGDALData = 0;
155
        return false;
156
    }
157

  
158
    //create the QImage
159
    mCurrentImage = new QImage( xSize, ySize, QImage::Format_ARGB32 );
160
    mCurrentImage->fill(qRgba(255, 255, 255, 0));
161
    return true;
162
}
163

  
src/core/raster/qgsrasterimagebuffer.h (revision 0)
1
/***************************************************************************
2
    qgsrasterimagebuffer.h
3
    ---------------------
4
    begin                : December 2009
5
    copyright            : (C) 2009 by Marco Hugentobler
6
    email                : marco at hugis dot net
7
 ***************************************************************************
8
 *                                                                         *
9
 *   This program is free software; you can redistribute it and/or modify  *
10
 *   it under the terms of the GNU General Public License as published by  *
11
 *   the Free Software Foundation; either version 2 of the License, or     *
12
 *   (at your option) any later version.                                   *
13
 *                                                                         *
14
 ***************************************************************************/
15

  
16
#ifndef QGSRASTERIMAGEBUFFER_H
17
#define QGSRASTERIMAGEBUFFER_H
18

  
19
#include <QColor>
20

  
21
typedef void* GDALRasterBandH;
22
class QgsMapToPixel;
23
struct QgsRasterViewPort;
24
class QImage;
25
class QPainter;
26

  
27
/**A class encapsulates reading from a raster band and drawing the pixels to a painter.
28
   The class allows sequential reading of the scan lines and setting the image scan line pixels. It automatically decides
29
   on how much of the band / image should stay in virtual memory at a time*/
30
class QgsRasterImageBuffer
31
{
32
    public:
33
        QgsRasterImageBuffer(GDALRasterBandH rasterBand, QPainter* p, \
34
                             QgsRasterViewPort* viewPort, const QgsMapToPixel* mapToPixel, double* mGeoTransform);
35
        ~QgsRasterImageBuffer();
36
        void reset();
37
        /**Returns a pointer to the next scan line (or 0 if end)*/
38
        bool nextScanLine(QRgb** imageScanLine, void** rasterScanLine);
39

  
40
    private:
41
        QgsRasterImageBuffer(); //forbidden
42
        /**Creates next part image. Returns false if at end*/
43
        bool createNextPartImage();
44

  
45
        GDALRasterBandH mRasterBand; //raster band
46
        QPainter* mPainter;
47
        QgsRasterViewPort* mViewPort;
48
        const QgsMapToPixel* mMapToPixel;
49
        double* mGeoTransform;
50

  
51
        bool mValid;
52
        int mCurrentRow;
53
        int mNumPartImages; //number of part images
54
        int mNumRasterRowsPerPart; //number of (raster source) rows per part
55
        int mCurrentPartRasterMin; //minimum (raster source) row of current image
56
        int mCurrentPartRasterMax; //maximum (raster source) row of current image
57
        int mCurrentPartImageRow; //current image row
58
        int mNumCurrentImageRows; //number of image rows for the current part
59

  
60
        //current memory image and gdal scan data
61
        QImage* mCurrentImage;
62
        void* mCurrentGDALData;
63
};
64

  
65
#endif // QGSRASTERIMAGEBUFFER_H
src/core/CMakeLists.txt (working copy)
110 110
  raster/qgslinearminmaxenhancement.cpp
111 111
  raster/qgslinearminmaxenhancementwithclip.cpp
112 112
  raster/qgspseudocolorshader.cpp
113
  raster/qgsrasterimagebuffer.cpp
113 114
  raster/qgsrasterlayer.cpp
114 115
  raster/qgsrastertransparency.cpp
115 116
  raster/qgsrastershader.cpp