comparison layer/Colour3DPlotLayer.cpp @ 946:36cddc3de023 alignment_view

Merge from default branch
author Chris Cannam
date Mon, 20 Apr 2015 09:19:52 +0100
parents 4a578a360011
children 94e4952a6774 1c37aa13bfd8
comparison
equal deleted inserted replaced
897:499b637f2a26 946:36cddc3de023
31 #include <cassert> 31 #include <cassert>
32 32
33 #ifndef __GNUC__ 33 #ifndef __GNUC__
34 #include <alloca.h> 34 #include <alloca.h>
35 #endif 35 #endif
36
37 using std::vector;
36 38
37 //#define DEBUG_COLOUR_3D_PLOT_LAYER_PAINT 1 39 //#define DEBUG_COLOUR_3D_PLOT_LAYER_PAINT 1
38 40
39 41
40 Colour3DPlotLayer::Colour3DPlotLayer() : 42 Colour3DPlotLayer::Colour3DPlotLayer() :
76 if (!m_model || !m_model->isOK()) return; 78 if (!m_model || !m_model->isOK()) return;
77 79
78 connectSignals(m_model); 80 connectSignals(m_model);
79 81
80 connect(m_model, SIGNAL(modelChanged()), this, SLOT(modelChanged())); 82 connect(m_model, SIGNAL(modelChanged()), this, SLOT(modelChanged()));
81 connect(m_model, SIGNAL(modelChangedWithin(int, int)), 83 connect(m_model, SIGNAL(modelChangedWithin(sv_frame_t, sv_frame_t)),
82 this, SLOT(modelChangedWithin(int, int))); 84 this, SLOT(modelChangedWithin(sv_frame_t, sv_frame_t)));
83 85
84 m_peakResolution = 256; 86 m_peakResolution = 256;
85 if (model->getResolution() > 512) { 87 if (model->getResolution() > 512) {
86 m_peakResolution = 16; 88 m_peakResolution = 16;
87 } else if (model->getResolution() > 128) { 89 } else if (model->getResolution() > 128) {
105 m_cacheValidStart = 0; 107 m_cacheValidStart = 0;
106 m_cacheValidEnd = 0; 108 m_cacheValidEnd = 0;
107 } 109 }
108 110
109 void 111 void
110 Colour3DPlotLayer::cacheInvalid(int startFrame, int endFrame) 112 Colour3DPlotLayer::cacheInvalid(sv_frame_t startFrame, sv_frame_t endFrame)
111 { 113 {
112 if (!m_cache || !m_model) return; 114 if (!m_cache || !m_model) return;
113 115
114 int modelResolution = m_model->getResolution(); 116 int modelResolution = m_model->getResolution();
115 int start = startFrame / modelResolution; 117 int start = int(startFrame / modelResolution);
116 int end = endFrame / modelResolution + 1; 118 int end = int(endFrame / modelResolution + 1);
117 if (m_cacheValidStart < end) m_cacheValidStart = end; 119 if (m_cacheValidStart < end) m_cacheValidStart = end;
118 if (m_cacheValidEnd > start) m_cacheValidEnd = start; 120 if (m_cacheValidEnd > start) m_cacheValidEnd = start;
119 if (m_cacheValidStart > m_cacheValidEnd) m_cacheValidEnd = m_cacheValidStart; 121 if (m_cacheValidStart > m_cacheValidEnd) m_cacheValidEnd = m_cacheValidStart;
120 } 122 }
121 123
133 } 135 }
134 cacheInvalid(); 136 cacheInvalid();
135 } 137 }
136 138
137 void 139 void
138 Colour3DPlotLayer::modelChangedWithin(int startFrame, int endFrame) 140 Colour3DPlotLayer::modelChangedWithin(sv_frame_t startFrame, sv_frame_t endFrame)
139 { 141 {
140 if (!m_colourScaleSet && m_colourScale == LinearScale) { 142 if (!m_colourScaleSet && m_colourScale == LinearScale) {
141 if (m_model && m_model->getWidth() > 50) { 143 if (m_model && m_model->getWidth() > 50) {
142 if (m_model->shouldUseLogValueScale()) { 144 if (m_model->shouldUseLogValueScale()) {
143 setColourScale(LogScale); 145 setColourScale(LogScale);
232 if (name == "Gain") { 234 if (name == "Gain") {
233 235
234 *min = -50; 236 *min = -50;
235 *max = 50; 237 *max = 50;
236 238
237 *deflt = lrintf(log10(1.f) * 20.0);; 239 *deflt = int(lrint(log10(1.0) * 20.0));
238 if (*deflt < *min) *deflt = *min; 240 if (*deflt < *min) *deflt = *min;
239 if (*deflt > *max) *deflt = *max; 241 if (*deflt > *max) *deflt = *max;
240 242
241 val = lrintf(log10(m_gain) * 20.0); 243 val = int(lrint(log10(m_gain) * 20.0));
242 if (val < *min) val = *min; 244 if (val < *min) val = *min;
243 if (val > *max) val = *max; 245 if (val > *max) val = *max;
244 246
245 } else if (name == "Colour Scale") { 247 } else if (name == "Colour Scale") {
246 248
334 336
335 void 337 void
336 Colour3DPlotLayer::setProperty(const PropertyName &name, int value) 338 Colour3DPlotLayer::setProperty(const PropertyName &name, int value)
337 { 339 {
338 if (name == "Gain") { 340 if (name == "Gain") {
339 setGain(pow(10, float(value)/20.0)); 341 setGain(float(pow(10, value/20.0)));
340 } else if (name == "Colour Scale") { 342 } else if (name == "Colour Scale") {
341 switch (value) { 343 switch (value) {
342 default: 344 default:
343 case 0: setColourScale(LinearScale); break; 345 case 0: setColourScale(LinearScale); break;
344 case 1: setColourScale(LogScale); break; 346 case 1: setColourScale(LogScale); break;
539 QPoint discard; 541 QPoint discard;
540 return !v->shouldIlluminateLocalFeatures(this, discard); 542 return !v->shouldIlluminateLocalFeatures(this, discard);
541 } 543 }
542 544
543 bool 545 bool
544 Colour3DPlotLayer::getValueExtents(float &min, float &max, 546 Colour3DPlotLayer::getValueExtents(double &min, double &max,
545 bool &logarithmic, QString &unit) const 547 bool &logarithmic, QString &unit) const
546 { 548 {
547 if (!m_model) return false; 549 if (!m_model) return false;
548 550
549 min = 0; 551 min = 0;
550 max = m_model->getHeight(); 552 max = double(m_model->getHeight());
551 553
552 logarithmic = false; 554 logarithmic = false;
553 unit = ""; 555 unit = "";
554 556
555 return true; 557 return true;
556 } 558 }
557 559
558 bool 560 bool
559 Colour3DPlotLayer::getDisplayExtents(float &min, float &max) const 561 Colour3DPlotLayer::getDisplayExtents(double &min, double &max) const
560 { 562 {
561 if (!m_model) return false; 563 if (!m_model) return false;
562 564
565 double hmax = double(m_model->getHeight());
566
563 min = m_miny; 567 min = m_miny;
564 max = m_maxy; 568 max = m_maxy;
565 if (max <= min) { 569 if (max <= min) {
566 min = 0; 570 min = 0;
567 max = m_model->getHeight(); 571 max = hmax;
568 } 572 }
569 if (min < 0) min = 0; 573 if (min < 0) min = 0;
570 if (max > m_model->getHeight()) max = m_model->getHeight(); 574 if (max > hmax) max = hmax;
571 575
572 return true; 576 return true;
573 } 577 }
574 578
575 bool 579 bool
576 Colour3DPlotLayer::setDisplayExtents(float min, float max) 580 Colour3DPlotLayer::setDisplayExtents(double min, double max)
577 { 581 {
578 if (!m_model) return false; 582 if (!m_model) return false;
579 583
580 m_miny = lrintf(min); 584 m_miny = int(lrint(min));
581 m_maxy = lrintf(max); 585 m_maxy = int(lrint(max));
582 586
583 emit layerParametersChanged(); 587 emit layerParametersChanged();
584 return true; 588 return true;
585 } 589 }
586 590
587 bool 591 bool
588 Colour3DPlotLayer::getYScaleValue(const View *, int, 592 Colour3DPlotLayer::getYScaleValue(const View *, int,
589 float &, QString &) const 593 double &, QString &) const
590 { 594 {
591 return false;//!!! 595 return false;//!!!
592 } 596 }
593 597
594 int 598 int
604 int 608 int
605 Colour3DPlotLayer::getCurrentVerticalZoomStep() const 609 Colour3DPlotLayer::getCurrentVerticalZoomStep() const
606 { 610 {
607 if (!m_model) return 0; 611 if (!m_model) return 0;
608 612
609 float min, max; 613 double min, max;
610 getDisplayExtents(min, max); 614 getDisplayExtents(min, max);
611 return m_model->getHeight() - lrintf(max - min); 615 return m_model->getHeight() - int(lrint(max - min));
612 } 616 }
613 617
614 void 618 void
615 Colour3DPlotLayer::setVerticalZoomStep(int step) 619 Colour3DPlotLayer::setVerticalZoomStep(int step)
616 { 620 {
618 622
619 // SVDEBUG << "Colour3DPlotLayer::setVerticalZoomStep(" <<step <<"): before: miny = " << m_miny << ", maxy = " << m_maxy << endl; 623 // SVDEBUG << "Colour3DPlotLayer::setVerticalZoomStep(" <<step <<"): before: miny = " << m_miny << ", maxy = " << m_maxy << endl;
620 624
621 int dist = m_model->getHeight() - step; 625 int dist = m_model->getHeight() - step;
622 if (dist < 1) dist = 1; 626 if (dist < 1) dist = 1;
623 float centre = m_miny + (float(m_maxy) - float(m_miny)) / 2.f; 627 double centre = m_miny + (m_maxy - m_miny) / 2.0;
624 m_miny = lrintf(centre - float(dist)/2); 628 m_miny = int(lrint(centre - dist/2.0));
625 if (m_miny < 0) m_miny = 0; 629 if (m_miny < 0) m_miny = 0;
626 m_maxy = m_miny + dist; 630 m_maxy = m_miny + dist;
627 if (m_maxy > m_model->getHeight()) m_maxy = m_model->getHeight(); 631 if (m_maxy > m_model->getHeight()) m_maxy = m_model->getHeight();
628 632
629 // SVDEBUG << "Colour3DPlotLayer::setVerticalZoomStep(" <<step <<"): after: miny = " << m_miny << ", maxy = " << m_maxy << endl; 633 // SVDEBUG << "Colour3DPlotLayer::setVerticalZoomStep(" <<step <<"): after: miny = " << m_miny << ", maxy = " << m_maxy << endl;
638 642
639 return new LinearRangeMapper(0, m_model->getHeight(), 643 return new LinearRangeMapper(0, m_model->getHeight(),
640 0, m_model->getHeight(), ""); 644 0, m_model->getHeight(), "");
641 } 645 }
642 646
643 float 647 double
644 Colour3DPlotLayer::getYForBin(View *v, float bin) const 648 Colour3DPlotLayer::getYForBin(View *v, double bin) const
645 { 649 {
646 float y = bin; 650 double y = bin;
647 if (!m_model) return y; 651 if (!m_model) return y;
648 float mn = 0, mx = m_model->getHeight(); 652 double mn = 0, mx = m_model->getHeight();
649 getDisplayExtents(mn, mx); 653 getDisplayExtents(mn, mx);
650 float h = v->height(); 654 double h = v->height();
651 if (m_binScale == LinearBinScale) { 655 if (m_binScale == LinearBinScale) {
652 y = h - (((bin - mn) * h) / (mx - mn)); 656 y = h - (((bin - mn) * h) / (mx - mn));
653 } else { 657 } else {
654 float logmin = mn + 1, logmax = mx + 1; 658 double logmin = mn + 1, logmax = mx + 1;
655 LogRange::mapRange(logmin, logmax); 659 LogRange::mapRange(logmin, logmax);
656 y = h - (((LogRange::map(bin + 1) - logmin) * h) / (logmax - logmin)); 660 y = h - (((LogRange::map(bin + 1) - logmin) * h) / (logmax - logmin));
657 } 661 }
658 return y; 662 return y;
659 } 663 }
660 664
661 float 665 int
662 Colour3DPlotLayer::getBinForY(View *v, float y) const 666 Colour3DPlotLayer::getIYForBin(View *v, int bin) const
663 { 667 {
664 float bin = y; 668 return int(round(getYForBin(v, bin)));
669 }
670
671 double
672 Colour3DPlotLayer::getBinForY(View *v, double y) const
673 {
674 double bin = y;
665 if (!m_model) return bin; 675 if (!m_model) return bin;
666 float mn = 0, mx = m_model->getHeight(); 676 double mn = 0, mx = m_model->getHeight();
667 getDisplayExtents(mn, mx); 677 getDisplayExtents(mn, mx);
668 float h = v->height(); 678 double h = v->height();
669 if (m_binScale == LinearBinScale) { 679 if (m_binScale == LinearBinScale) {
670 bin = mn + ((h - y) * (mx - mn)) / h; 680 bin = mn + ((h - y) * (mx - mn)) / h;
671 } else { 681 } else {
672 float logmin = mn + 1, logmax = mx + 1; 682 double logmin = mn + 1, logmax = mx + 1;
673 LogRange::mapRange(logmin, logmax); 683 LogRange::mapRange(logmin, logmax);
674 bin = LogRange::unmap(logmin + ((h - y) * (logmax - logmin)) / h) - 1; 684 bin = LogRange::unmap(logmin + ((h - y) * (logmax - logmin)) / h) - 1;
675 } 685 }
676 return bin; 686 return bin;
677 } 687 }
678 688
689 int
690 Colour3DPlotLayer::getIBinForY(View *v, int y) const
691 {
692 return int(floor(getBinForY(v, y)));
693 }
694
679 QString 695 QString
680 Colour3DPlotLayer::getFeatureDescription(View *v, QPoint &pos) const 696 Colour3DPlotLayer::getFeatureDescription(View *v, QPoint &pos) const
681 { 697 {
682 if (!m_model) return ""; 698 if (!m_model) return "";
683 699
684 int x = pos.x(); 700 int x = pos.x();
685 int y = pos.y(); 701 int y = pos.y();
686 702
687 int modelStart = m_model->getStartFrame(); 703 sv_frame_t modelStart = m_model->getStartFrame();
688 int modelResolution = m_model->getResolution(); 704 int modelResolution = m_model->getResolution();
689 705
690 float srRatio = 706 double srRatio =
691 float(v->getViewManager()->getMainModelSampleRate()) / 707 v->getViewManager()->getMainModelSampleRate() /
692 float(m_model->getSampleRate()); 708 m_model->getSampleRate();
693 709
694 int sx0 = int((v->getFrameForX(x) / srRatio - modelStart) / 710 int sx0 = int((double(v->getFrameForX(x)) / srRatio - double(modelStart)) /
695 modelResolution); 711 modelResolution);
696 712
697 int f0 = sx0 * modelResolution; 713 int f0 = sx0 * modelResolution;
698 int f1 = f0 + modelResolution; 714 int f1 = f0 + modelResolution;
699 715
706 symax = sh; 722 symax = sh;
707 } 723 }
708 if (symin < 0) symin = 0; 724 if (symin < 0) symin = 0;
709 if (symax > sh) symax = sh; 725 if (symax > sh) symax = sh;
710 726
711 // float binHeight = float(v->height()) / (symax - symin); 727 // double binHeight = double(v->height()) / (symax - symin);
712 // int sy = int((v->height() - y) / binHeight) + symin; 728 // int sy = int((v->height() - y) / binHeight) + symin;
713 729
714 int sy = getBinForY(v, y); 730 int sy = getIBinForY(v, y);
715 731
716 if (sy < 0 || sy >= m_model->getHeight()) { 732 if (sy < 0 || sy >= m_model->getHeight()) {
717 return ""; 733 return "";
718 } 734 }
719 735
777 int cw = getColourScaleWidth(paint); 793 int cw = getColourScaleWidth(paint);
778 794
779 int ch = h - 20; 795 int ch = h - 20;
780 if (ch > 20 && m_cache) { 796 if (ch > 20 && m_cache) {
781 797
782 float min = m_model->getMinimumLevel(); 798 double min = m_model->getMinimumLevel();
783 float max = m_model->getMaximumLevel(); 799 double max = m_model->getMaximumLevel();
784 800
785 float mmin = min; 801 double mmin = min;
786 float mmax = max; 802 double mmax = max;
787 803
788 if (m_colourScale == LogScale) { 804 if (m_colourScale == LogScale) {
789 LogRange::mapRange(mmin, mmax); 805 LogRange::mapRange(mmin, mmax);
790 } else if (m_colourScale == PlusMinusOneScale) { 806 } else if (m_colourScale == PlusMinusOneScale) {
791 mmin = -1.f; 807 mmin = -1.f;
792 mmax = 1.f; 808 mmax = 1.f;
793 } else if (m_colourScale == AbsoluteScale) { 809 } else if (m_colourScale == AbsoluteScale) {
794 if (mmin < 0) { 810 if (mmin < 0) {
795 if (fabsf(mmin) > fabsf(mmax)) mmax = fabsf(mmin); 811 if (fabs(mmin) > fabs(mmax)) mmax = fabs(mmin);
796 else mmax = fabsf(mmax); 812 else mmax = fabs(mmax);
797 mmin = 0; 813 mmin = 0;
798 } else { 814 } else {
799 mmin = fabsf(mmin); 815 mmin = fabs(mmin);
800 mmax = fabsf(mmax); 816 mmax = fabs(mmax);
801 } 817 }
802 } 818 }
803 819
804 if (max == min) max = min + 1.0; 820 if (max == min) max = min + 1.f;
805 if (mmax == mmin) mmax = mmin + 1.0; 821 if (mmax == mmin) mmax = mmin + 1.f;
806 822
807 paint.setPen(v->getForeground()); 823 paint.setPen(v->getForeground());
808 paint.drawRect(4, 10, cw - 8, ch+1); 824 paint.drawRect(4, 10, cw - 8, ch+1);
809 825
810 for (int y = 0; y < ch; ++y) { 826 for (int y = 0; y < ch; ++y) {
811 float value = ((max - min) * (ch - y - 1)) / ch + min; 827 double value = ((max - min) * (double(ch-y) - 1.0)) / double(ch) + min;
812 if (m_colourScale == LogScale) { 828 if (m_colourScale == LogScale) {
813 value = LogRange::map(value); 829 value = LogRange::map(value);
814 } 830 }
815 int pixel = int(((value - mmin) * 256) / (mmax - mmin)); 831 int pixel = int(((value - mmin) * 256) / (mmax - mmin));
816 if (pixel >= 0 && pixel < 256) { 832 if (pixel >= 0 && pixel < 256) {
868 884
869 for (int i = symin; i <= symax; ++i) { 885 for (int i = symin; i <= symax; ++i) {
870 886
871 int y0; 887 int y0;
872 888
873 y0 = lrintf(getYForBin(v, i)); 889 y0 = getIYForBin(v, i);
874 int h = py - y0; 890 int h = py - y0;
875 891
876 if (i > symin) { 892 if (i > symin) {
877 if (paint.fontMetrics().height() >= h) { 893 if (paint.fontMetrics().height() >= h) {
878 if (h >= 8) { 894 if (h >= 8) {
916 932
917 DenseThreeDimensionalModel::Column values = m_model->getColumn(col); 933 DenseThreeDimensionalModel::Column values = m_model->getColumn(col);
918 while (values.size() < m_model->getHeight()) values.push_back(0.f); 934 while (values.size() < m_model->getHeight()) values.push_back(0.f);
919 if (!m_normalizeColumns && !m_normalizeHybrid) return values; 935 if (!m_normalizeColumns && !m_normalizeHybrid) return values;
920 936
921 float colMax = 0.f, colMin = 0.f; 937 double colMax = 0.f, colMin = 0.f;
922 float min = 0.f, max = 0.f; 938 double min = 0.f, max = 0.f;
923 939
924 min = m_model->getMinimumLevel(); 940 min = m_model->getMinimumLevel();
925 max = m_model->getMaximumLevel(); 941 max = m_model->getMaximumLevel();
926 942
927 for (int y = 0; y < values.size(); ++y) { 943 for (int y = 0; y < values.size(); ++y) {
930 } 946 }
931 if (colMin == colMax) colMax = colMin + 1; 947 if (colMin == colMax) colMax = colMin + 1;
932 948
933 for (int y = 0; y < values.size(); ++y) { 949 for (int y = 0; y < values.size(); ++y) {
934 950
935 float value = values.at(y); 951 double value = values.at(y);
936 float norm = (value - colMin) / (colMax - colMin); 952 double norm = (value - colMin) / (colMax - colMin);
937 float newvalue = min + (max - min) * norm; 953 double newvalue = min + (max - min) * norm;
938 954
939 if (value != newvalue) values[y] = newvalue; 955 if (value != newvalue) values[y] = float(newvalue);
940 } 956 }
941 957
942 if (m_normalizeHybrid && (colMax > 0.0)) { 958 if (m_normalizeHybrid && (colMax > 0.0)) {
943 float logmax = log10(colMax); 959 double logmax = log10(colMax);
944 for (int y = 0; y < values.size(); ++y) { 960 for (int y = 0; y < values.size(); ++y) {
945 values[y] *= logmax; 961 values[y] = float(values[y] * logmax);
946 } 962 }
947 } 963 }
948 964
949 return values; 965 return values;
950 } 966 }
952 void 968 void
953 Colour3DPlotLayer::fillCache(int firstBin, int lastBin) const 969 Colour3DPlotLayer::fillCache(int firstBin, int lastBin) const
954 { 970 {
955 Profiler profiler("Colour3DPlotLayer::fillCache", true); 971 Profiler profiler("Colour3DPlotLayer::fillCache", true);
956 972
957 int modelStart = m_model->getStartFrame(); 973 sv_frame_t modelStart = m_model->getStartFrame();
958 int modelEnd = m_model->getEndFrame(); 974 sv_frame_t modelEnd = m_model->getEndFrame();
959 int modelResolution = m_model->getResolution(); 975 int modelResolution = m_model->getResolution();
960 976
961 int modelStartBin = modelStart / modelResolution; 977 int modelStartBin = int(modelStart / modelResolution);
962 int modelEndBin = modelEnd / modelResolution; 978 int modelEndBin = int(modelEnd / modelResolution);
963 979
964 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT 980 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT
965 cerr << "Colour3DPlotLayer::fillCache: range " << firstBin << " -> " << lastBin << " of model range " << modelStartBin << " -> " << modelEndBin << " (model resolution " << modelResolution << ")" << endl; 981 cerr << "Colour3DPlotLayer::fillCache: range " << firstBin << " -> " << lastBin << " of model range " << modelStartBin << " -> " << modelEndBin << " (model resolution " << modelResolution << ")" << endl;
966 #endif 982 #endif
967 983
1067 cerr << "Cache size " << cacheWidth << "x" << cacheHeight << " will be valid from " << m_cacheValidStart << " to " << m_cacheValidEnd << " (fillStart = " << fillStart << ", fillEnd = " << fillEnd << ")" << endl; 1083 cerr << "Cache size " << cacheWidth << "x" << cacheHeight << " will be valid from " << m_cacheValidStart << " to " << m_cacheValidEnd << " (fillStart = " << fillStart << ", fillEnd = " << fillEnd << ")" << endl;
1068 #endif 1084 #endif
1069 1085
1070 DenseThreeDimensionalModel::Column values; 1086 DenseThreeDimensionalModel::Column values;
1071 1087
1072 float min = m_model->getMinimumLevel(); 1088 double min = m_model->getMinimumLevel();
1073 float max = m_model->getMaximumLevel(); 1089 double max = m_model->getMaximumLevel();
1074 1090
1075 if (m_colourScale == LogScale) { 1091 if (m_colourScale == LogScale) {
1076 LogRange::mapRange(min, max); 1092 LogRange::mapRange(min, max);
1077 } else if (m_colourScale == PlusMinusOneScale) { 1093 } else if (m_colourScale == PlusMinusOneScale) {
1078 min = -1.f; 1094 min = -1.f;
1079 max = 1.f; 1095 max = 1.f;
1080 } else if (m_colourScale == AbsoluteScale) { 1096 } else if (m_colourScale == AbsoluteScale) {
1081 if (min < 0) { 1097 if (min < 0) {
1082 if (fabsf(min) > fabsf(max)) max = fabsf(min); 1098 if (fabs(min) > fabs(max)) max = fabs(min);
1083 else max = fabsf(max); 1099 else max = fabs(max);
1084 min = 0; 1100 min = 0;
1085 } else { 1101 } else {
1086 min = fabsf(min); 1102 min = fabs(min);
1087 max = fabsf(max); 1103 max = fabs(max);
1088 } 1104 }
1089 } 1105 }
1090 1106
1091 if (max == min) max = min + 1.0; 1107 if (max == min) max = min + 1.f;
1092 1108
1093 ColourMapper mapper(m_colourMap, 0.f, 255.f); 1109 ColourMapper mapper(m_colourMap, 0.f, 255.f);
1094 1110
1095 for (int index = 0; index < 256; ++index) { 1111 for (int index = 0; index < 256; ++index) {
1096 QColor colour = mapper.map(index); 1112 QColor colour = mapper.map(index);
1100 m_peaksCache->setColor 1116 m_peaksCache->setColor
1101 (index, qRgb(colour.red(), colour.green(), colour.blue())); 1117 (index, qRgb(colour.red(), colour.green(), colour.blue()));
1102 } 1118 }
1103 } 1119 }
1104 1120
1105 float visibleMax = 0.f, visibleMin = 0.f; 1121 double visibleMax = 0.f, visibleMin = 0.f;
1106 1122
1107 if (normalizeVisible) { 1123 if (normalizeVisible) {
1108 1124
1109 for (int c = fillStart; c <= fillEnd; ++c) { 1125 for (int c = fillStart; c <= fillEnd; ++c) {
1110 1126
1111 values = getColumn(c); 1127 values = getColumn(c);
1112 1128
1113 float colMax = 0.f, colMin = 0.f; 1129 double colMax = 0.f, colMin = 0.f;
1114 1130
1115 for (int y = 0; y < cacheHeight; ++y) { 1131 for (int y = 0; y < cacheHeight; ++y) {
1116 if (y >= values.size()) break; 1132 if (y >= values.size()) break;
1117 if (y == 0 || values[y] > colMax) colMax = values[y]; 1133 if (y == 0 || values[y] > colMax) colMax = values[y];
1118 if (y == 0 || values[y] < colMin) colMin = values[y]; 1134 if (y == 0 || values[y] < colMin) colMin = values[y];
1126 visibleMin = LogRange::map(visibleMin); 1142 visibleMin = LogRange::map(visibleMin);
1127 visibleMax = LogRange::map(visibleMax); 1143 visibleMax = LogRange::map(visibleMax);
1128 if (visibleMin > visibleMax) std::swap(visibleMin, visibleMax); 1144 if (visibleMin > visibleMax) std::swap(visibleMin, visibleMax);
1129 } else if (m_colourScale == AbsoluteScale) { 1145 } else if (m_colourScale == AbsoluteScale) {
1130 if (visibleMin < 0) { 1146 if (visibleMin < 0) {
1131 if (fabsf(visibleMin) > fabsf(visibleMax)) visibleMax = fabsf(visibleMin); 1147 if (fabs(visibleMin) > fabs(visibleMax)) visibleMax = fabs(visibleMin);
1132 else visibleMax = fabsf(visibleMax); 1148 else visibleMax = fabs(visibleMax);
1133 visibleMin = 0; 1149 visibleMin = 0;
1134 } else { 1150 } else {
1135 visibleMin = fabsf(visibleMin); 1151 visibleMin = fabs(visibleMin);
1136 visibleMax = fabsf(visibleMax); 1152 visibleMax = fabs(visibleMax);
1137 } 1153 }
1138 } 1154 }
1139 } 1155 }
1140 1156
1141 if (visibleMin == visibleMax) visibleMax = visibleMin + 1; 1157 if (visibleMin == visibleMax) visibleMax = visibleMin + 1;
1160 continue; 1176 continue;
1161 } 1177 }
1162 1178
1163 for (int y = 0; y < cacheHeight; ++y) { 1179 for (int y = 0; y < cacheHeight; ++y) {
1164 1180
1165 float value = min; 1181 double value = min;
1166 if (y < values.size()) { 1182 if (y < values.size()) {
1167 value = values.at(y); 1183 value = values.at(y);
1168 } 1184 }
1169 1185
1170 value = value * m_gain; 1186 value = value * m_gain;
1171 1187
1172 if (m_colourScale == LogScale) { 1188 if (m_colourScale == LogScale) {
1173 value = LogRange::map(value); 1189 value = LogRange::map(value);
1174 } else if (m_colourScale == AbsoluteScale) { 1190 } else if (m_colourScale == AbsoluteScale) {
1175 value = fabsf(value); 1191 value = fabs(value);
1176 } 1192 }
1177 1193
1178 if (normalizeVisible) { 1194 if (normalizeVisible) {
1179 float norm = (value - visibleMin) / (visibleMax - visibleMin); 1195 double norm = (value - visibleMin) / (visibleMax - visibleMin);
1180 value = min + (max - min) * norm; 1196 value = min + (max - min) * norm;
1181 } 1197 }
1182 1198
1183 int pixel = int(((value - min) * 256) / (max - min)); 1199 int pixel = int(((value - min) * 256) / (max - min));
1184 if (pixel < 0) pixel = 0; 1200 if (pixel < 0) pixel = 0;
1233 Colour3DPlotLayer::shouldPaintDenseIn(const View *v) const 1249 Colour3DPlotLayer::shouldPaintDenseIn(const View *v) const
1234 { 1250 {
1235 if (!m_model || !v || !(v->getViewManager())) { 1251 if (!m_model || !v || !(v->getViewManager())) {
1236 return false; 1252 return false;
1237 } 1253 }
1238 float srRatio = 1254 double srRatio =
1239 float(v->getViewManager()->getMainModelSampleRate()) / 1255 v->getViewManager()->getMainModelSampleRate() / m_model->getSampleRate();
1240 float(m_model->getSampleRate());
1241 if (m_opaque || 1256 if (m_opaque ||
1242 m_smooth || 1257 m_smooth ||
1243 m_model->getHeight() >= v->height() || 1258 m_model->getHeight() >= v->height() ||
1244 ((m_model->getResolution() * srRatio) / v->getZoomLevel()) < 2) { 1259 ((m_model->getResolution() * srRatio) / v->getZoomLevel()) < 2) {
1245 return true; 1260 return true;
1269 return; 1284 return;
1270 } 1285 }
1271 1286
1272 if (m_normalizeVisibleArea && !m_normalizeColumns) rect = v->rect(); 1287 if (m_normalizeVisibleArea && !m_normalizeColumns) rect = v->rect();
1273 1288
1274 int modelStart = m_model->getStartFrame(); 1289 sv_frame_t modelStart = m_model->getStartFrame();
1275 int modelEnd = m_model->getEndFrame(); 1290 sv_frame_t modelEnd = m_model->getEndFrame();
1276 int modelResolution = m_model->getResolution(); 1291 int modelResolution = m_model->getResolution();
1277 1292
1278 // The cache is from the model's start frame to the model's end 1293 // The cache is from the model's start frame to the model's end
1279 // frame at the model's window increment frames per pixel. We 1294 // frame at the model's window increment frames per pixel. We
1280 // want to draw from our start frame + x0 * zoomLevel to our start 1295 // want to draw from our start frame + x0 * zoomLevel to our start
1287 int x0 = rect.left(); 1302 int x0 = rect.left();
1288 int x1 = rect.right() + 1; 1303 int x1 = rect.right() + 1;
1289 1304
1290 int h = v->height(); 1305 int h = v->height();
1291 1306
1292 float srRatio = 1307 double srRatio =
1293 float(v->getViewManager()->getMainModelSampleRate()) / 1308 v->getViewManager()->getMainModelSampleRate() / m_model->getSampleRate();
1294 float(m_model->getSampleRate()); 1309
1295 1310 int sx0 = int((double(v->getFrameForX(x0)) / srRatio - double(modelStart))
1296 int sx0 = int((v->getFrameForX(x0) / srRatio - modelStart)
1297 / modelResolution); 1311 / modelResolution);
1298 int sx1 = int((v->getFrameForX(x1) / srRatio - modelStart) 1312 int sx1 = int((double(v->getFrameForX(x1)) / srRatio - double(modelStart))
1299 / modelResolution); 1313 / modelResolution);
1300 int sh = m_model->getHeight(); 1314 int sh = m_model->getHeight();
1301 1315
1302 int symin = m_miny; 1316 int symin = m_miny;
1303 int symax = m_maxy; 1317 int symax = m_maxy;
1335 const int buflen = 40; 1349 const int buflen = 40;
1336 char labelbuf[buflen]; 1350 char labelbuf[buflen];
1337 1351
1338 for (int sx = sx0; sx <= sx1; ++sx) { 1352 for (int sx = sx0; sx <= sx1; ++sx) {
1339 1353
1340 int fx = sx * modelResolution; 1354 sv_frame_t fx = sx * modelResolution;
1341 1355
1342 if (fx + modelResolution <= modelStart || fx > modelEnd) continue; 1356 if (fx + modelResolution <= modelStart || fx > modelEnd) continue;
1343 1357
1344 int rx0 = v->getXForFrame(int((fx + modelStart) * srRatio)); 1358 int rx0 = v->getXForFrame(int(double(fx + modelStart) * srRatio));
1345 int rx1 = v->getXForFrame(int((fx + modelStart + modelResolution + 1) * srRatio)); 1359 int rx1 = v->getXForFrame(int(double(fx + modelStart + modelResolution + 1) * srRatio));
1346 1360
1347 int rw = rx1 - rx0; 1361 int rw = rx1 - rx0;
1348 if (rw < 1) rw = 1; 1362 if (rw < 1) rw = 1;
1349 1363
1350 bool showLabel = (rw > 10 && 1364 bool showLabel = (rw > 10 &&
1351 paint.fontMetrics().width("0.000000") < rw - 3 && 1365 paint.fontMetrics().width("0.000000") < rw - 3 &&
1352 paint.fontMetrics().height() < (h / sh)); 1366 paint.fontMetrics().height() < (h / sh));
1353 1367
1354 for (int sy = symin; sy < symax; ++sy) { 1368 for (int sy = symin; sy < symax; ++sy) {
1355 1369
1356 int ry0 = getYForBin(v, sy); 1370 int ry0 = getIYForBin(v, sy);
1357 int ry1 = getYForBin(v, sy + 1); 1371 int ry1 = getIYForBin(v, sy + 1);
1358 QRect r(rx0, ry1, rw, ry0 - ry1); 1372 QRect r(rx0, ry1, rw, ry0 - ry1);
1359 1373
1360 QRgb pixel = qRgb(255, 255, 255); 1374 QRgb pixel = qRgb(255, 255, 255);
1361 if (sx >= 0 && sx < m_cache->width() && 1375 if (sx >= 0 && sx < m_cache->width() &&
1362 sy >= 0 && sy < m_cache->height()) { 1376 sy >= 0 && sy < m_cache->height()) {
1394 paint.drawRect(r); 1408 paint.drawRect(r);
1395 1409
1396 if (showLabel) { 1410 if (showLabel) {
1397 if (sx >= 0 && sx < m_cache->width() && 1411 if (sx >= 0 && sx < m_cache->width() &&
1398 sy >= 0 && sy < m_cache->height()) { 1412 sy >= 0 && sy < m_cache->height()) {
1399 float value = m_model->getValueAt(sx, sy); 1413 double value = m_model->getValueAt(sx, sy);
1400 snprintf(labelbuf, buflen, "%06f", value); 1414 snprintf(labelbuf, buflen, "%06f", value);
1401 QString text(labelbuf); 1415 QString text(labelbuf);
1402 paint.setPen(v->getBackground()); 1416 paint.setPen(v->getBackground());
1403 paint.drawText(rx0 + 2, 1417 paint.drawText(rx0 + 2,
1404 ry0 - h / sh - 1 + 2 + paint.fontMetrics().ascent(), 1418 ry0 - h / sh - 1 + 2 + paint.fontMetrics().ascent(),
1413 Colour3DPlotLayer::paintDense(View *v, QPainter &paint, QRect rect) const 1427 Colour3DPlotLayer::paintDense(View *v, QPainter &paint, QRect rect) const
1414 { 1428 {
1415 Profiler profiler("Colour3DPlotLayer::paintDense", true); 1429 Profiler profiler("Colour3DPlotLayer::paintDense", true);
1416 if (!m_cache) return; 1430 if (!m_cache) return;
1417 1431
1418 float modelStart = m_model->getStartFrame(); 1432 double modelStart = double(m_model->getStartFrame());
1419 float modelResolution = m_model->getResolution(); 1433 double modelResolution = double(m_model->getResolution());
1420 1434
1421 int mmsr = v->getViewManager()->getMainModelSampleRate(); 1435 sv_samplerate_t mmsr = v->getViewManager()->getMainModelSampleRate();
1422 int msr = m_model->getSampleRate(); 1436 sv_samplerate_t msr = m_model->getSampleRate();
1423 float srRatio = float(mmsr) / float(msr); 1437 double srRatio = mmsr / msr;
1424 1438
1425 int x0 = rect.left(); 1439 int x0 = rect.left();
1426 int x1 = rect.right() + 1; 1440 int x1 = rect.right() + 1;
1427 1441
1428 const int w = x1 - x0; // const so it can be used as array size below 1442 const int w = x1 - x0; // const so it can be used as array size below
1474 #endif 1488 #endif
1475 } 1489 }
1476 1490
1477 int sw = source->width(); 1491 int sw = source->width();
1478 1492
1479 int xf = -1; 1493 sv_frame_t xf = -1;
1480 int nxf = v->getFrameForX(x0); 1494 sv_frame_t nxf = v->getFrameForX(x0);
1481 1495
1482 float epsilon = 0.000001; 1496 double epsilon = 0.000001;
1483 1497
1484 #ifdef __GNUC__ 1498 vector<double> sxa(w*2);
1485 float sxa[w * 2]; 1499
1486 #else
1487 float *sxa = (float *)alloca(w * 2 * sizeof(float));
1488 #endif
1489 for (int x = 0; x < w; ++x) { 1500 for (int x = 0; x < w; ++x) {
1490 1501
1491 xf = nxf; 1502 xf = nxf;
1492 nxf = xf + zoomLevel; 1503 nxf = xf + zoomLevel;
1493 1504
1494 float sx0 = (float(xf) / srRatio - modelStart) / modelResolution; 1505 double sx0 = (double(xf) / srRatio - modelStart) / modelResolution;
1495 float sx1 = (float(nxf) / srRatio - modelStart) / modelResolution; 1506 double sx1 = (double(nxf) / srRatio - modelStart) / modelResolution;
1496 1507
1497 sxa[x*2] = sx0; 1508 sxa[x*2] = sx0;
1498 sxa[x*2 + 1] = sx1; 1509 sxa[x*2 + 1] = sx1;
1499 } 1510 }
1500 1511
1501 float logmin = symin+1, logmax = symax+1; 1512 double logmin = symin+1, logmax = symax+1;
1502 LogRange::mapRange(logmin, logmax); 1513 LogRange::mapRange(logmin, logmax);
1503 1514
1504 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT 1515 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT
1505 cerr << "m_smooth = " << m_smooth << ", w = " << w << ", h = " << h << endl; 1516 cerr << "m_smooth = " << m_smooth << ", w = " << w << ", h = " << h << endl;
1506 #endif 1517 #endif
1507 1518
1508 if (m_smooth) { 1519 if (m_smooth) {
1509 1520
1510 for (int y = 0; y < h; ++y) { 1521 for (int y = 0; y < h; ++y) {
1511 1522
1512 float sy = getBinForY(v, y) - 0.5; 1523 double sy = getBinForY(v, y) - 0.5;
1513 int syi = int(sy + epsilon); 1524 int syi = int(sy + epsilon);
1514 if (syi < 0 || syi >= source->height()) continue; 1525 if (syi < 0 || syi >= source->height()) continue;
1515 1526
1516 uchar *targetLine = img.scanLine(y); 1527 uchar *targetLine = img.scanLine(y);
1517 uchar *sourceLine = source->scanLine(syi); 1528 uchar *sourceLine = source->scanLine(syi);
1524 1535
1525 for (int x = 0; x < w; ++x) { 1536 for (int x = 0; x < w; ++x) {
1526 1537
1527 targetLine[x] = 0; 1538 targetLine[x] = 0;
1528 1539
1529 float sx0 = sxa[x*2]; 1540 double sx0 = sxa[x*2];
1530 if (sx0 < 0) continue; 1541 if (sx0 < 0) continue;
1531 int sx0i = int(sx0 + epsilon); 1542 int sx0i = int(sx0 + epsilon);
1532 if (sx0i >= sw) break; 1543 if (sx0i >= sw) break;
1533 1544
1534 float a = float(sourceLine[sx0i]); 1545 double a = sourceLine[sx0i];
1535 float b = a; 1546 double b = a;
1536 float value; 1547 double value;
1537 1548
1538 float sx1 = sxa[x*2+1]; 1549 double sx1 = sxa[x*2+1];
1539 if (sx1 > sx0 + 1.f) { 1550 if (sx1 > sx0 + 1.f) {
1540 int sx1i = int(sx1); 1551 int sx1i = int(sx1);
1541 bool have = false; 1552 bool have = false;
1542 for (int sx = sx0i; sx <= sx1i; ++sx) { 1553 for (int sx = sx0i; sx <= sx1i; ++sx) {
1543 if (sx < 0 || sx >= sw) continue; 1554 if (sx < 0 || sx >= sw) continue;
1544 if (!have) { 1555 if (!have) {
1545 a = float(sourceLine[sx]); 1556 a = sourceLine[sx];
1546 b = float(nextSource[sx]); 1557 b = nextSource[sx];
1547 have = true; 1558 have = true;
1548 } else { 1559 } else {
1549 a = std::max(a, float(sourceLine[sx])); 1560 a = std::max(a, double(sourceLine[sx]));
1550 b = std::max(b, float(nextSource[sx])); 1561 b = std::max(b, double(nextSource[sx]));
1551 } 1562 }
1552 } 1563 }
1553 float yprop = sy - syi; 1564 double yprop = sy - syi;
1554 value = (a * (1.f - yprop) + b * yprop); 1565 value = (a * (1.f - yprop) + b * yprop);
1555 } else { 1566 } else {
1556 a = float(sourceLine[sx0i]); 1567 a = sourceLine[sx0i];
1557 b = float(nextSource[sx0i]); 1568 b = nextSource[sx0i];
1558 float yprop = sy - syi; 1569 double yprop = sy - syi;
1559 value = (a * (1.f - yprop) + b * yprop); 1570 value = (a * (1.f - yprop) + b * yprop);
1560 int oi = sx0i + 1; 1571 int oi = sx0i + 1;
1561 float xprop = sx0 - sx0i; 1572 double xprop = sx0 - sx0i;
1562 xprop -= 0.5; 1573 xprop -= 0.5;
1563 if (xprop < 0) { 1574 if (xprop < 0) {
1564 oi = sx0i - 1; 1575 oi = sx0i - 1;
1565 xprop = -xprop; 1576 xprop = -xprop;
1566 } 1577 }
1567 if (oi < 0 || oi >= sw) oi = sx0i; 1578 if (oi < 0 || oi >= sw) oi = sx0i;
1568 a = float(sourceLine[oi]); 1579 a = sourceLine[oi];
1569 b = float(nextSource[oi]); 1580 b = nextSource[oi];
1570 value = (value * (1.f - xprop) + 1581 value = (value * (1.f - xprop) +
1571 (a * (1.f - yprop) + b * yprop) * xprop); 1582 (a * (1.f - yprop) + b * yprop) * xprop);
1572 } 1583 }
1573 1584
1574 int vi = lrintf(value); 1585 int vi = int(lrint(value));
1575 if (vi > 255) vi = 255; 1586 if (vi > 255) vi = 255;
1576 if (vi < 0) vi = 0; 1587 if (vi < 0) vi = 0;
1577 targetLine[x] = uchar(vi); 1588 targetLine[x] = uchar(vi);
1578 } 1589 }
1579 } 1590 }
1580 } else { 1591 } else {
1581 1592
1582 float sy0 = getBinForY(v, 0); 1593 double sy0 = getBinForY(v, 0);
1583 1594
1584 int psy0i = -1, psy1i = -1; 1595 int psy0i = -1, psy1i = -1;
1585 1596
1586 for (int y = 0; y < h; ++y) { 1597 for (int y = 0; y < h; ++y) {
1587 1598
1588 float sy1 = sy0; 1599 double sy1 = sy0;
1589 sy0 = getBinForY(v, y + 1); 1600 sy0 = getBinForY(v, double(y + 1));
1590 1601
1591 int sy0i = int(sy0 + epsilon); 1602 int sy0i = int(sy0 + epsilon);
1592 int sy1i = int(sy1); 1603 int sy1i = int(sy1);
1593 1604
1594 uchar *targetLine = img.scanLine(y); 1605 uchar *targetLine = img.scanLine(y);
1611 1622
1612 uchar *sourceLine = source->scanLine(sy); 1623 uchar *sourceLine = source->scanLine(sy);
1613 1624
1614 for (int x = 0; x < w; ++x) { 1625 for (int x = 0; x < w; ++x) {
1615 1626
1616 float sx1 = sxa[x*2 + 1]; 1627 double sx1 = sxa[x*2 + 1];
1617 if (sx1 < 0) continue; 1628 if (sx1 < 0) continue;
1618 int sx1i = int(sx1); 1629 int sx1i = int(sx1);
1619 1630
1620 float sx0 = sxa[x*2]; 1631 double sx0 = sxa[x*2];
1621 if (sx0 < 0) continue; 1632 if (sx0 < 0) continue;
1622 int sx0i = int(sx0 + epsilon); 1633 int sx0i = int(sx0 + epsilon);
1623 if (sx0i >= sw) break; 1634 if (sx0i >= sw) break;
1624 1635
1625 uchar peak = 0; 1636 uchar peak = 0;
1642 1653
1643 paint.drawImage(x0, 0, img); 1654 paint.drawImage(x0, 0, img);
1644 } 1655 }
1645 1656
1646 bool 1657 bool
1647 Colour3DPlotLayer::snapToFeatureFrame(View *v, int &frame, 1658 Colour3DPlotLayer::snapToFeatureFrame(View *v, sv_frame_t &frame,
1648 int &resolution, 1659 int &resolution,
1649 SnapType snap) const 1660 SnapType snap) const
1650 { 1661 {
1651 if (!m_model) { 1662 if (!m_model) {
1652 return Layer::snapToFeatureFrame(v, frame, resolution, snap); 1663 return Layer::snapToFeatureFrame(v, frame, resolution, snap);
1653 } 1664 }
1654 1665
1655 resolution = m_model->getResolution(); 1666 resolution = m_model->getResolution();
1656 int left = (frame / resolution) * resolution; 1667 sv_frame_t left = (frame / resolution) * resolution;
1657 int right = left + resolution; 1668 sv_frame_t right = left + resolution;
1658 1669
1659 switch (snap) { 1670 switch (snap) {
1660 case SnapLeft: frame = left; break; 1671 case SnapLeft: frame = left; break;
1661 case SnapRight: frame = right; break; 1672 case SnapRight: frame = right; break;
1662 case SnapNearest: 1673 case SnapNearest: