Mercurial > hg > svgui
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 } |