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: |
