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