10#include "qwt_plot_spectrogram.h" 
   11#include "qwt_painter.h" 
   12#include "qwt_interval.h" 
   13#include "qwt_scale_map.h" 
   14#include "qwt_color_map.h" 
   22#include <qtconcurrentrun.h> 
   27#include <qelapsedtimer.h> 
   32static inline bool qwtIsNaN( 
double d )
 
   37    const uchar* ch = (
const uchar*)&d;
 
   38    if ( QSysInfo::ByteOrder == QSysInfo::BigEndian )
 
   40        return ( ch[0] & 0x7f ) == 0x7f && ch[1] > 0xf0;
 
   44        return ( ch[7] & 0x7f ) == 0x7f && ch[6] > 0xf0;
 
   48class QwtPlotSpectrogram::PrivateData
 
   70    void updateColorTable()
 
   78            if ( colorTableSize == 0 )
 
   81                colorTable = colorMap->
colorTable( colorTableSize );
 
   90    QPen defaultContourPen;
 
  111    m_data = 
new PrivateData();
 
 
  143    if ( on != 
bool( mode & m_data->displayMode ) )
 
  146            m_data->displayMode |= mode;
 
  148            m_data->displayMode &= ~mode;
 
 
  163    return ( m_data->displayMode & mode );
 
 
  184        delete m_data->colorMap;
 
  188    m_data->updateColorTable();
 
 
  202    return m_data->colorMap;
 
 
  226    numColors = qMax( numColors, 0 );
 
  227    if ( numColors != m_data->colorTableSize )
 
  229        m_data->colorTableSize = numColors;
 
  230        m_data->updateColorTable();
 
 
  240    return m_data->colorTableSize;
 
 
  257    const QColor& color, qreal width, Qt::PenStyle style )
 
 
  274    if ( pen != m_data->defaultContourPen )
 
  276        m_data->defaultContourPen = pen;
 
 
  289    return m_data->defaultContourPen;
 
 
  305    if ( m_data->data == NULL || m_data->colorMap == NULL )
 
  309    const QColor c( m_data->colorMap->
rgb( intensityRange, level ) );
 
 
  327    if ( 
bool( m_data->conrecFlags & flag ) == on )
 
  331        m_data->conrecFlags |= flag;
 
  333        m_data->conrecFlags &= ~flag;
 
 
  353    return m_data->conrecFlags & flag;
 
 
  367    m_data->contourLevels = levels;
 
  368    std::sort( m_data->contourLevels.begin(), m_data->contourLevels.end() );
 
 
  384    return m_data->contourLevels;
 
 
  395    if ( 
data != m_data->data )
 
 
  434    if ( m_data->data == NULL )
 
  437    return m_data->data->
interval( axis );
 
 
  458    if ( m_data->data == NULL )
 
 
  482    const QRectF& area, 
const QSize& imageSize )
 const 
  484    if ( imageSize.isEmpty() || m_data->data == NULL
 
  485        || m_data->colorMap == NULL )
 
  491    if ( !intensityRange.
isValid() )
 
  494    const QImage::Format format = ( m_data->colorMap->format() == 
QwtColorMap::RGB )
 
  495        ? QImage::Format_ARGB32 : QImage::Format_Indexed8;
 
  497    QImage image( imageSize, format );
 
  502    m_data->data->
initRaster( area, image.size() );
 
  509#if !defined( QT_NO_QFUTURE ) 
  512    if ( numThreads <= 0 )
 
  513        numThreads = QThread::idealThreadCount();
 
  515    if ( numThreads <= 0 )
 
  518    const int numRows = imageSize.height() / numThreads;
 
  521    futures.reserve( numThreads - 1 );
 
  523    for ( uint i = 0; i < numThreads; i++ )
 
  525        QRect tile( 0, i * numRows, image.width(), numRows );
 
  526        if ( i == numThreads - 1 )
 
  528            tile.setHeight( image.height() - i * numRows );
 
  533            futures += QtConcurrent::run(
 
  534#
if QT_VERSION >= 0x060000
 
  539                xMap, yMap, tile, &image );
 
  543    for ( 
int i = 0; i < futures.size(); i++ )
 
  544        futures[i].waitForFinished();
 
  547    const QRect tile( 0, 0, image.width(), image.height() );
 
  552    const qint64 elapsed = time.elapsed();
 
  553    qDebug() << 
"renderImage" << imageSize << elapsed;
 
 
  574    const QRect& tile, QImage* image )
 const 
  577    if ( range.
width() <= 0.0 )
 
  584        const int numColors = m_data->colorTable.size();
 
  585        const QRgb* rgbTable = m_data->colorTable.constData();
 
  588        for ( 
int y = tile.top(); y <= tile.bottom(); y++ )
 
  592            QRgb* line = 
reinterpret_cast< QRgb* 
>( image->scanLine( y ) );
 
  595            for ( 
int x = tile.left(); x <= tile.right(); x++ )
 
  599                const double value = m_data->data->
value( tx, ty );
 
  601                if ( hasGaps && qwtIsNaN( value ) )
 
  605                else if ( numColors == 0 )
 
  612                    *line++ = rgbTable[index];
 
  619        for ( 
int y = tile.top(); y <= tile.bottom(); y++ )
 
  623            unsigned char* line = image->scanLine( y );
 
  626            for ( 
int x = tile.left(); x <= tile.right(); x++ )
 
  630                const double value = m_data->data->
value( tx, ty );
 
  632                if ( hasGaps && qwtIsNaN( value ) )
 
  638                    const uint index = m_data->colorMap->
