comparison layer/Colour3DPlotLayer.cpp @ 1107:6d720fe1c8cc spectrogram-minor-refactor

Remove almost all of the "old" paint logic from Colour3DPlotLayer
author Chris Cannam
date Thu, 14 Jul 2016 17:12:08 +0100
parents ea5ae9dd10ba
children edbe229860ac
comparison
equal deleted inserted replaced
1106:8abdefce36a6 1107:6d720fe1c8cc
46 //#define DEBUG_COLOUR_3D_PLOT_LAYER_PAINT 1 46 //#define DEBUG_COLOUR_3D_PLOT_LAYER_PAINT 1
47 47
48 48
49 Colour3DPlotLayer::Colour3DPlotLayer() : 49 Colour3DPlotLayer::Colour3DPlotLayer() :
50 m_model(0), 50 m_model(0),
51 m_cache(0),
52 m_peaksCache(0),
53 m_cacheValidStart(0),
54 m_cacheValidEnd(0),
55 m_colourScale(ColourScaleType::Linear), 51 m_colourScale(ColourScaleType::Linear),
56 m_colourScaleSet(false), 52 m_colourScaleSet(false),
57 m_colourMap(0), 53 m_colourMap(0),
58 m_gain(1.0), 54 m_gain(1.0),
59 m_binScale(BinScale::Linear), 55 m_binScale(BinScale::Linear),
75 settings.endGroup(); 71 settings.endGroup();
76 } 72 }
77 73
78 Colour3DPlotLayer::~Colour3DPlotLayer() 74 Colour3DPlotLayer::~Colour3DPlotLayer()
79 { 75 {
80 delete m_cache; 76 invalidateRenderers();
81 delete m_peaksCache; //!!! this one is to go...
82 delete m_peakCache; 77 delete m_peakCache;
83
84 cacheInvalid(); //!!! dup with above?
85 } 78 }
86 79
87 ColourScaleType 80 ColourScaleType
88 Colour3DPlotLayer::convertToColourScale(int value) 81 Colour3DPlotLayer::convertToColourScale(int value)
89 { 82 {
167 } 160 }
168 161
169 delete m_peakCache; 162 delete m_peakCache;
170 m_peakCache = 0; 163 m_peakCache = 0;
171 164
172 cacheInvalid(); 165 invalidateRenderers();
173 166
174 emit modelReplaced(); 167 emit modelReplaced();
175 emit sliceableModelReplaced(oldModel, model); 168 emit sliceableModelReplaced(oldModel, model);
176 } 169 }
177 170
178 void 171 void
179 Colour3DPlotLayer::cacheInvalid() 172 Colour3DPlotLayer::cacheInvalid()
180 { 173 {
181 //!!! to go 174 invalidateRenderers();
182 175 }
183 delete m_cache; 176
184 delete m_peaksCache; 177 void
185 m_cache = 0; 178 Colour3DPlotLayer::cacheInvalid(sv_frame_t /* startFrame */,
186 m_peaksCache = 0; 179 sv_frame_t /* endFrame */)
187 m_cacheValidStart = 0; 180 {
188 m_cacheValidEnd = 0; 181 //!!! should do this only if the range is visible
189 182 delete m_peakCache;
190 //!!! 183 invalidateRenderers();
184 }
185
186 void
187 Colour3DPlotLayer::invalidateRenderers()
188 {
191 for (ViewRendererMap::iterator i = m_renderers.begin(); 189 for (ViewRendererMap::iterator i = m_renderers.begin();
192 i != m_renderers.end(); ++i) { 190 i != m_renderers.end(); ++i) {
193 delete i->second; 191 delete i->second;
194 } 192 }
195 m_renderers.clear(); 193 m_renderers.clear();
196 }
197
198 void
199 Colour3DPlotLayer::cacheInvalid(sv_frame_t startFrame, sv_frame_t endFrame)
200 {
201 //!!! to go
202
203 if (!m_cache || !m_model) return;
204
205 int modelResolution = m_model->getResolution();
206 int start = int(startFrame / modelResolution);
207 int end = int(endFrame / modelResolution + 1);
208 if (m_cacheValidStart < end) m_cacheValidStart = end;
209 if (m_cacheValidEnd > start) m_cacheValidEnd = start;
210 if (m_cacheValidStart > m_cacheValidEnd) m_cacheValidEnd = m_cacheValidStart;
211 } 194 }
212 195
213 Dense3DModelPeakCache * 196 Dense3DModelPeakCache *
214 Colour3DPlotLayer::getPeakCache() const 197 Colour3DPlotLayer::getPeakCache() const
215 { 198 {
475 Colour3DPlotLayer::setColourScale(ColourScaleType scale) 458 Colour3DPlotLayer::setColourScale(ColourScaleType scale)
476 { 459 {
477 if (m_colourScale == scale) return; 460 if (m_colourScale == scale) return;
478 m_colourScale = scale; 461 m_colourScale = scale;
479 m_colourScaleSet = true; 462 m_colourScaleSet = true;
480 cacheInvalid(); 463 invalidateRenderers();
481 emit layerParametersChanged(); 464 emit layerParametersChanged();
482 } 465 }
483 466
484 void 467 void
485 Colour3DPlotLayer::setColourMap(int map) 468 Colour3DPlotLayer::setColourMap(int map)
486 { 469 {
487 if (m_colourMap == map) return; 470 if (m_colourMap == map) return;
488 m_colourMap = map; 471 m_colourMap = map;
489 cacheInvalid(); 472 invalidateRenderers();
490 emit layerParametersChanged(); 473 emit layerParametersChanged();
491 } 474 }
492 475
493 void 476 void
494 Colour3DPlotLayer::setGain(float gain) 477 Colour3DPlotLayer::setGain(float gain)
495 { 478 {
496 if (m_gain == gain) return; 479 if (m_gain == gain) return;
497 m_gain = gain; 480 m_gain = gain;
498 cacheInvalid(); 481 invalidateRenderers();
499 emit layerParametersChanged(); 482 emit layerParametersChanged();
500 } 483 }
501 484
502 float 485 float
503 Colour3DPlotLayer::getGain() const 486 Colour3DPlotLayer::getGain() const
508 void 491 void
509 Colour3DPlotLayer::setBinScale(BinScale binScale) 492 Colour3DPlotLayer::setBinScale(BinScale binScale)
510 { 493 {
511 if (m_binScale == binScale) return; 494 if (m_binScale == binScale) return;
512 m_binScale = binScale; 495 m_binScale = binScale;
513 cacheInvalid(); 496 invalidateRenderers();
514 emit layerParametersChanged(); 497 emit layerParametersChanged();
515 } 498 }
516 499
517 BinScale 500 BinScale
518 Colour3DPlotLayer::getBinScale() const 501 Colour3DPlotLayer::getBinScale() const
524 Colour3DPlotLayer::setNormalization(ColumnNormalization n) 507 Colour3DPlotLayer::setNormalization(ColumnNormalization n)
525 { 508 {
526 if (m_normalization == n) return; 509 if (m_normalization == n) return;
527 510
528 m_normalization = n; 511 m_normalization = n;
529 cacheInvalid(); 512 invalidateRenderers();
530 513
531 emit layerParametersChanged(); 514 emit layerParametersChanged();
532 } 515 }
533 516
534 ColumnNormalization 517 ColumnNormalization
541 Colour3DPlotLayer::setNormalizeVisibleArea(bool n) 524 Colour3DPlotLayer::setNormalizeVisibleArea(bool n)
542 { 525 {
543 if (m_normalizeVisibleArea == n) return; 526 if (m_normalizeVisibleArea == n) return;
544 527
545 m_normalizeVisibleArea = n; 528 m_normalizeVisibleArea = n;
546 cacheInvalid(); 529 invalidateRenderers();
547 530
548 emit layerParametersChanged(); 531 emit layerParametersChanged();
549 } 532 }
550 533
551 bool 534 bool
557 void 540 void
558 Colour3DPlotLayer::setInvertVertical(bool n) 541 Colour3DPlotLayer::setInvertVertical(bool n)
559 { 542 {
560 if (m_invertVertical == n) return; 543 if (m_invertVertical == n) return;
561 m_invertVertical = n; 544 m_invertVertical = n;
562 cacheInvalid(); 545 invalidateRenderers();
563 emit layerParametersChanged(); 546 emit layerParametersChanged();
564 } 547 }
565 548
566 void 549 void
567 Colour3DPlotLayer::setOpaque(bool n) 550 Colour3DPlotLayer::setOpaque(bool n)
568 { 551 {
569 if (m_opaque == n) return; 552 if (m_opaque == n) return;
570 m_opaque = n; 553 m_opaque = n;
554 invalidateRenderers();
571 emit layerParametersChanged(); 555 emit layerParametersChanged();
572 } 556 }
573 557
574 void 558 void
575 Colour3DPlotLayer::setSmooth(bool n) 559 Colour3DPlotLayer::setSmooth(bool n)
576 { 560 {
577 if (m_smooth == n) return; 561 if (m_smooth == n) return;
578 m_smooth = n; 562 m_smooth = n;
563 invalidateRenderers();
579 emit layerParametersChanged(); 564 emit layerParametersChanged();
580 } 565 }
581 566
582 bool 567 bool
583 Colour3DPlotLayer::getInvertVertical() const 568 Colour3DPlotLayer::getInvertVertical() const
625 Colour3DPlotLayer::isLayerScrollable(const LayerGeometryProvider *v) const 610 Colour3DPlotLayer::isLayerScrollable(const LayerGeometryProvider *v) const
626 { 611 {
627 if (m_normalizeVisibleArea) { 612 if (m_normalizeVisibleArea) {
628 return false; 613 return false;
629 } 614 }
630 if (shouldPaintDenseIn(v)) { 615 //!!! if (shouldPaintDenseIn(v)) {
631 return true; 616 // return true;
632 } 617 // }
633 QPoint discard; 618 QPoint discard;
634 return !v->shouldIlluminateLocalFeatures(this, discard); 619 return !v->shouldIlluminateLocalFeatures(this, discard);
635 } 620 }
636 621
637 bool 622 bool
872 int h = rect.height(), w = rect.width(); 857 int h = rect.height(), w = rect.width();
873 858
874 int cw = getColourScaleWidth(paint); 859 int cw = getColourScaleWidth(paint);
875 860
876 int ch = h - 20; 861 int ch = h - 20;
877 if (ch > 20 && m_cache) { 862 if (ch > 20) {
878 863
879 double min = m_model->getMinimumLevel(); 864 double min = m_model->getMinimumLevel();
880 double max = m_model->getMaximumLevel(); 865 double max = m_model->getMaximumLevel();
881 866
882 double mmin = min; 867 double mmin = min;
909 if (m_colourScale == ColourScaleType::Log) { 894 if (m_colourScale == ColourScaleType::Log) {
910 value = LogRange::map(value); 895 value = LogRange::map(value);
911 } 896 }
912 int pixel = int(((value - mmin) * 256) / (mmax - mmin)); 897 int pixel = int(((value - mmin) * 256) / (mmax - mmin));
913 if (pixel >= 0 && pixel < 256) { 898 if (pixel >= 0 && pixel < 256) {
914 QRgb c = m_cache->color(pixel); 899 //!!! replace this
915 paint.setPen(QColor(qRed(c), qGreen(c), qBlue(c))); 900 // QRgb c = m_cache->color(pixel);
901 // paint.setPen(QColor(qRed(c), qGreen(c), qBlue(c)));
916 paint.drawLine(5, 11 + y, cw - 5, 11 + y); 902 paint.drawLine(5, 11 + y, cw - 5, 11 + y);
917 } else { 903 } else {
918 cerr << "WARNING: Colour3DPlotLayer::paintVerticalScale: value " << value << ", mmin " << mmin << ", mmax " << mmax << " leads to invalid pixel " << pixel << endl; 904 cerr << "WARNING: Colour3DPlotLayer::paintVerticalScale: value " << value << ", mmin " << mmin << ", mmax " << mmax << " leads to invalid pixel " << pixel << endl;
919 } 905 }
920 } 906 }
1055 } 1041 }
1056 } 1042 }
1057 1043
1058 return values; 1044 return values;
1059 } 1045 }
1060 1046 /*!!! replace this
1061 void
1062 Colour3DPlotLayer::fillCache(int firstColumn, int lastColumn) const
1063 {
1064 // This call requests a (perhaps partial) fill of the cache
1065 // between model columns firstColumn and lastColumn inclusive.
1066 // The cache itself always has size sufficient to contain the
1067 // whole model, but its validity may be less, depending on which
1068 // regions have been requested via calls to this function. Note
1069 // that firstColumn and lastColumn are *model* column numbers. If
1070 // the model starts at a frame > 0, a firstColumn of zero still
1071 // corresponds to the first column in the model, not the first
1072 // column on the resulting rendered layer.
1073
1074 Profiler profiler("Colour3DPlotLayer::fillCache", true);
1075
1076 int cacheWidth = m_model->getWidth();
1077 int cacheHeight = m_model->getHeight();
1078
1079 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT
1080 cerr << "Colour3DPlotLayer::fillCache: range " << firstColumn << " -> " << lastColumn << " (cache size will be " << cacheWidth << " x " << cacheHeight << ")" << endl;
1081 #endif
1082
1083 if (m_cache && m_cache->height() != cacheHeight) {
1084 // height has changed: delete everything rather than resizing
1085 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT
1086 cerr << "Colour3DPlotLayer::fillCache: Cache height has changed, recreating" << endl;
1087 #endif
1088 delete m_cache;
1089 delete m_peaksCache;
1090 m_cache = 0;
1091 m_peaksCache = 0;
1092 }
1093
1094 if (m_cache && m_cache->width() != cacheWidth) {
1095 // width has changed and we have an existing cache: resize it
1096 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT
1097 cerr << "Colour3DPlotLayer::fillCache: Cache width has changed, resizing existing cache" << endl;
1098 #endif
1099 QImage *newCache =
1100 new QImage(m_cache->copy(0, 0, cacheWidth, cacheHeight));
1101 delete m_cache;
1102 m_cache = newCache;
1103 if (m_peaksCache) {
1104 QImage *newPeaksCache =
1105 new QImage(m_peaksCache->copy
1106 (0, 0, cacheWidth / m_peakResolution + 1, cacheHeight));
1107 delete m_peaksCache;
1108 m_peaksCache = newPeaksCache;
1109 }
1110 }
1111
1112 if (!m_cache) {
1113 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT
1114 cerr << "Colour3DPlotLayer::fillCache: Have no cache, making one" << endl;
1115 #endif
1116 m_cache = new QImage(cacheWidth, cacheHeight, QImage::Format_Indexed8);
1117 m_cache->setColorCount(256);
1118 m_cache->fill(0);
1119 if (!m_normalizeVisibleArea) {
1120 m_peaksCache = new QImage
1121 (cacheWidth / m_peakResolution + 1, cacheHeight,
1122 QImage::Format_Indexed8);
1123 m_peaksCache->setColorCount(256);
1124 m_peaksCache->fill(0);
1125 } else if (m_peaksCache) {
1126 delete m_peaksCache;
1127 m_peaksCache = 0;
1128 }
1129 m_cacheValidStart = 0;
1130 m_cacheValidEnd = 0;
1131 }
1132
1133 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT
1134 cerr << "cache size = " << m_cache->width() << "x" << m_cache->height()
1135 << " peaks cache size = " << m_peaksCache->width() << "x" << m_peaksCache->height() << endl;
1136 #endif
1137
1138 if (m_cacheValidStart <= firstColumn && m_cacheValidEnd >= lastColumn) {
1139 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT
1140 cerr << "Cache is valid in this region already" << endl;
1141 #endif
1142 return;
1143 }
1144
1145 int fillStart = firstColumn;
1146 int fillEnd = lastColumn;
1147
1148 if (fillStart >= cacheWidth) fillStart = cacheWidth-1;
1149 if (fillStart < 0) fillStart = 0;
1150 if (fillEnd >= cacheWidth) fillEnd = cacheWidth-1;
1151 if (fillEnd < 0) fillEnd = 0;
1152 if (fillEnd < fillStart) fillEnd = fillStart;
1153
1154 bool normalizeVisible = (m_normalizeVisibleArea);
1155
1156 if (!normalizeVisible && (m_cacheValidStart < m_cacheValidEnd)) {
1157
1158 if (m_cacheValidEnd < fillStart) {
1159 fillStart = m_cacheValidEnd + 1;
1160 }
1161 if (m_cacheValidStart > fillEnd) {
1162 fillEnd = m_cacheValidStart - 1;
1163 }
1164
1165 m_cacheValidStart = std::min(fillStart, m_cacheValidStart);
1166 m_cacheValidEnd = std::max(fillEnd, m_cacheValidEnd);
1167
1168 } else {
1169
1170 // when normalising the visible area, the only valid area,
1171 // ever, is the currently visible one
1172
1173 m_cacheValidStart = fillStart;
1174 m_cacheValidEnd = fillEnd;
1175 }
1176
1177 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT
1178 cerr << "Cache size " << cacheWidth << "x" << cacheHeight << " will be valid from " << m_cacheValidStart << " to " << m_cacheValidEnd << " (fillStart = " << fillStart << ", fillEnd = " << fillEnd << ")" << endl;
1179 #endif
1180
1181 DenseThreeDimensionalModel::Column values;
1182
1183 double min = m_model->getMinimumLevel();
1184 double max = m_model->getMaximumLevel();
1185
1186 if (m_colourScale == ColourScaleType::Log) {
1187 LogRange::mapRange(min, max);
1188 } else if (m_colourScale == ColourScaleType::PlusMinusOne) {
1189 min = -1.f;
1190 max = 1.f;
1191 } else if (m_colourScale == ColourScaleType::Absolute) {
1192 if (min < 0) {
1193 if (fabs(min) > fabs(max)) max = fabs(min);
1194 else max = fabs(max);
1195 min = 0;
1196 } else {
1197 min = fabs(min);
1198 max = fabs(max);
1199 }
1200 }
1201
1202 if (max == min) max = min + 1.f;
1203
1204 ColourMapper mapper(m_colourMap, 0.f, 255.f);
1205
1206 for (int index = 0; index < 256; ++index) {
1207 QColor colour = mapper.map(index);
1208 m_cache->setColor
1209 (index, qRgb(colour.red(), colour.green(), colour.blue()));
1210 if (m_peaksCache) {
1211 m_peaksCache->setColor
1212 (index, qRgb(colour.red(), colour.green(), colour.blue()));
1213 }
1214 }
1215
1216 double visibleMax = 0.f, visibleMin = 0.f;
1217
1218 if (normalizeVisible) {
1219
1220 for (int c = fillStart; c <= fillEnd; ++c) {
1221
1222 values = getColumn(c);
1223
1224 double colMax = 0.f, colMin = 0.f;
1225
1226 for (int y = 0; y < cacheHeight; ++y) {
1227 if (!in_range_for(values, y)) break;
1228 if (y == 0 || values[y] > colMax) colMax = values[y];
1229 if (y == 0 || values[y] < colMin) colMin = values[y];
1230 }
1231
1232 if (c == fillStart || colMax > visibleMax) visibleMax = colMax;
1233 if (c == fillStart || colMin < visibleMin) visibleMin = colMin;
1234 }
1235
1236 if (m_colourScale == ColourScaleType::Log) {
1237 visibleMin = LogRange::map(visibleMin);
1238 visibleMax = LogRange::map(visibleMax);
1239 if (visibleMin > visibleMax) std::swap(visibleMin, visibleMax);
1240 } else if (m_colourScale == ColourScaleType::Absolute) {
1241 if (visibleMin < 0) {
1242 if (fabs(visibleMin) > fabs(visibleMax)) visibleMax = fabs(visibleMin);
1243 else visibleMax = fabs(visibleMax);
1244 visibleMin = 0;
1245 } else {
1246 visibleMin = fabs(visibleMin);
1247 visibleMax = fabs(visibleMax);
1248 }
1249 }
1250 }
1251
1252 if (visibleMin == visibleMax) visibleMax = visibleMin + 1;
1253
1254 int *peaks = 0;
1255 if (m_peaksCache) {
1256 peaks = new int[cacheHeight];
1257 for (int y = 0; y < cacheHeight; ++y) {
1258 peaks[y] = 0;
1259 }
1260 }
1261
1262 Profiler profiler2("Colour3DPlotLayer::fillCache: filling", true);
1263
1264 for (int c = fillStart; c <= fillEnd; ++c) {
1265
1266 values = getColumn(c);
1267
1268 if (c >= m_cache->width()) {
1269 cerr << "ERROR: column " << c << " >= cache width "
1270 << m_cache->width() << endl;
1271 continue;
1272 }
1273
1274 for (int y = 0; y < cacheHeight; ++y) {
1275
1276 double value = min;
1277 if (in_range_for(values, y)) {
1278 value = values.at(y);
1279 }
1280
1281 value = value * m_gain;
1282
1283 if (m_colourScale == ColourScaleType::Log) {
1284 value = LogRange::map(value);
1285 } else if (m_colourScale == ColourScaleType::Absolute) {
1286 value = fabs(value);
1287 }
1288
1289 if (normalizeVisible) {
1290 double norm = (value - visibleMin) / (visibleMax - visibleMin);
1291 value = min + (max - min) * norm;
1292 }
1293
1294 int pixel = int(((value - min) * 256) / (max - min));
1295 if (pixel < 0) pixel = 0;
1296 if (pixel > 255) pixel = 255;
1297 if (peaks && (pixel > peaks[y])) peaks[y] = pixel;
1298
1299 if (m_invertVertical) {
1300 m_cache->setPixel(c, cacheHeight - y - 1, pixel);
1301 } else {
1302 if (y >= m_cache->height()) {
1303 cerr << "ERROR: row " << y << " >= cache height " << m_cache->height() << endl;
1304 } else {
1305 m_cache->setPixel(c, y, pixel);
1306 }
1307 }
1308 }
1309
1310 if (peaks) {
1311 int notch = (c % m_peakResolution);
1312 if (notch == m_peakResolution-1 || c == fillEnd) {
1313 int pc = c / m_peakResolution;
1314 if (pc >= m_peaksCache->width()) {
1315 cerr << "ERROR: peak column " << pc
1316 << " (from col " << c << ") >= peaks cache width "
1317 << m_peaksCache->width() << endl;
1318 continue;
1319 }
1320 for (int y = 0; y < cacheHeight; ++y) {
1321 if (m_invertVertical) {
1322 m_peaksCache->setPixel(pc, cacheHeight - y - 1, peaks[y]);
1323 } else {
1324 if (y >= m_peaksCache->height()) {
1325 cerr << "ERROR: row " << y
1326 << " >= peaks cache height "
1327 << m_peaksCache->height() << endl;
1328 } else {
1329 m_peaksCache->setPixel(pc, y, peaks[y]);
1330 }
1331 }
1332 }
1333 for (int y = 0; y < cacheHeight; ++y) {
1334 peaks[y] = 0;
1335 }
1336 }
1337 }
1338 }
1339
1340 delete[] peaks;
1341 }
1342
1343 bool 1047 bool
1344 Colour3DPlotLayer::shouldPaintDenseIn(const LayerGeometryProvider *v) const 1048 Colour3DPlotLayer::shouldPaintDenseIn(const LayerGeometryProvider *v) const
1345 { 1049 {
1346 if (!m_model || !v || !(v->getViewManager())) { 1050 if (!m_model || !v || !(v->getViewManager())) {
1347 return false; 1051 return false;
1354 ((m_model->getResolution() * srRatio) / v->getZoomLevel()) < 2) { 1058 ((m_model->getResolution() * srRatio) / v->getZoomLevel()) < 2) {
1355 return true; 1059 return true;
1356 } 1060 }
1357 return false; 1061 return false;
1358 } 1062 }
1359 1063 */
1360 Colour3DPlotRenderer * 1064 Colour3DPlotRenderer *
1361 Colour3DPlotLayer::getRenderer(LayerGeometryProvider *v) const 1065 Colour3DPlotLayer::getRenderer(LayerGeometryProvider *v) const
1362 { 1066 {
1363 if (m_renderers.find(v->getId()) == m_renderers.end()) { 1067 if (m_renderers.find(v->getId()) == m_renderers.end()) {
1364 1068
1386 1090
1387 return m_renderers[v->getId()]; 1091 return m_renderers[v->getId()];
1388 } 1092 }
1389 1093
1390 void 1094 void
1391 Colour3DPlotLayer::paintAlternative(LayerGeometryProvider *v, QPainter &paint, QRect rect) const 1095 Colour3DPlotLayer::paintWithRenderer(LayerGeometryProvider *v,
1096 QPainter &paint, QRect rect) const
1392 { 1097 {
1393 static int depth = 0; 1098 static int depth = 0;
1394 1099
1395 Colour3DPlotRenderer *renderer = getRenderer(v); 1100 Colour3DPlotRenderer *renderer = getRenderer(v);
1396 1101
1445 << "nothing to paint (yet)" << endl; 1150 << "nothing to paint (yet)" << endl;
1446 #endif 1151 #endif
1447 return; 1152 return;
1448 } 1153 }
1449 1154
1155 //!!!???
1156
1157 if (m_normalizeVisibleArea) {
1158 rect = v->getPaintRect();
1159 }
1160
1450 //!!! why is the setLayerDormant(false) found here in 1161 //!!! why is the setLayerDormant(false) found here in
1451 //!!! SpectrogramLayer not present in Colour3DPlotLayer? 1162 //!!! SpectrogramLayer not present in Colour3DPlotLayer?
1452 //!!! unnecessary? vestigial? forgotten? 1163 //!!! unnecessary? vestigial? forgotten?
1453 1164
1454 paintAlternative(v, paint, rect); 1165 paintWithRenderer(v, paint, rect);
1455 return; 1166 }
1456 1167
1457 //!!!??? 1168 /*!!! This will be needed in some form still.
1458
1459 if (m_normalizeVisibleArea) {
1460 rect = v->getPaintRect();
1461 }
1462 1169
1463 sv_frame_t modelStart = m_model->getStartFrame(); 1170 sv_frame_t modelStart = m_model->getStartFrame();
1464 sv_frame_t modelEnd = m_model->getEndFrame(); 1171 sv_frame_t modelEnd = m_model->getEndFrame();
1465 int modelResolution = m_model->getResolution(); 1172 int modelResolution = m_model->getResolution();
1466 1173
1598 } 1305 }
1599 } 1306 }
1600 } 1307 }
1601 } 1308 }
1602 } 1309 }
1603 1310 */
1604 void 1311
1605 Colour3DPlotLayer::paintDense(LayerGeometryProvider *v, QPainter &paint, QRect rect) const
1606 {
1607 Profiler profiler("Colour3DPlotLayer::paintDense", true);
1608 if (!m_cache) return;
1609
1610 double modelStart = double(m_model->getStartFrame());
1611 double modelResolution = double(m_model->getResolution());
1612
1613 sv_samplerate_t mmsr = v->getViewManager()->getMainModelSampleRate();
1614 sv_samplerate_t msr = m_model->getSampleRate();
1615 double srRatio = mmsr / msr;
1616
1617 int x0 = rect.left();
1618 int x1 = rect.right() + 1;
1619
1620 const int w = x1 - x0; // const so it can be used as array size below
1621 int h = v->getPaintHeight(); // we always paint full height
1622 int sh = m_model->getHeight();
1623
1624 int symin = m_miny;
1625 int symax = m_maxy;
1626 if (symax <= symin) {
1627 symin = 0;
1628 symax = sh;
1629 }
1630 if (symin < 0) symin = 0;
1631 if (symax > sh) symax = sh;
1632
1633 QImage img(w, h, QImage::Format_Indexed8);
1634 img.setColorTable(m_cache->colorTable());
1635
1636 uchar *peaks = new uchar[w];
1637 memset(peaks, 0, w);
1638
1639 int zoomLevel = v->getZoomLevel();
1640
1641 QImage *source = m_cache;
1642
1643 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT
1644 cerr << "modelResolution " << modelResolution << ", srRatio "
1645 << srRatio << ", m_peakResolution " << m_peakResolution
1646 << ", zoomLevel " << zoomLevel << ", result "
1647 << ((modelResolution * srRatio * m_peakResolution) / zoomLevel)
1648 << endl;
1649 #endif
1650
1651 if (m_peaksCache) {
1652 if (((modelResolution * srRatio * m_peakResolution) / zoomLevel) < 1) {
1653 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT
1654 cerr << "using peaks cache" << endl;
1655 #endif
1656 source = m_peaksCache;
1657 modelResolution *= m_peakResolution;
1658 } else {
1659 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT
1660 cerr << "not using peaks cache" << endl;
1661 #endif
1662 }
1663 } else {
1664 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT
1665 cerr << "have no peaks cache" << endl;
1666 #endif
1667 }
1668
1669 int sw = source->width();
1670
1671 sv_frame_t xf = -1;
1672 sv_frame_t nxf = v->getFrameForX(x0);
1673
1674 double epsilon = 0.000001;
1675
1676 vector<double> sxa(w*2);
1677
1678 for (int x = 0; x < w; ++x) {
1679
1680 xf = nxf;
1681 nxf = xf + zoomLevel;
1682
1683 double sx0 = (double(xf) / srRatio - modelStart) / modelResolution;
1684 double sx1 = (double(nxf) / srRatio - modelStart) / modelResolution;
1685
1686 sxa[x*2] = sx0;
1687 sxa[x*2 + 1] = sx1;
1688 }
1689
1690 double logmin = symin+1, logmax = symax+1;
1691 LogRange::mapRange(logmin, logmax);
1692
1693 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT
1694 cerr << "m_smooth = " << m_smooth << ", w = " << w << ", h = " << h << endl;
1695 #endif
1696
1697 if (m_smooth) {
1698
1699 for (int y = 0; y < h; ++y) {
1700
1701 double sy = getBinForY(v, y) - 0.5;
1702 int syi = int(sy + epsilon);
1703 if (syi < 0 || syi >= source->height()) continue;
1704
1705 uchar *targetLine = img.scanLine(y);
1706 uchar *sourceLine = source->scanLine(syi);
1707 uchar *nextSource;
1708 if (syi + 1 < source->height()) {
1709 nextSource = source->scanLine(syi + 1);
1710 } else {
1711 nextSource = sourceLine;
1712 }
1713
1714 for (int x = 0; x < w; ++x) {
1715
1716 targetLine[x] = 0;
1717
1718 double sx0 = sxa[x*2];
1719 if (sx0 < 0) continue;
1720 int sx0i = int(sx0 + epsilon);
1721 if (sx0i >= sw) break;
1722
1723 double a = sourceLine[sx0i];
1724 double b = a;
1725 double value;
1726
1727 double sx1 = sxa[x*2+1];
1728 if (sx1 > sx0 + 1.f) {
1729 int sx1i = int(sx1);
1730 bool have = false;
1731 for (int sx = sx0i; sx <= sx1i; ++sx) {
1732 if (sx < 0 || sx >= sw) continue;
1733 if (!have) {
1734 a = sourceLine[sx];
1735 b = nextSource[sx];
1736 have = true;
1737 } else {
1738 a = std::max(a, double(sourceLine[sx]));
1739 b = std::max(b, double(nextSource[sx]));
1740 }
1741 }
1742 double yprop = sy - syi;
1743 value = (a * (1.f - yprop) + b * yprop);
1744 } else {
1745 a = sourceLine[sx0i];
1746 b = nextSource[sx0i];
1747 double yprop = sy - syi;
1748 value = (a * (1.f - yprop) + b * yprop);
1749 int oi = sx0i + 1;
1750 double xprop = sx0 - sx0i;
1751 xprop -= 0.5;
1752 if (xprop < 0) {
1753 oi = sx0i - 1;
1754 xprop = -xprop;
1755 }
1756 if (oi < 0 || oi >= sw) oi = sx0i;
1757 a = sourceLine[oi];
1758 b = nextSource[oi];
1759 value = (value * (1.f - xprop) +
1760 (a * (1.f - yprop) + b * yprop) * xprop);
1761 }
1762
1763 int vi = int(lrint(value));
1764 if (vi > 255) vi = 255;
1765 if (vi < 0) vi = 0;
1766 targetLine[x] = uchar(vi);
1767 }
1768 }
1769 } else {
1770
1771 double sy0 = getBinForY(v, 0);
1772
1773 int psy0i = -1, psy1i = -1;
1774
1775 for (int y = 0; y < h; ++y) {
1776
1777 double sy1 = sy0;
1778 sy0 = getBinForY(v, double(y + 1));
1779
1780 int sy0i = int(sy0 + epsilon);
1781 int sy1i = int(sy1);
1782
1783 uchar *targetLine = img.scanLine(y);
1784
1785 if (sy0i == psy0i && sy1i == psy1i) {
1786 // same source scan line as just computed
1787 goto copy;
1788 }
1789
1790 psy0i = sy0i;
1791 psy1i = sy1i;
1792
1793 for (int x = 0; x < w; ++x) {
1794 peaks[x] = 0;
1795 }
1796
1797 for (int sy = sy0i; sy <= sy1i; ++sy) {
1798
1799 if (sy < 0 || sy >= source->height()) continue;
1800
1801 uchar *sourceLine = source->scanLine(sy);
1802
1803 for (int x = 0; x < w; ++x) {
1804
1805 double sx1 = sxa[x*2 + 1];
1806 if (sx1 < 0) continue;
1807 int sx1i = int(sx1);
1808
1809 double sx0 = sxa[x*2];
1810 if (sx0 < 0) continue;
1811 int sx0i = int(sx0 + epsilon);
1812 if (sx0i >= sw) break;
1813
1814 uchar peak = 0;
1815 for (int sx = sx0i; sx <= sx1i; ++sx) {
1816 if (sx < 0 || sx >= sw) continue;
1817 if (sourceLine[sx] > peak) peak = sourceLine[sx];
1818 }
1819 peaks[x] = peak;
1820 }
1821 }
1822
1823 copy:
1824 for (int x = 0; x < w; ++x) {
1825 targetLine[x] = peaks[x];
1826 }
1827 }
1828 }
1829
1830 delete[] peaks;
1831
1832 paint.drawImage(x0, 0, img);
1833 }
1834 1312
1835 bool 1313 bool
1836 Colour3DPlotLayer::snapToFeatureFrame(LayerGeometryProvider *v, sv_frame_t &frame, 1314 Colour3DPlotLayer::snapToFeatureFrame(LayerGeometryProvider *v, sv_frame_t &frame,
1837 int &resolution, 1315 int &resolution,
1838 SnapType snap) const 1316 SnapType snap) const