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> 
   24 #define DEBUG_RENDER 0 
   27 #include <qelapsedtimer.h> 
   32 static 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;
 
   48 class QwtPlotSpectrogram::PrivateData
 
   70     void updateColorTable()
 
  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 )
 
  308     const QwtInterval intensityRange = m_data->data->interval(Qt::ZAxis);
 
  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 )
 
  461     return m_data->data->pixelHint( area );
 
  482     const QRectF& area, 
const QSize& imageSize )
 const 
  484     if ( imageSize.isEmpty() || m_data->data == NULL
 
  485         || m_data->colorMap == NULL )
 
  490     const QwtInterval intensityRange = m_data->data->interval( Qt::ZAxis );
 
  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 );
 
  500         image.setColorTable( m_data->colorMap->colorTable256() );
 
  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;
 
  556     m_data->data->discardRaster();
 
  574     const QRect& tile, QImage* image )
 const 
  576     const QwtInterval range = m_data->data->interval( Qt::ZAxis );
 
  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 )
 
  695     return m_data->data->contourLines( rect, raster,
 
  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.
QMap< double, QPolygonF > ContourLines
Contour lines.
QFlags< ConrecFlag > ConrecFlags
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