colorIndex( 256, range, value );
 
  639                    *line++ = 
static_cast< unsigned char >( index );
 
 
  664    const QRectF& area, 
const QRect& rect )
 const 
  666    QSize raster = rect.size() / 2;
 
  668    const QRectF pixelRect = 
pixelHint( area );
 
  669    if ( !pixelRect.isEmpty() )
 
  671        const QSize res( qwtCeil( rect.width() / pixelRect.width() ),
 
  672            qwtCeil( rect.height() / pixelRect.height() ) );
 
  673        raster = raster.boundedTo( res );
 
 
  690    const QRectF& rect, 
const QSize& raster )
 const 
  692    if ( m_data->data == NULL )
 
  696        m_data->contourLevels, m_data->conrecFlags );
 
 
  713    if ( m_data->data == NULL )
 
  716    const int numLevels = m_data->contourLevels.size();
 
  717    for ( 
int l = 0; l < numLevels; l++ )
 
  719        const double level = m_data->contourLevels[l];
 
  722        if ( pen.style() == Qt::NoPen )
 
  725        if ( pen.style() == Qt::NoPen )
 
  728        painter->setPen( pen );
 
  730        const QPolygonF& lines = contourLines[level];
 
  731        for ( 
int i = 0; i < lines.size(); i += 2 )
 
  733            const QPointF p1( xMap.
transform( lines[i].x() ),
 
  735            const QPointF p2( xMap.
transform( lines[i + 1].x() ),
 
 
  756    const QRectF& canvasRect )
 const 
  764        const int margin = 2;
 
  765        QRectF rasterRect( canvasRect.x() - margin, canvasRect.y() - margin,
 
  766            canvasRect.width() + 2 * margin, canvasRect.height() + 2 * margin );
 
  774            if ( area.isEmpty() )
 
  781        raster = raster.boundedTo( rasterRect.toRect().size() );
 
  782        if ( raster.isValid() )
 
 
QwtColorMap is used to map values into colors.
virtual uint colorIndex(int numColors, const QwtInterval &interval, double value) const
Map a value of a given interval into a color index.
@ RGB
The map is intended to map into RGB values.
virtual QVector< QRgb > colorTable(int numColors) const
virtual QVector< QRgb > colorTable256() const
virtual QRgb rgb(const QwtInterval &interval, double value) const =0
A class representing an interval.
double width() const
Return the width of an interval.
QwtLinearColorMap builds a color map from color stops.
static void drawLine(QPainter *, qreal x1, qreal y1, qreal x2, qreal y2)
Wrapper for QPainter::drawLine()
virtual void legendChanged()
void setZ(double z)
Set the z value.
void setItemAttribute(ItemAttribute, bool on=true)
@ Rtti_PlotSpectrogram
For QwtPlotSpectrogram.
virtual void itemChanged()
@ Legend
The item is represented on the legend.
uint renderThreadCount() const
A class, which displays raster data.
virtual void draw(QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect) const override
Draw the raster data.
virtual QRectF boundingRect() const override
void setColorTableSize(int numColors)
virtual QPen contourPen(double level) const
Calculate the pen for a contour line.
QFlags< DisplayMode > DisplayModes
virtual QSize contourRasterSize(const QRectF &, const QRect &) const
Return the raster to be used by the CONREC contour algorithm.
virtual QwtRasterData::ContourLines renderContourLines(const QRectF &rect, const QSize &raster) const
QList< double > contourLevels() const
virtual QRectF pixelHint(const QRectF &) const override
Pixel hint.
void setDisplayMode(DisplayMode, bool on=true)
virtual QwtInterval interval(Qt::Axis) const override
void setColorMap(QwtColorMap *)
void setContourLevels(const QList< double > &)
void setData(QwtRasterData *data)
bool testConrecFlag(QwtRasterData::ConrecFlag) const
virtual void drawContourLines(QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QwtRasterData::ContourLines &) const
void renderTile(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRect &tile, QImage *) const
Render a tile of an image.
@ ContourMode
The data is displayed using contour lines.
@ ImageMode
The values are mapped to colors using a color map.
int colorTableSize() const
QwtPlotSpectrogram(const QString &title=QString())
const QwtRasterData * data() const
const QwtColorMap * colorMap() const
bool testDisplayMode(DisplayMode) const
virtual void draw(QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect) const override
Draw the spectrogram.
void setConrecFlag(QwtRasterData::ConrecFlag, bool on)
virtual int rtti() const override
virtual ~QwtPlotSpectrogram()
Destructor.
void setDefaultContourPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)
virtual QImage renderImage(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &area, const QSize &imageSize) const override
Render an image from data and color map.
QPen defaultContourPen() const
QwtRasterData defines an interface to any type of raster data.
virtual QRectF pixelHint(const QRectF &) const
Pixel hint.
bool testAttribute(Attribute) const
QMap< double, QPolygonF > ContourLines
Contour lines.
QFlags< ConrecFlag > ConrecFlags
virtual void discardRaster()
Discard a raster.
virtual double value(double x, double y) const =0
virtual void initRaster(const QRectF &, const QSize &raster)
Initialize a raster.
virtual ContourLines contourLines(const QRectF &rect, const QSize &raster, const QList< double > &levels, ConrecFlags) const
virtual QwtInterval interval(Qt::Axis) const =0
ConrecFlag
Flags to modify the contour algorithm.
@ IgnoreOutOfRange
Ignore all values, that are out of range.
@ IgnoreAllVerticesOnLevel
Ignore all vertices on the same level.
double transform(double s) const
double invTransform(double p) const