comparison layer/Colour3DPlotLayer.cpp @ 466:b13dfc443e71

* Make Colour3DPlotLayer::paintDense much faster (but still not fast enough)
author Chris Cannam
date Thu, 22 Jan 2009 17:39:04 +0000
parents b77b79413cdb
children 76a47146f1f6
comparison
equal deleted inserted replaced
465:b77b79413cdb 466:b13dfc443e71
703 } 703 }
704 704
705 void 705 void
706 Colour3DPlotLayer::fillCache(size_t firstBin, size_t lastBin) const 706 Colour3DPlotLayer::fillCache(size_t firstBin, size_t lastBin) const
707 { 707 {
708 Profiler profiler("Colour3DPlotLayer::fillCache");
708 size_t modelStart = m_model->getStartFrame(); 709 size_t modelStart = m_model->getStartFrame();
709 size_t modelEnd = m_model->getEndFrame(); 710 size_t modelEnd = m_model->getEndFrame();
710 size_t modelResolution = m_model->getResolution(); 711 size_t modelResolution = m_model->getResolution();
711 712
712 // std::cerr << "Colour3DPlotLayer::fillCache: " << firstBin << " -> " << lastBin << std::endl; 713 // std::cerr << "Colour3DPlotLayer::fillCache: " << firstBin << " -> " << lastBin << std::endl;
865 /*!!! 866 /*!!!
866 if (m_model) { 867 if (m_model) {
867 std::cerr << "Colour3DPlotLayer::paint: model says shouldUseLogValueScale = " << m_model->shouldUseLogValueScale() << std::endl; 868 std::cerr << "Colour3DPlotLayer::paint: model says shouldUseLogValueScale = " << m_model->shouldUseLogValueScale() << std::endl;
868 } 869 }
869 */ 870 */
870 // Profiler profiler("Colour3DPlotLayer::paint"); 871 Profiler profiler("Colour3DPlotLayer::paint");
871 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT 872 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT
872 std::cerr << "Colour3DPlotLayer::paint(): m_model is " << m_model << ", zoom level is " << v->getZoomLevel() << std::endl; 873 std::cerr << "Colour3DPlotLayer::paint(): m_model is " << m_model << ", zoom level is " << v->getZoomLevel() << std::endl;
873 #endif 874 #endif
874 875
875 int completion = 0; 876 int completion = 0;
923 if (sx0 > 0) --sx0; 924 if (sx0 > 0) --sx0;
924 fillCache(sx0 < 0 ? 0 : sx0, 925 fillCache(sx0 < 0 ? 0 : sx0,
925 sx1 < 0 ? 0 : sx1); 926 sx1 < 0 ? 0 : sx1);
926 927
927 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT 928 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT
928 std::cerr << "Colour3DPlotLayer::paint: height = "<< m_model->getHeight() << ", modelStart = " << modelStart << ", resolution = " << modelResolution << ", model rate = " << m_model->getSampleRate() << std::endl; 929 std::cerr << "Colour3DPlotLayer::paint: height = "<< m_model->getHeight() << ", modelStart = " << modelStart << ", resolution = " << modelResolution << ", model rate = " << m_model->getSampleRate() << " (zoom level = " << v->getZoomLevel() << ", srRatio = " << srRatio << ")" << std::endl;
929 #endif 930 #endif
930 931
931 if (m_opaque || 932 if (m_opaque ||
932 int(m_model->getHeight()) >= v->height() || 933 int(m_model->getHeight()) >= v->height() ||
933 int(modelResolution * m_model->getSampleRate()) < v->getZoomLevel() / 2) { 934 // int(modelResolution * m_model->getSampleRate()) < v->getZoomLevel() / 2) {
935 ((modelResolution * srRatio) / v->getZoomLevel()) < 2) {
934 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT 936 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT
935 std::cerr << "calling paintDense" << std::endl; 937 std::cerr << "calling paintDense" << std::endl;
936 #endif 938 #endif
937 paintDense(v, paint, rect); 939 paintDense(v, paint, rect);
938 return; 940 return;
1023 } 1025 }
1024 1026
1025 void 1027 void
1026 Colour3DPlotLayer::paintDense(View *v, QPainter &paint, QRect rect) const 1028 Colour3DPlotLayer::paintDense(View *v, QPainter &paint, QRect rect) const
1027 { 1029 {
1030 Profiler profiler("Colour3DPlotLayer::paintDense");
1028 if (!m_cache) return; 1031 if (!m_cache) return;
1029 1032
1030 size_t modelStart = m_model->getStartFrame(); 1033 float modelStart = m_model->getStartFrame();
1031 size_t modelResolution = m_model->getResolution(); 1034 float modelResolution = m_model->getResolution();
1032 1035
1033 float srRatio = 1036 float srRatio =
1034 float(v->getViewManager()->getMainModelSampleRate()) / 1037 float(v->getViewManager()->getMainModelSampleRate()) /
1035 float(m_model->getSampleRate()); 1038 float(m_model->getSampleRate());
1036 1039
1048 symax = sh; 1051 symax = sh;
1049 } 1052 }
1050 if (symin < 0) symin = 0; 1053 if (symin < 0) symin = 0;
1051 if (symax > sh) symax = sh; 1054 if (symax > sh) symax = sh;
1052 1055
1053 QImage img(w, h, QImage::Format_RGB32); 1056 QImage img(w, h, QImage::Format_Indexed8);
1054 1057 img.setColorTable(m_cache->colorTable());
1055 for (int x = x0; x < x1; ++x) { 1058
1056 1059 uchar *peaks = new uchar[w];
1057 long xf = long(v->getFrameForX(x)); 1060 memset(peaks, 0, w);
1058 if (xf < 0) { 1061
1059 for (int y = 0; y < h; ++y) { 1062 int psy1i = -1;
1060 img.setPixel(x - x0, y, m_cache->color(0)); 1063
1064 for (int y = 0; y < h; ++y) {
1065
1066 float sy0 = symin + (float(h - y - 1) * (symax - symin)) / h;
1067 float sy1 = symin + (float(h - y) * (symax - symin)) / h;
1068
1069 int sy0i = int(sy0 + 0.001);
1070 int sy1i = int(sy1);
1071
1072 uchar *targetLine = img.scanLine(y);
1073
1074 if (sy0i == sy1i && sy0i == psy1i) { // same scan line as just computed
1075 goto copy;
1076 }
1077
1078 memset(peaks, 0, w);
1079
1080 for (int sy = sy0i; sy <= sy1i; ++sy) {
1081
1082 if (sy < 0 || sy >= m_cache->height()) continue;
1083
1084 uchar *sourceLine = m_cache->scanLine(sy);
1085
1086 long xf = -1, nxf = -1;
1087
1088 for (int x = 0; x < w; ++x) {
1089
1090 xf = nxf;
1091 nxf = v->getFrameForX(x + 1 + x0);
1092
1093 if (xf < 0) {
1094 xf = v->getFrameForX(x + x0);
1095 }
1096
1097 if (xf < 0) {
1098 peaks[x] = 0;
1099 continue;
1100 }
1101
1102 float sx0 = (float(xf) / srRatio - modelStart) / modelResolution;
1103 float sx1 = (float(nxf) / srRatio - modelStart) / modelResolution;
1104
1105 int sx0i = int(sx0 + 0.001);
1106 int sx1i = int(sx1);
1107
1108 uchar peak = 0;
1109 for (int sx = sx0i; sx <= sx1i; ++sx) {
1110 if (sx < 0 || sx >= m_cache->width()) continue;
1111 if (sourceLine[sx] > peak) peak = sourceLine[sx];
1112 }
1113 peaks[x] = peak;
1061 } 1114 }
1062 continue;
1063 } 1115 }
1064 1116
1065 xf /= srRatio; 1117 copy:
1066 1118 for (int x = 0; x < w; ++x) {
1067 float sx0 = (float(xf) - modelStart) / modelResolution; 1119 targetLine[x] = peaks[x];
1068 float sx1 = (float(v->getFrameForX(x+1) / srRatio) - modelStart) / modelResolution;
1069
1070 int sx0i = int(sx0 + 0.001);
1071 int sx1i = int(sx1);
1072
1073 for (int y = 0; y < h; ++y) {
1074
1075 float sy0 = symin + (float(h - y - 1) * (symax - symin)) / h;
1076 float sy1 = symin + (float(h - y) * (symax - symin)) / h;
1077
1078 int sy0i = int(sy0 + 0.001);
1079 int sy1i = int(sy1);
1080
1081 float mag = 0.0, div = 0.0;
1082 int max = 0;
1083
1084 for (int sx = sx0i; sx <= sx1i; ++sx) {
1085
1086 if (sx < 0 || sx >= m_cache->width()) continue;
1087
1088 for (int sy = sy0i; sy <= sy1i; ++sy) {
1089
1090 if (sy < 0 || sy >= m_cache->height()) continue;
1091
1092 float prop = 1.0;
1093 if (sx == sx0i) prop *= (sx + 1) - sx0;
1094 if (sx == sx1i) prop *= sx1 - sx;
1095 if (sy == sy0i) prop *= (sy + 1) - sy0;
1096 if (sy == sy1i) prop *= sy1 - sy;
1097
1098 mag += prop * m_cache->pixelIndex(sx, sy);
1099 max = std::max(max, m_cache->pixelIndex(sx, sy));
1100 div += prop;
1101 }
1102 }
1103
1104 if (div != 0) mag /= div;
1105 if (mag < 0) mag = 0;
1106 if (mag > 255) mag = 255;
1107 if (max < 0) max = 0;
1108 if (max > 255) max = 255;
1109
1110 img.setPixel(x - x0, y, m_cache->color(int(mag + 0.001)));
1111 } 1120 }
1112 } 1121 }
1113 1122
1114 paint.drawImage(x0, 0, img); 1123 paint.drawImage(x0, 0, img);
1115 } 1124 }