~ubuntu-branches/ubuntu/trusty/gnuradio/trusty

« back to all changes in this revision

Viewing changes to gr-qtgui/src/lib/plot_waterfall.cc

  • Committer: Bazaar Package Importer
  • Author(s): Kamal Mostafa
  • Date: 2010-03-13 07:46:01 UTC
  • mfrom: (2.1.2 sid)
  • Revision ID: james.westby@ubuntu.com-20100313074601-zjsa893a87bozyh7
Tags: 3.2.2.dfsg-1ubuntu1
* Fix build for Ubuntu lucid (LP: #260406)
  - add binary package dep for libusrp0, libusrp2-0: adduser
  - debian/rules clean: remove pre-built Qt moc files

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <qimage.h>
 
2
#include <qpen.h>
 
3
#include <qpainter.h>
 
4
#include "qwt_painter.h"
 
5
#include "qwt_double_interval.h"
 
6
#include "qwt_scale_map.h"
 
7
#include "qwt_color_map.h"
 
8
#include "plot_waterfall.h"
 
9
 
 
10
#if QT_VERSION < 0x040000
 
11
typedef Q3ValueVector<QRgb> QwtColorTable;
 
12
#else
 
13
typedef QVector<QRgb> QwtColorTable;
 
14
#endif
 
15
 
 
16
 
 
17
class PlotWaterfallImage: public QImage
 
18
{
 
19
    // This class hides some Qt3/Qt4 API differences
 
20
public:
 
21
    PlotWaterfallImage(const QSize &size, QwtColorMap::Format format):
 
22
#if QT_VERSION < 0x040000
 
23
        QImage(size, format == QwtColorMap::RGB ? 32 : 8)
 
24
#else
 
25
        QImage(size, format == QwtColorMap::RGB
 
26
               ? QImage::Format_ARGB32 : QImage::Format_Indexed8 )
 
27
#endif
 
28
        {
 
29
        }
 
30
 
 
31
    PlotWaterfallImage(const QImage &other):
 
32
        QImage(other)
 
33
        {
 
34
        }
 
35
 
 
36
    void initColorTable(const QImage& other)
 
37
        {
 
38
#if QT_VERSION < 0x040000
 
39
            const unsigned int numColors = other.numColors();
 
40
 
 
41
            setNumColors(numColors);
 
42
            for ( unsigned int i = 0; i < numColors; i++ )
 
43
                setColor(i, other.color(i));
 
44
#else
 
45
            setColorTable(other.colorTable());
 
46
#endif
 
47
        }
 
48
 
 
49
#if QT_VERSION < 0x040000
 
50
 
 
51
    void setColorTable(const QwtColorTable &colorTable)
 
52
        {
 
53
            setNumColors(colorTable.size());
 
54
            for ( unsigned int i = 0; i < colorTable.size(); i++ )
 
55
                setColor(i, colorTable[i]);
 
56
        }
 
57
 
 
58
    QwtColorTable colorTable() const
 
59
        {
 
60
            QwtColorTable table(numColors());
 
61
            for ( int i = 0; i < numColors(); i++ )
 
62
                table[i] = color(i);
 
63
 
 
64
            return table;
 
65
        }
 
66
#endif
 
67
};
 
68
 
 
69
class PlotWaterfall::PrivateData
 
70
{
 
71
public:
 
72
    PrivateData()
 
73
        {
 
74
            data = NULL;
 
75
            colorMap = new QwtLinearColorMap();
 
76
        }
 
77
    ~PrivateData()
 
78
        {
 
79
            delete colorMap;
 
80
        }
 
81
 
 
82
    WaterfallData *data;
 
83
    QwtColorMap *colorMap;
 
84
};
 
85
 
 
86
/*!
 
87
  Sets the following item attributes:
 
88
  - QwtPlotItem::AutoScale: true
 
89
  - QwtPlotItem::Legend:    false
 
90
 
 
91
  The z value is initialized by 8.0.
 
92
   
 
93
  \param title Title
 
94
 
 
95
  \sa QwtPlotItem::setItemAttribute(), QwtPlotItem::setZ()
 
96
*/
 
97
PlotWaterfall::PlotWaterfall(WaterfallData* data, const QString &title):
 
98
    QwtPlotRasterItem(title)
 
99
{
 
100
    d_data = new PrivateData();
 
101
    d_data->data = data;
 
102
 
 
103
//    setCachePolicy(QwtPlotRasterItem::PaintCache);
 
104
 
 
105
    setItemAttribute(QwtPlotItem::AutoScale, true);
 
106
    setItemAttribute(QwtPlotItem::Legend, false);
 
107
 
 
108
    setZ(8.0);
 
109
}
 
110
 
 
111
//! Destructor
 
112
PlotWaterfall::~PlotWaterfall()
 
113
{
 
114
    delete d_data;
 
115
}
 
116
 
 
117
const WaterfallData* PlotWaterfall::data()const{
 
118
    return d_data->data;
 
119
}
 
120
 
 
121
//! \return QwtPlotItem::Rtti_PlotSpectrogram
 
122
int PlotWaterfall::rtti() const
 
123
{
 
124
    return QwtPlotItem::Rtti_PlotSpectrogram;
 
125
}
 
126
 
 
127
/*!
 
128
  Change the color map
 
129
 
 
130
  Often it is useful to display the mapping between intensities and
 
131
  colors as an additional plot axis, showing a color bar.
 
132
 
 
133
  \param colorMap Color Map
 
134
 
 
135
  \sa colorMap(), QwtScaleWidget::setColorBarEnabled(),
 
136
  QwtScaleWidget::setColorMap()
 
137
*/
 
138
void PlotWaterfall::setColorMap(const QwtColorMap &colorMap)
 
139
{
 
140
    delete d_data->colorMap;
 
141
    d_data->colorMap = colorMap.copy();
 
142
 
 
143
    invalidateCache();
 
144
    itemChanged();
 
145
}
 
146
 
 
147
/*!
 
148
  \return Color Map used for mapping the intensity values to colors
 
149
  \sa setColorMap()
 
150
*/
 
151
const QwtColorMap &PlotWaterfall::colorMap() const
 
152
{
 
153
    return *d_data->colorMap;
 
154
}
 
155
/*!
 
156
  \return Bounding rect of the data
 
157
  \sa QwtRasterData::boundingRect
 
158
*/
 
159
QwtDoubleRect PlotWaterfall::boundingRect() const
 
160
{
 
161
    return d_data->data->boundingRect();
 
162
}
 
163
 
 
164
/*!
 
165
  \brief Returns the recommended raster for a given rect.
 
166
 
 
167
  F.e the raster hint is used to limit the resolution of
 
168
  the image that is rendered.
 
169
 
 
170
  \param rect Rect for the raster hint
 
171
  \return data().rasterHint(rect)
 
172
*/
 
173
QSize PlotWaterfall::rasterHint(const QwtDoubleRect &rect) const
 
174
{
 
175
    return d_data->data->rasterHint(rect);
 
176
}
 
177
 
 
178
/*!
 
179
  \brief Render an image from the data and color map.
 
180
 
 
181
  The area is translated into a rect of the paint device. 
 
182
  For each pixel of this rect the intensity is mapped
 
183
  into a color.
 
184
 
 
185
  \param xMap X-Scale Map
 
186
  \param yMap Y-Scale Map
 
187
  \param area Area that should be rendered in scale coordinates.
 
188
 
 
189
  \return A QImage::Format_Indexed8 or QImage::Format_ARGB32 depending 
 
190
  on the color map.
 
191
 
 
192
  \sa QwtRasterData::intensity(), QwtColorMap::rgb(),
 
193
  QwtColorMap::colorIndex()
 
194
*/
 
195
QImage PlotWaterfall::renderImage(
 
196
    const QwtScaleMap &xMap, const QwtScaleMap &yMap, 
 
197
    const QwtDoubleRect &area) const
 
198
{
 
199
    if ( area.isEmpty() )
 
200
        return QImage();
 
201
 
 
202
    QRect rect = transform(xMap, yMap, area);
 
203
 
 
204
    QwtScaleMap xxMap = xMap;
 
205
    QwtScaleMap yyMap = yMap;
 
206
 
 
207
    const QSize res = d_data->data->rasterHint(area);
 
208
    if ( res.isValid() )
 
209
    {
 
210
        /*
 
211
          It is useless to render an image with a higher resolution
 
212
          than the data offers. Of course someone will have to
 
213
          scale this image later into the size of the given rect, but f.e.
 
214
          in case of postscript this will done on the printer.
 
215
        */
 
216
        rect.setSize(rect.size().boundedTo(res));
 
217
 
 
218
        int px1 = rect.x();
 
219
        int px2 = rect.x() + rect.width();
 
220
        if ( xMap.p1() > xMap.p2() )
 
221
            qSwap(px1, px2);
 
222
 
 
223
        double sx1 = area.x();
 
224
        double sx2 = area.x() + area.width();
 
225
        if ( xMap.s1() > xMap.s2() )
 
226
            qSwap(sx1, sx2);
 
227
 
 
228
        int py1 = rect.y();
 
229
        int py2 = rect.y() + rect.height();
 
230
        if ( yMap.p1() > yMap.p2() )
 
231
            qSwap(py1, py2);
 
232
 
 
233
        double sy1 = area.y();
 
234
        double sy2 = area.y() + area.height();
 
235
        if ( yMap.s1() > yMap.s2() )
 
236
            qSwap(sy1, sy2);
 
237
 
 
238
        xxMap.setPaintInterval(px1, px2);
 
239
        xxMap.setScaleInterval(sx1, sx2);
 
240
        yyMap.setPaintInterval(py1, py2);
 
241
        yyMap.setScaleInterval(sy1, sy2); 
 
242
    }
 
243
 
 
244
    PlotWaterfallImage image(rect.size(), d_data->colorMap->format());
 
245
 
 
246
    const QwtDoubleInterval intensityRange = d_data->data->range();
 
247
    if ( !intensityRange.isValid() )
 
248
        return image;
 
249
 
 
250
    d_data->data->initRaster(area, rect.size());
 
251
 
 
252
    if ( d_data->colorMap->format() == QwtColorMap::RGB )
 
253
    {
 
254
        for ( int y = rect.top(); y <= rect.bottom(); y++ )
 
255
        {
 
256
            const double ty = yyMap.invTransform(y);
 
257
 
 
258
            QRgb *line = (QRgb *)image.scanLine(y - rect.top());
 
259
            for ( int x = rect.left(); x <= rect.right(); x++ )
 
260
            {
 
261
                const double tx = xxMap.invTransform(x);
 
262
 
 
263
                *line++ = d_data->colorMap->rgb(intensityRange,
 
264
                                                d_data->data->value(tx, ty));
 
265
            }
 
266
        }
 
267
    }
 
268
    else if ( d_data->colorMap->format() == QwtColorMap::Indexed )
 
269
    {
 
270
        image.setColorTable(d_data->colorMap->colorTable(intensityRange));
 
271
 
 
272
        for ( int y = rect.top(); y <= rect.bottom(); y++ )
 
273
        {
 
274
            const double ty = yyMap.invTransform(y);
 
275
 
 
276
            unsigned char *line = image.scanLine(y - rect.top());
 
277
            for ( int x = rect.left(); x <= rect.right(); x++ )
 
278
            {
 
279
                const double tx = xxMap.invTransform(x);
 
280
 
 
281
                *line++ = d_data->colorMap->colorIndex(intensityRange,
 
282
                                                       d_data->data->value(tx, ty));
 
283
            }
 
284
        }
 
285
    }
 
286
 
 
287
    d_data->data->discardRaster();
 
288
 
 
289
    // Mirror the image in case of inverted maps
 
290
 
 
291
    const bool hInvert = xxMap.p1() > xxMap.p2();
 
292
    const bool vInvert = yyMap.p1() < yyMap.p2();
 
293
    if ( hInvert || vInvert )
 
294
    {
 
295
#ifdef __GNUC__
 
296
#endif
 
297
#if QT_VERSION < 0x040000
 
298
        image = image.mirror(hInvert, vInvert);
 
299
#else
 
300
        image = image.mirrored(hInvert, vInvert);
 
301
#endif
 
302
    }
 
303
 
 
304
    return image;
 
305
}
 
306
 
 
307
/*!
 
308
  \brief Draw the spectrogram
 
309
 
 
310
  \param painter Painter
 
311
  \param xMap Maps x-values into pixel coordinates.
 
312
  \param yMap Maps y-values into pixel coordinates.
 
313
  \param canvasRect Contents rect of the canvas in painter coordinates 
 
314
 
 
315
  \sa setDisplayMode, renderImage, 
 
316
  QwtPlotRasterItem::draw, drawContourLines
 
317
*/
 
318
 
 
319
void PlotWaterfall::draw(QPainter *painter,
 
320
                         const QwtScaleMap &xMap, const QwtScaleMap &yMap,
 
321
                         const QRect &canvasRect) const
 
322
{
 
323
    QwtPlotRasterItem::draw(painter, xMap, yMap, canvasRect);
 
324
}
 
325