Mercurial > hg > svgui
comparison layer/Colour3DPlotRenderer.cpp @ 1165:c036560a7205 3.0-integration
Introduce our own scaleDrawBufferImage (though I think we probably won't actually want to use this, so I expect to back it out again)
author | Chris Cannam |
---|---|
date | Thu, 17 Nov 2016 11:48:42 +0000 |
parents | f2f43802718b |
children | d89e04b0eff3 |
comparison
equal
deleted
inserted
replaced
1164:f2f43802718b | 1165:c036560a7205 |
---|---|
29 | 29 |
30 #include "view/ViewManager.h" // for main model sample rate. Pity | 30 #include "view/ViewManager.h" // for main model sample rate. Pity |
31 | 31 |
32 #include <vector> | 32 #include <vector> |
33 | 33 |
34 //#define DEBUG_COLOUR_PLOT_REPAINT 1 | 34 #define DEBUG_COLOUR_PLOT_REPAINT 1 |
35 | 35 |
36 using namespace std; | 36 using namespace std; |
37 | 37 |
38 Colour3DPlotRenderer::RenderResult | 38 Colour3DPlotRenderer::RenderResult |
39 Colour3DPlotRenderer::render(const LayerGeometryProvider *v, QPainter &paint, QRect rect) | 39 Colour3DPlotRenderer::render(const LayerGeometryProvider *v, QPainter &paint, QRect rect) |
576 for (int i = 0; in_range_for(m_magRanges, i); ++i) { | 576 for (int i = 0; in_range_for(m_magRanges, i); ++i) { |
577 m_magCache.sampleColumn(i, m_magRanges.at(i)); | 577 m_magCache.sampleColumn(i, m_magRanges.at(i)); |
578 } | 578 } |
579 } | 579 } |
580 | 580 |
581 QImage | |
582 Colour3DPlotRenderer::scaleDrawBufferImage(QImage image, | |
583 int targetWidth, | |
584 int targetHeight) const | |
585 { | |
586 int sourceWidth = image.width(); | |
587 int sourceHeight = image.height(); | |
588 | |
589 // We can only do this if we're making the image larger -- | |
590 // otherwise peaks may be lost. So this should be called only when | |
591 // rendering in DrawBufferBinResolution mode. Whenever the bin | |
592 // size is smaller than the pixel size, in either x or y axis, we | |
593 // should be using DrawBufferPixelResolution mode instead | |
594 | |
595 if (targetWidth < sourceWidth || targetHeight < sourceHeight) { | |
596 throw std::logic_error("Colour3DPlotRenderer::scaleDrawBufferImage: Can only use this function when making the image larger; should be rendering DrawBufferPixelResolution instead"); | |
597 } | |
598 | |
599 if (sourceWidth <= 0 || sourceHeight <= 0) { | |
600 throw std::logic_error("Colour3DPlotRenderer::scaleDrawBufferImage: Source image is empty"); | |
601 } | |
602 | |
603 if (targetWidth <= 0 || targetHeight <= 0) { | |
604 throw std::logic_error("Colour3DPlotRenderer::scaleDrawBufferImage: Target image is empty"); | |
605 } | |
606 | |
607 // This function exists because of some unpredictable behaviour | |
608 // from Qt when scaling images with FastTransformation mode. We | |
609 // continue to use Qt's scaler for SmoothTransformation but let's | |
610 // bring the non-interpolated version "in-house" so we know what | |
611 // it's really doing. | |
612 | |
613 if (m_params.interpolate) { | |
614 return image.scaled(targetWidth, targetHeight, | |
615 Qt::IgnoreAspectRatio, | |
616 Qt::SmoothTransformation); | |
617 } | |
618 | |
619 // Same format as the target cache | |
620 QImage target(targetWidth, targetHeight, QImage::Format_ARGB32_Premultiplied); | |
621 | |
622 for (int y = 0; y < targetHeight; ++y) { | |
623 | |
624 QRgb *targetLine = reinterpret_cast<QRgb *>(target.scanLine(y)); | |
625 | |
626 int sy = int((uint64_t(y) * sourceHeight) / targetHeight); | |
627 if (sy == sourceHeight) --sy; | |
628 | |
629 for (int x = 0; x < targetWidth; ++x) { | |
630 | |
631 int sx = int((uint64_t(x) * sourceWidth) / targetWidth); | |
632 if (sx == sourceWidth) --sx; | |
633 | |
634 targetLine[x] = image.pixel(sx, sy); | |
635 } | |
636 } | |
637 | |
638 return target; | |
639 } | |
640 | |
581 void | 641 void |
582 Colour3DPlotRenderer::renderToCacheBinResolution(const LayerGeometryProvider *v, | 642 Colour3DPlotRenderer::renderToCacheBinResolution(const LayerGeometryProvider *v, |
583 int x0, int repaintWidth) | 643 int x0, int repaintWidth) |
584 { | 644 { |
585 Profiler profiler("Colour3DPlotRenderer::renderToCacheBinResolution"); | 645 Profiler profiler("Colour3DPlotRenderer::renderToCacheBinResolution"); |
648 | 708 |
649 for (int x = 0; x < drawBufferWidth; ++x) { | 709 for (int x = 0; x < drawBufferWidth; ++x) { |
650 binforx[x] = int(leftBoundaryFrame / binResolution) + x; | 710 binforx[x] = int(leftBoundaryFrame / binResolution) + x; |
651 } | 711 } |
652 | 712 |
653 SVDEBUG << "[BIN] binResolution " << binResolution | 713 SVDEBUG << "[BIN] binResolution " << binResolution << endl; |
654 << endl; | |
655 | 714 |
656 for (int y = 0; y < h; ++y) { | 715 for (int y = 0; y < h; ++y) { |
657 binfory[y] = m_sources.verticalBinLayer->getBinForY(v, h - y - 1); | 716 binfory[y] = m_sources.verticalBinLayer->getBinForY(v, h - y - 1); |
658 } | 717 } |
659 | 718 |
673 #ifdef DEBUG_COLOUR_PLOT_REPAINT | 732 #ifdef DEBUG_COLOUR_PLOT_REPAINT |
674 cerr << "scaling draw buffer from width " << m_drawBuffer.width() | 733 cerr << "scaling draw buffer from width " << m_drawBuffer.width() |
675 << " to " << (scaledRight - scaledLeft) << " (nb drawBufferWidth = " | 734 << " to " << (scaledRight - scaledLeft) << " (nb drawBufferWidth = " |
676 << drawBufferWidth << ")" << endl; | 735 << drawBufferWidth << ")" << endl; |
677 #endif | 736 #endif |
678 | 737 |
679 QImage scaled = m_drawBuffer.scaled | 738 QImage scaled = scaleDrawBufferImage |
680 (scaledRight - scaledLeft, h, | 739 (m_drawBuffer, scaledRight - scaledLeft, h); |
681 Qt::IgnoreAspectRatio, (m_params.interpolate ? | |
682 Qt::SmoothTransformation : | |
683 Qt::FastTransformation)); | |
684 | 740 |
685 int scaledLeftCrop = v->getXForFrame(leftCropFrame); | 741 int scaledLeftCrop = v->getXForFrame(leftCropFrame); |
686 int scaledRightCrop = v->getXForFrame(rightCropFrame); | 742 int scaledRightCrop = v->getXForFrame(rightCropFrame); |
687 | 743 |
688 int targetLeft = scaledLeftCrop; | 744 int targetLeft = scaledLeftCrop; |
742 Profiler profiler("Colour3DPlotRenderer::renderDrawBuffer"); | 798 Profiler profiler("Colour3DPlotRenderer::renderDrawBuffer"); |
743 | 799 |
744 int divisor = 1; | 800 int divisor = 1; |
745 const DenseThreeDimensionalModel *sourceModel = m_sources.source; | 801 const DenseThreeDimensionalModel *sourceModel = m_sources.source; |
746 if (usePeakCache) { | 802 if (usePeakCache) { |
803 cerr << "usePeakCache is true, with divisor " << divisor << endl; | |
747 divisor = m_sources.peakCache->getColumnsPerPeak(); | 804 divisor = m_sources.peakCache->getColumnsPerPeak(); |
748 sourceModel = m_sources.peakCache; | 805 sourceModel = m_sources.peakCache; |
806 } else { | |
807 cerr << "usePeakCache is false" << endl; | |
749 } | 808 } |
750 | 809 |
751 int sh = sourceModel->getHeight(); | 810 int sh = sourceModel->getHeight(); |
752 | 811 |
753 int minbin = int(binfory[0] + 0.0001); | 812 int minbin = int(binfory[0] + 0.0001); |
799 if (sx0 < 0) sx0 = sx1 - 1; | 858 if (sx0 < 0) sx0 = sx1 - 1; |
800 if (sx0 < 0) continue; | 859 if (sx0 < 0) continue; |
801 if (sx1 <= sx0) sx1 = sx0 + 1; | 860 if (sx1 <= sx0) sx1 = sx0 + 1; |
802 | 861 |
803 #ifdef DEBUG_COLOUR_PLOT_REPAINT | 862 #ifdef DEBUG_COLOUR_PLOT_REPAINT |
804 cerr << "x = " << x << ", binforx[x] = " << binforx[x] << ", sx range " << sx0 << " -> " << sx1 << endl; | 863 // cerr << "x = " << x << ", binforx[x] = " << binforx[x] << ", sx range " << sx0 << " -> " << sx1 << endl; |
805 #endif | 864 #endif |
806 | 865 |
807 vector<float> pixelPeakColumn; | 866 vector<float> pixelPeakColumn; |
808 MagnitudeRange magRange; | 867 MagnitudeRange magRange; |
809 | 868 |