comparison layer/Colour3DPlotLayer.cpp @ 159:c1fb771b7646

* Various improvements to colour 3d plot layer, particularly for large and/or dense plots. Still a work in progress
author Chris Cannam
date Fri, 06 Oct 2006 16:53:25 +0000
parents 10eec0da9efe
children f4be20ebdfa4
comparison
equal deleted inserted replaced
158:9c3a4b42d8f8 159:c1fb771b7646
30 30
31 31
32 Colour3DPlotLayer::Colour3DPlotLayer() : 32 Colour3DPlotLayer::Colour3DPlotLayer() :
33 Layer(), 33 Layer(),
34 m_model(0), 34 m_model(0),
35 m_cache(0) 35 m_cache(0),
36 m_colourScale(LinearScale)
36 { 37 {
37 38
38 } 39 }
39 40
40 Colour3DPlotLayer::~Colour3DPlotLayer() 41 Colour3DPlotLayer::~Colour3DPlotLayer()
72 Colour3DPlotLayer::cacheInvalid(size_t, size_t) 73 Colour3DPlotLayer::cacheInvalid(size_t, size_t)
73 { 74 {
74 cacheInvalid(); 75 cacheInvalid();
75 } 76 }
76 77
78 Layer::PropertyList
79 Colour3DPlotLayer::getProperties() const
80 {
81 PropertyList list;
82 list.push_back("Colour Scale");
83 return list;
84 }
85
86 QString
87 Colour3DPlotLayer::getPropertyLabel(const PropertyName &name) const
88 {
89 if (name == "Colour Scale") return tr("Colour Scale");
90 return "";
91 }
92
93 Layer::PropertyType
94 Colour3DPlotLayer::getPropertyType(const PropertyName &name) const
95 {
96 return ValueProperty;
97 }
98
99 QString
100 Colour3DPlotLayer::getPropertyGroupName(const PropertyName &name) const
101 {
102 return QString();
103 }
104
105 int
106 Colour3DPlotLayer::getPropertyRangeAndValue(const PropertyName &name,
107 int *min, int *max) const
108 {
109 int deft = 0;
110
111 int garbage0, garbage1;
112 if (!min) min = &garbage0;
113 if (!max) max = &garbage1;
114
115 if (name == "Colour Scale") {
116
117 *min = 0;
118 *max = 3;
119
120 deft = (int)m_colourScale;
121
122 } else {
123 deft = Layer::getPropertyRangeAndValue(name, min, max);
124 }
125
126 return deft;
127 }
128
129 QString
130 Colour3DPlotLayer::getPropertyValueLabel(const PropertyName &name,
131 int value) const
132 {
133 if (name == "Colour Scale") {
134 switch (value) {
135 default:
136 case 0: return tr("Linear");
137 case 1: return tr("Absolute");
138 case 2: return tr("Meter");
139 case 3: return tr("dB");
140 }
141 }
142 return tr("<unknown>");
143 }
144
145 void
146 Colour3DPlotLayer::setProperty(const PropertyName &name, int value)
147 {
148 if (name == "Colour Scale") {
149 switch (value) {
150 default:
151 case 0: setColourScale(LinearScale); break;
152 case 1: setColourScale(AbsoluteScale); break;
153 case 2: setColourScale(MeterScale); break;
154 case 3: setColourScale(dBScale); break;
155 }
156 }
157 }
158
159 void
160 Colour3DPlotLayer::setColourScale(ColourScale scale)
161 {
162 if (m_colourScale == scale) return;
163 m_colourScale = scale;
164 cacheInvalid();
165 emit layerParametersChanged();
166 }
167
77 bool 168 bool
78 Colour3DPlotLayer::isLayerScrollable(const View *v) const 169 Colour3DPlotLayer::isLayerScrollable(const View *v) const
79 { 170 {
80 QPoint discard; 171 QPoint discard;
81 return !v->shouldIlluminateLocalFeatures(this, discard); 172 return !v->shouldIlluminateLocalFeatures(this, discard);
90 int y = pos.y(); 181 int y = pos.y();
91 182
92 size_t modelStart = m_model->getStartFrame(); 183 size_t modelStart = m_model->getStartFrame();
93 size_t modelResolution = m_model->getResolution(); 184 size_t modelResolution = m_model->getResolution();
94 185
186 float srRatio =
187 float(v->getViewManager()->getMainModelSampleRate()) /
188 float(m_model->getSampleRate());
189
95 int sx0 = modelResolution * 190 int sx0 = modelResolution *
96 int((v->getFrameForX(x) - long(modelStart)) / long(modelResolution)); 191 int((v->getFrameForX(x) / srRatio - long(modelStart)) / long(modelResolution));
97 int sx1 = sx0 + modelResolution; 192 int sx1 = sx0 + modelResolution;
98 193
99 float binHeight = float(v->height()) / m_model->getYBinCount(); 194 float binHeight = float(v->height()) / m_model->getYBinCount();
100 int sy = (v->height() - y) / binHeight; 195 int sy = (v->height() - y) / binHeight;
101 196
102 float value = m_model->getBinValue(sx0, sy); 197 float value = m_model->getBinValue(sx0, sy);
198
199 // std::cerr << "bin value (" << sx0 << "," << sy << ") is " << value << std::endl;
103 200
104 QString binName = m_model->getBinName(sy); 201 QString binName = m_model->getBinName(sy);
105 if (binName == "") binName = QString("[%1]").arg(sy + 1); 202 if (binName == "") binName = QString("[%1]").arg(sy + 1);
106 else binName = QString("%1 [%2]").arg(binName).arg(sy + 1); 203 else binName = QString("%1 [%2]").arg(binName).arg(sy + 1);
107 204
115 212
116 return text; 213 return text;
117 } 214 }
118 215
119 int 216 int
217 Colour3DPlotLayer::getColourScaleWidth(QPainter &paint) const
218 {
219 int cw = 20;
220 return cw;
221 }
222
223 int
120 Colour3DPlotLayer::getVerticalScaleWidth(View *v, QPainter &paint) const 224 Colour3DPlotLayer::getVerticalScaleWidth(View *v, QPainter &paint) const
121 { 225 {
122 if (!m_model) return 0; 226 if (!m_model) return 0;
123 227
124 QString sampleText = QString("[%1]").arg(m_model->getYBinCount()); 228 QString sampleText = QString("[%1]").arg(m_model->getYBinCount());
133 } 237 }
134 if (another) { 238 if (another) {
135 tw = std::max(tw, paint.fontMetrics().width(sampleText)); 239 tw = std::max(tw, paint.fontMetrics().width(sampleText));
136 } 240 }
137 241
138 return tw + 13; 242 return tw + 13 + getColourScaleWidth(paint);
139 } 243 }
140 244
141 void 245 void
142 Colour3DPlotLayer::paintVerticalScale(View *v, QPainter &paint, QRect rect) const 246 Colour3DPlotLayer::paintVerticalScale(View *v, QPainter &paint, QRect rect) const
143 { 247 {
144 if (!m_model) return; 248 if (!m_model) return;
145 249
146 int h = rect.height(), w = rect.width(); 250 int h = rect.height(), w = rect.width();
147 float binHeight = float(v->height()) / m_model->getYBinCount(); 251 float binHeight = float(v->height()) / m_model->getYBinCount();
252
253 int cw = getColourScaleWidth(paint);
254
255 int ch = h - 20;
256 if (ch > 20 && m_cache) {
257
258 paint.setPen(Qt::black);
259 paint.drawRect(4, 10, cw - 8, ch - 19);
260
261 for (int y = 0; y < ch - 20; ++y) {
262 QRgb c = m_cache->color(((ch - 20 - y) * 255) / (ch - 20));
263 // std::cerr << "y = " << y << ": rgb " << qRed(c) << "," << qGreen(c) << "," << qBlue(c) << std::endl;
264 paint.setPen(QColor(qRed(c), qGreen(c), qBlue(c)));
265 paint.drawLine(5, 11 + y, cw - 5, 11 + y);
266 }
267 }
268
269 paint.setPen(Qt::black);
148 270
149 int count = v->height() / paint.fontMetrics().height(); 271 int count = v->height() / paint.fontMetrics().height();
150 int step = m_model->getYBinCount() / count; 272 int step = m_model->getYBinCount() / count;
151 if (step == 0) step = 1; 273 if (step == 0) step = 1;
152 274
157 int y0 = v->height() - (i * binHeight) - 1; 279 int y0 = v->height() - (i * binHeight) - 1;
158 280
159 QString text = m_model->getBinName(i); 281 QString text = m_model->getBinName(i);
160 if (text == "") text = QString("[%1]").arg(i + 1); 282 if (text == "") text = QString("[%1]").arg(i + 1);
161 283
162 paint.drawLine(0, y0, w, y0); 284 paint.drawLine(cw, y0, w, y0);
163 285
164 int cy = y0 - (step * binHeight)/2; 286 int cy = y0 - (step * binHeight)/2;
165 int ty = cy + paint.fontMetrics().ascent()/2; 287 int ty = cy + paint.fontMetrics().ascent()/2;
166 288
167 paint.drawText(10, ty, text); 289 paint.drawText(cw + 5, ty, text);
168 } 290 }
169 } 291 }
170 292
171 void 293 void
172 Colour3DPlotLayer::paint(View *v, QPainter &paint, QRect rect) const 294 Colour3DPlotLayer::paint(View *v, QPainter &paint, QRect rect) const
173 { 295 {
174 // Profiler profiler("Colour3DPlotLayer::paint"); 296 // Profiler profiler("Colour3DPlotLayer::paint");
175 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT 297 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT
176 std::cerr << "Colour3DPlotLayer::paint(): m_model is " << m_model << ", zoom level is " << v->getZoomLevel() << std::endl; 298 std::cerr << "Colour3DPlotLayer::paint(): m_model is " << m_model << ", zoom level is " << v->getZoomLevel() << std::endl;
177 #endif 299 #endif
178
179 //!!! This doesn't yet accommodate the fact that the model may
180 //have a different sample rate from an underlying model. At the
181 //moment our paint mechanism assumes all models have the same
182 //sample rate. If that isn't the case, they won't align and the
183 //time ruler will match whichever model was used to construct it.
184 //Obviously it is not going to be the case in general that models
185 //will have the same samplerate, so we need a pane samplerate as
186 //well which we trivially realign to. (We can probably require
187 //the waveform and spectrogram layers to display at the pane
188 //samplerate.)
189 300
190 int completion = 0; 301 int completion = 0;
191 if (!m_model || !m_model->isOK() || !m_model->isReady(&completion)) { 302 if (!m_model || !m_model->isOK() || !m_model->isReady(&completion)) {
192 if (completion > 0) { 303 if (completion > 0) {
193 paint.fillRect(0, 10, v->width() * completion / 100, 304 paint.fillRect(0, 10, v->width() * completion / 100,
209 320
210 delete m_cache; 321 delete m_cache;
211 m_cache = 0; 322 m_cache = 0;
212 } 323 }
213 324
214 if (!m_cache) { 325 if (!m_cache) {
215 326
216 m_cache = new QImage(cacheWidth, cacheHeight, QImage::Format_Indexed8); 327 m_cache = new QImage(cacheWidth, cacheHeight, QImage::Format_Indexed8);
328
329 std::cerr << "Cache size " << cacheWidth << "x" << cacheHeight << std::endl;
217 330
218 m_cache->setNumColors(256); 331 m_cache->setNumColors(256);
219 DenseThreeDimensionalModel::BinValueSet values; 332 DenseThreeDimensionalModel::BinValueSet values;
220 333
221 float min = m_model->getMinimumLevel(); 334 float min = m_model->getMinimumLevel();
222 float max = m_model->getMaximumLevel(); 335 float max = m_model->getMaximumLevel();
223 336
224 if (max == min) max = min + 1.0; 337 if (max == min) max = min + 1.0;
225 338
226 for (int value = 0; value < 256; ++value) { 339 int zeroIndex = 0;
227 int hue = 256 - value; 340 if (min < 0.f) {
228 QColor colour = QColor::fromHsv(hue, value/2 + 128, value); 341 if (m_colourScale == LinearScale) {
229 m_cache->setColor(value, qRgba(colour.red(), colour.green(), colour.blue(), 80)); 342 zeroIndex = int(((-min) * 256) / (max - min));
343 } else {
344 max = std::max(-min, max);
345 min = 0;
346 }
347 }
348 if (zeroIndex < 0) zeroIndex = 0;
349 if (zeroIndex > 255) zeroIndex = 255;
350
351 //!!! want this and spectrogram to share a colour mapping unit
352
353 for (int index = 0; index < 256; ++index) {
354 int effective = abs(((index - zeroIndex) * 255) /
355 std::max(255 - zeroIndex, zeroIndex));
356 int hue = 256 - effective;
357 if (zeroIndex > 0) {
358 if (index <= zeroIndex) hue = 255;
359 else hue = 0;
360 }
361 while (hue < 0) hue += 255;
362 while (hue > 255) hue -= 255;
363 int saturation = effective / 2 + 128;
364 if (saturation < 0) saturation = -saturation;
365 if (saturation > 255) saturation = 255;
366 int value = effective;
367 if (value < 0) value = -value;
368 if (value > 255) value = 255;
369 // std::cerr << "min: " << min << ", max: " << max << ", zi " << zeroIndex << ", index " << index << ": " << hue << ", " << saturation << ", " << value << std::endl;
370 QColor colour = QColor::fromHsv(hue, saturation, value);
371 // std::cerr << "rgb: " << colour.red() << "," << colour.green() << "," << colour.blue() << std::endl;
372 m_cache->setColor(index, qRgb(colour.red(), colour.green(), colour.blue()));
230 } 373 }
231 374
232 m_cache->fill(min); 375 m_cache->fill(zeroIndex);
233 376
234 for (size_t f = modelStart; f <= modelEnd; f += modelResolution) { 377 for (size_t f = modelStart; f <= modelEnd; f += modelResolution) {
235 378
236 values.clear(); 379 values.clear();
237 m_model->getBinValues(f, values); 380 m_model->getBinValues(f, values);
238 381
239 for (size_t y = 0; y < m_model->getYBinCount(); ++y) { 382 for (size_t y = 0; y < m_model->getYBinCount(); ++y) {
240 383
241 float value = min; 384 float value = min;
242 if (y < values.size()) value = values[y]; 385 if (y < values.size()) {
386 value = values[y];
387 if (m_colourScale != LinearScale) {
388 value = fabs(value);
389 }
390 }
243 391
244 int pixel = int(((value - min) * 256) / (max - min)); 392 int pixel = int(((value - min) * 256) / (max - min));
245 if (pixel < 0) pixel = 0; 393 if (pixel < 0) pixel = 0;
246 if (pixel > 255) pixel = 255; 394 if (pixel > 255) pixel = 255;
247 395
248 m_cache->setPixel(f / modelResolution, y, pixel); 396 m_cache->setPixel(f / modelResolution, y, pixel);
249 } 397 }
250 } 398 }
251 } 399 }
252 400
253 if (m_model->getYBinCount() >= v->height()) { 401 if (m_model->getYBinCount() >= v->height() ||
402 modelResolution < v->getZoomLevel() / 2) {
254 paintDense(v, paint, rect); 403 paintDense(v, paint, rect);
255 return; 404 return;
256 } 405 }
257 406
258 int x0 = rect.left(); 407 int x0 = rect.left();
259 int x1 = rect.right() + 1; 408 int x1 = rect.right() + 1;
260 409
261 int w = x1 - x0;
262 int h = v->height(); 410 int h = v->height();
263 411
264 // The cache is from the model's start frame to the model's end 412 // The cache is from the model's start frame to the model's end
265 // frame at the model's window increment frames per pixel. We 413 // frame at the model's window increment frames per pixel. We
266 // want to draw from our start frame + x0 * zoomLevel to our start 414 // want to draw from our start frame + x0 * zoomLevel to our start
269 //!!! Strictly speaking we want quite different paint mechanisms 417 //!!! Strictly speaking we want quite different paint mechanisms
270 //for models that have more than one bin per pixel in either 418 //for models that have more than one bin per pixel in either
271 //direction. This one is only really appropriate for models with 419 //direction. This one is only really appropriate for models with
272 //far fewer bins in both directions. 420 //far fewer bins in both directions.
273 421
274 int sx0 = int((v->getFrameForX(x0) - long(modelStart)) / long(modelResolution)); 422 float srRatio =
275 int sx1 = int((v->getFrameForX(x1) - long(modelStart)) / long(modelResolution)); 423 float(v->getViewManager()->getMainModelSampleRate()) /
276 int sw = sx1 - sx0; 424 float(m_model->getSampleRate());
425
426 int sx0 = int((v->getFrameForX(x0) / srRatio - long(modelStart)) / long(modelResolution));
427 int sx1 = int((v->getFrameForX(x1) / srRatio - long(modelStart)) / long(modelResolution));
277 int sh = m_model->getYBinCount(); 428 int sh = m_model->getYBinCount();
278 429
279 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT 430 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT
280 std::cerr << "Colour3DPlotLayer::paint: w " << w << ", h " << h << ", sx0 " << sx0 << ", sx1 " << sx1 << ", sw " << sw << ", sh " << sh << std::endl; 431 std::cerr << "Colour3DPlotLayer::paint: w " << w << ", h " << h << ", sx0 " << sx0 << ", sx1 " << sx1 << ", sw " << sw << ", sh " << sh << std::endl;
281 std::cerr << "Colour3DPlotLayer: sample rate is " << m_model->getSampleRate() << ", resolution " << m_model->getResolution() << std::endl; 432 std::cerr << "Colour3DPlotLayer: sample rate is " << m_model->getSampleRate() << ", resolution " << m_model->getResolution() << std::endl;
290 int fx = sx * int(modelResolution); 441 int fx = sx * int(modelResolution);
291 442
292 if (fx + modelResolution < int(modelStart) || 443 if (fx + modelResolution < int(modelStart) ||
293 fx > int(modelEnd)) continue; 444 fx > int(modelEnd)) continue;
294 445
295 int rx0 = v->getXForFrame(fx + int(modelStart)); 446 int rx0 = v->getXForFrame((fx + int(modelStart)) * srRatio);
296 int rx1 = v->getXForFrame(fx + int(modelStart) + int(modelResolution)); 447 int rx1 = v->getXForFrame((fx + int(modelStart) + int(modelResolution) + 1) * srRatio);
297 448
298 int w = rx1 - rx0; 449 int rw = rx1 - rx0;
299 if (w < 1) w = 1; 450 if (rw < 1) rw = 1;
300 451
301 bool showLabel = (w > 10 && 452 bool showLabel = (rw > 10 &&
302 paint.fontMetrics().width("0.000000") < w - 3 && 453 paint.fontMetrics().width("0.000000") < rw - 3 &&
303 paint.fontMetrics().height() < (h / sh)); 454 paint.fontMetrics().height() < (h / sh));
304 455
305 for (int sy = 0; sy < sh; ++sy) { 456 for (int sy = 0; sy < sh; ++sy) {
306 457
307 int ry0 = h - (sy * h) / sh - 1; 458 int ry0 = h - (sy * h) / sh - 1;
309 if (sx >= 0 && sx < m_cache->width() && 460 if (sx >= 0 && sx < m_cache->width() &&
310 sy >= 0 && sy < m_cache->height()) { 461 sy >= 0 && sy < m_cache->height()) {
311 pixel = m_cache->pixel(sx, sy); 462 pixel = m_cache->pixel(sx, sy);
312 } 463 }
313 464
465 QRect r(rx0, ry0 - h / sh - 1, rw, h / sh + 1);
466
467 if (rw == 1) {
468 paint.setPen(pixel);
469 paint.setBrush(Qt::NoBrush);
470 paint.drawLine(r.x(), r.y(), r.x(), r.y() + r.height() - 1);
471 continue;
472 }
473
314 QColor pen(255, 255, 255, 80); 474 QColor pen(255, 255, 255, 80);
315 QColor brush(pixel); 475 QColor brush(pixel);
316 brush.setAlpha(160); 476
477 if (rw > 3 && r.height() > 3) {
478 brush.setAlpha(160);
479 }
480
317 paint.setPen(Qt::NoPen); 481 paint.setPen(Qt::NoPen);
318 paint.setBrush(brush); 482 paint.setBrush(brush);
319
320 QRect r(rx0, ry0 - h / sh - 1, w, h / sh + 1);
321 483
322 if (illuminate) { 484 if (illuminate) {
323 if (r.contains(illuminatePos)) { 485 if (r.contains(illuminatePos)) {
324 paint.setPen(Qt::black);//!!! 486 paint.setPen(Qt::black);//!!!
325 } 487 }
326 } 488 }
327 489
328 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT 490 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT
329 std::cerr << "rect " << rx0 << "," << (ry0 - h / sh - 1) << " " 491 std::cerr << "rect " << r.x() << "," << r.y() << " "
330 << w << "x" << (h / sh + 1) << std::endl; 492 << r.width() << "x" << r.height() << std::endl;
331 #endif 493 #endif
332 494
333 paint.drawRect(r); 495 paint.drawRect(r);
334 496
335 if (showLabel) { 497 if (showLabel) {
356 518
357 size_t modelStart = m_model->getStartFrame(); 519 size_t modelStart = m_model->getStartFrame();
358 size_t modelEnd = m_model->getEndFrame(); 520 size_t modelEnd = m_model->getEndFrame();
359 size_t modelResolution = m_model->getResolution(); 521 size_t modelResolution = m_model->getResolution();
360 522
523 float srRatio =
524 float(v->getViewManager()->getMainModelSampleRate()) /
525 float(m_model->getSampleRate());
526
361 int x0 = rect.left(); 527 int x0 = rect.left();
362 int x1 = rect.right() + 1; 528 int x1 = rect.right() + 1;
363 529
364 int w = x1 - x0; 530 int w = x1 - x0;
365 int h = v->height(); 531 int h = v->height();
367 533
368 QImage img(w, h, QImage::Format_RGB32); 534 QImage img(w, h, QImage::Format_RGB32);
369 535
370 for (int x = x0; x < x1; ++x) { 536 for (int x = x0; x < x1; ++x) {
371 537
372 long xf = v->getFrameForX(x); 538 long xf = v->getFrameForX(x) / srRatio;
373 if (xf < 0) { 539 if (xf < 0) {
374 for (int y = 0; y < h; ++y) { 540 for (int y = 0; y < h; ++y) {
375 img.setPixel(x - x0, y, m_cache->color(0)); 541 img.setPixel(x - x0, y, m_cache->color(0));
376 } 542 }
377 continue; 543 continue;
378 } 544 }
379 545
380 float sx0 = (float(xf) - modelStart) / modelResolution; 546 float sx0 = (float(xf) - modelStart) / modelResolution;
381 float sx1 = (float(v->getFrameForX(x+1)) - modelStart) / modelResolution; 547 float sx1 = (float(v->getFrameForX(x+1) / srRatio) - modelStart) / modelResolution;
382 548
383 int sx0i = int(sx0 + 0.001); 549 int sx0i = int(sx0 + 0.001);
384 int sx1i = int(sx1); 550 int sx1i = int(sx1);
385 551
386 for (int y = 0; y < h; ++y) { 552 for (int y = 0; y < h; ++y) {
390 556
391 int sy0i = int(sy0 + 0.001); 557 int sy0i = int(sy0 + 0.001);
392 int sy1i = int(sy1); 558 int sy1i = int(sy1);
393 559
394 float mag = 0.0, div = 0.0; 560 float mag = 0.0, div = 0.0;
561 int max = 0;
395 562
396 for (int sx = sx0i; sx <= sx1i; ++sx) { 563 for (int sx = sx0i; sx <= sx1i; ++sx) {
397 564
398 if (sx < 0 || sx >= m_cache->width()) continue; 565 if (sx < 0 || sx >= m_cache->width()) continue;
399 566
406 if (sx == sx1i) prop *= sx1 - sx; 573 if (sx == sx1i) prop *= sx1 - sx;
407 if (sy == sy0i) prop *= (sy + 1) - sy0; 574 if (sy == sy0i) prop *= (sy + 1) - sy0;
408 if (sy == sy1i) prop *= sy1 - sy; 575 if (sy == sy1i) prop *= sy1 - sy;
409 576
410 mag += prop * m_cache->pixelIndex(sx, sy); 577 mag += prop * m_cache->pixelIndex(sx, sy);
578 max = std::max(max, m_cache->pixelIndex(sx, sy));
411 div += prop; 579 div += prop;
412 } 580 }
413 } 581 }
414 582
415 if (div != 0) mag /= div; 583 if (div != 0) mag /= div;
416 if (mag < 0) mag = 0; 584 if (mag < 0) mag = 0;
417 if (mag > 255) mag = 255; 585 if (mag > 255) mag = 255;
586 if (max < 0) max = 0;
587 if (max > 255) max = 255;
418 588
419 img.setPixel(x - x0, y, m_cache->color(int(mag + 0.001))); 589 img.setPixel(x - x0, y, m_cache->color(int(mag + 0.001)));
590 // img.setPixel(x - x0, y, m_cache->color(max));
420 } 591 }
421 } 592 }
422 593
423 paint.drawImage(x0, 0, img); 594 paint.drawImage(x0, 0, img);
424 } 595 }