From f3bfdad19b830b13318a96c2ed64d28cda648d85 Mon Sep 17 00:00:00 2001 From: Alex <4lex49@zoho.com> Date: Thu, 29 Mar 2018 16:10:50 +0300 Subject: [PATCH 01/11] ~ Code refactoring and fixes. --- ConsoleBatch.cpp | 4 ++-- DebugImageView.cpp | 5 ++--- LoadFileTask.cpp | 2 +- MainWindow.cpp | 4 ++-- SettingsDialog.cpp | 12 +++++------- SettingsDialog.h | 2 -- filters/deskew/Filter.cpp | 2 +- filters/deskew/Task.cpp | 4 ++-- filters/fix_orientation/Task.cpp | 2 +- filters/output/DespeckleView.cpp | 8 ++++---- filters/output/FillZoneEditor.cpp | 2 +- filters/output/PictureZoneEditor.cpp | 2 +- filters/output/Task.cpp | 8 ++++---- filters/page_layout/Filter.cpp | 6 +++--- filters/page_layout/Task.cpp | 6 +++--- filters/page_split/Filter.cpp | 4 ++-- filters/page_split/Task.cpp | 4 ++-- filters/select_content/Filter.cpp | 6 +++--- filters/select_content/Task.cpp | 6 +++--- zones/SplineVertex.cpp | 4 ++-- zones/ZoneDefaultInteraction.cpp | 4 ++-- 21 files changed, 46 insertions(+), 51 deletions(-) diff --git a/ConsoleBatch.cpp b/ConsoleBatch.cpp index 24f2cf6b2..65876e741 100644 --- a/ConsoleBatch.cpp +++ b/ConsoleBatch.cpp @@ -139,8 +139,8 @@ BackgroundTaskPtr ConsoleBatch::createCompositeTask(const PageInfo& page, const } assert(fix_orientation_task); - return BackgroundTaskPtr( - new LoadFileTask(BackgroundTask::BATCH, page, m_ptrThumbnailCache, m_ptrPages, fix_orientation_task)); + return make_intrusive(BackgroundTask::BATCH, page, m_ptrThumbnailCache, m_ptrPages, + fix_orientation_task); } // ConsoleBatch::createCompositeTask // process the image vector **images** and save output to **output_dir** diff --git a/DebugImageView.cpp b/DebugImageView.cpp index 67f202a64..8b9138467 100644 --- a/DebugImageView.cpp +++ b/DebugImageView.cpp @@ -52,7 +52,7 @@ class DebugImageView::ImageLoader : public AbstractCommand0(m_ptrOwner, image); } private: @@ -74,8 +74,7 @@ DebugImageView::DebugImageView(AutoRemovingFile file, void DebugImageView::setLive(const bool live) { if (live && !m_isLive) { - ImageViewBase::backgroundExecutor().enqueueTask( - BackgroundExecutor::TaskPtr(new ImageLoader(this, m_file.get()))); + ImageViewBase::backgroundExecutor().enqueueTask(make_intrusive(this, m_file.get())); } else if (!live && m_isLive) { if (QWidget* wgt = currentWidget()) { if (wgt != m_pPlaceholderWidget) { diff --git a/LoadFileTask.cpp b/LoadFileTask.cpp index 380d22b8d..88f7c119b 100644 --- a/LoadFileTask.cpp +++ b/LoadFileTask.cpp @@ -73,7 +73,7 @@ FilterResultPtr LoadFileTask::operator()() { throwIfCancelled(); if (image.isNull()) { - return FilterResultPtr(new ErrorResult(m_imageId.filePath())); + return make_intrusive(m_imageId.filePath()); } else { updateImageSizeIfChanged(image); overrideDpi(image); diff --git a/MainWindow.cpp b/MainWindow.cpp index 70d290447..0befae8e2 100644 --- a/MainWindow.cpp +++ b/MainWindow.cpp @@ -1923,8 +1923,8 @@ BackgroundTaskPtr MainWindow::createCompositeTask(const PageInfo& page, } assert(fix_orientation_task); - return BackgroundTaskPtr(new LoadFileTask(batch ? BackgroundTask::BATCH : BackgroundTask::INTERACTIVE, page, - m_ptrThumbnailCache, m_ptrPages, fix_orientation_task)); + return make_intrusive(batch ? BackgroundTask::BATCH : BackgroundTask::INTERACTIVE, page, + m_ptrThumbnailCache, m_ptrPages, fix_orientation_task); } // MainWindow::createCompositeTask intrusive_ptr MainWindow::createCompositeCacheDrivenTask(const int last_filter_idx) { diff --git a/SettingsDialog.cpp b/SettingsDialog.cpp index c5fd157dd..53626b9fc 100644 --- a/SettingsDialog.cpp +++ b/SettingsDialog.cpp @@ -88,7 +88,10 @@ SettingsDialog::SettingsDialog(QWidget* parent) : QDialog(parent) { ui.autoSaveProjectCB->setChecked(settings.value("settings/auto_save_project").toBool()); ui.highlightDeviationCB->setChecked(settings.value("settings/highlight_deviation", true).toBool()); - connect(ui.colorSchemeBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onColorSchemeChanged(int))); + connect(ui.colorSchemeBox, static_cast(&QComboBox::currentIndexChanged), [this](int) { + QMessageBox::information(this, tr("Information"), + tr("ScanTailor need to be restarted to apply the color scheme changes.")); + }); } SettingsDialog::~SettingsDialog() = default; @@ -116,9 +119,4 @@ void SettingsDialog::commitChanges() { settings.setValue("settings/marginsDeviationThreshold", ui.marginsDeviationThresholdSB->value()); emit settingsChanged(); -} - -void SettingsDialog::onColorSchemeChanged(int idx) { - QMessageBox::information(this, tr("Information"), - tr("ScanTailor need to be restarted to apply the color scheme changes.")); -} +} \ No newline at end of file diff --git a/SettingsDialog.h b/SettingsDialog.h index c26d4f859..730a8e136 100644 --- a/SettingsDialog.h +++ b/SettingsDialog.h @@ -38,8 +38,6 @@ private slots: void commitChanges(); - void onColorSchemeChanged(int idx); - private: Ui::SettingsDialog ui; }; diff --git a/filters/deskew/Filter.cpp b/filters/deskew/Filter.cpp index 111e28eb5..f281ed10f 100644 --- a/filters/deskew/Filter.cpp +++ b/filters/deskew/Filter.cpp @@ -44,7 +44,7 @@ Filter::Filter(const PageSelectionAccessor& page_selection_accessor) typedef PageOrderOption::ProviderPtr ProviderPtr; const ProviderPtr default_order; - const ProviderPtr order_by_deviation(new OrderByDeviationProvider(m_ptrSettings->deviationProvider())); + const auto order_by_deviation = make_intrusive(m_ptrSettings->deviationProvider()); m_pageOrderOptions.emplace_back(tr("Natural order"), default_order); m_pageOrderOptions.emplace_back(tr("Order by decreasing deviation"), order_by_deviation); } diff --git a/filters/deskew/Task.cpp b/filters/deskew/Task.cpp index 8eb686421..fd017f438 100644 --- a/filters/deskew/Task.cpp +++ b/filters/deskew/Task.cpp @@ -166,8 +166,8 @@ FilterResultPtr Task::process(const TaskStatus& status, FilterData data) { if (m_ptrNextTask) { return m_ptrNextTask->process(status, FilterData(data, new_xform)); } else { - return FilterResultPtr(new UiUpdater(m_ptrFilter, std::move(m_ptrDbg), data.origImage(), m_pageId, new_xform, - ui_data, m_batchProcessing)); + return make_intrusive(m_ptrFilter, std::move(m_ptrDbg), data.origImage(), m_pageId, new_xform, + ui_data, m_batchProcessing); } } // Task::process diff --git a/filters/fix_orientation/Task.cpp b/filters/fix_orientation/Task.cpp index 698c263f1..cda40ca86 100644 --- a/filters/fix_orientation/Task.cpp +++ b/filters/fix_orientation/Task.cpp @@ -86,7 +86,7 @@ FilterResultPtr Task::process(const TaskStatus& status, FilterData data) { if (m_ptrNextTask) { return m_ptrNextTask->process(status, FilterData(data, xform)); } else { - return FilterResultPtr(new UiUpdater(m_ptrFilter, data.origImage(), m_imageId, xform, m_batchProcessing)); + return make_intrusive(m_ptrFilter, data.origImage(), m_imageId, xform, m_batchProcessing); } } diff --git a/filters/output/DespeckleView.cpp b/filters/output/DespeckleView.cpp index c43c564cb..4310e371a 100644 --- a/filters/output/DespeckleView.cpp +++ b/filters/output/DespeckleView.cpp @@ -164,8 +164,8 @@ void DespeckleView::initiateDespeckling(const AnimationAction anim_action) { // Note that we are getting rid of m_initialSpeckles, // as we wouldn't need it any more. - const BackgroundExecutor::TaskPtr task( - new DespeckleTask(this, m_despeckleState, m_ptrCancelHandle, m_despeckleLevel, m_debug)); + const auto task + = make_intrusive(this, m_despeckleState, m_ptrCancelHandle, m_despeckleLevel, m_debug); ImageViewBase::backgroundExecutor().enqueueTask(task); } @@ -241,8 +241,8 @@ BackgroundExecutor::TaskResultPtr DespeckleView::DespeckleTask::operator()() { m_ptrCancelHandle->throwIfCancelled(); - return BackgroundExecutor::TaskResultPtr(new DespeckleResult(m_ptrOwner, m_ptrCancelHandle, m_despeckleState, - visualization, std::move(m_ptrDbg))); + return make_intrusive(m_ptrOwner, m_ptrCancelHandle, m_despeckleState, visualization, + std::move(m_ptrDbg)); } catch (const TaskCancelException&) { return nullptr; } diff --git a/filters/output/FillZoneEditor.cpp b/filters/output/FillZoneEditor.cpp index 97edea33d..45de5ef2d 100644 --- a/filters/output/FillZoneEditor.cpp +++ b/filters/output/FillZoneEditor.cpp @@ -83,7 +83,7 @@ FillZoneEditor::FillZoneEditor(const QImage& image, rootInteractionHandler().makeLastFollower(m_zoomHandler); for (const Zone& zone : m_ptrSettings->fillZonesForPage(page_id)) { - EditableSpline::Ptr spline(new EditableSpline(zone.spline().transformed(m_origToImage))); + auto spline = make_intrusive(zone.spline().transformed(m_origToImage)); m_zones.addZone(spline, zone.properties()); } } diff --git a/filters/output/PictureZoneEditor.cpp b/filters/output/PictureZoneEditor.cpp index c7b1f4df2..630c31d2f 100644 --- a/filters/output/PictureZoneEditor.cpp +++ b/filters/output/PictureZoneEditor.cpp @@ -133,7 +133,7 @@ PictureZoneEditor::PictureZoneEditor(const QImage& image, m_pictureMaskRebuildTimer.setInterval(150); for (const Zone& zone : m_ptrSettings->pictureZonesForPage(page_id)) { - EditableSpline::Ptr spline(new EditableSpline(zone.spline())); + auto spline = make_intrusive(zone.spline()); m_zones.addZone(spline, zone.properties()); } } diff --git a/filters/output/Task.cpp b/filters/output/Task.cpp index 03ba5fd63..6fc8f3dfc 100644 --- a/filters/output/Task.cpp +++ b/filters/output/Task.cpp @@ -447,10 +447,10 @@ FilterResultPtr Task::process(const TaskStatus& status, const FilterData& data, } if (CommandLine::get().isGui()) { - return FilterResultPtr(new UiUpdater(m_ptrFilter, m_ptrSettings, std::move(m_ptrDbg), params, new_xform, - generator.getPostTransform(), generator.outputContentRect(), m_pageId, - data.origImage(), out_img, automask_img, despeckle_state, - despeckle_visualization, m_batchProcessing, m_debug)); + return make_intrusive(m_ptrFilter, m_ptrSettings, std::move(m_ptrDbg), params, new_xform, + generator.getPostTransform(), generator.outputContentRect(), m_pageId, + data.origImage(), out_img, automask_img, despeckle_state, + despeckle_visualization, m_batchProcessing, m_debug); } else { return nullptr; } diff --git a/filters/page_layout/Filter.cpp b/filters/page_layout/Filter.cpp index b84d8ad0b..4e8c9c400 100644 --- a/filters/page_layout/Filter.cpp +++ b/filters/page_layout/Filter.cpp @@ -52,9 +52,9 @@ Filter::Filter(intrusive_ptr pages, const PageSelectionAccessor& p typedef PageOrderOption::ProviderPtr ProviderPtr; const ProviderPtr default_order; - const ProviderPtr order_by_width(new OrderByWidthProvider(m_ptrSettings)); - const ProviderPtr order_by_height(new OrderByHeightProvider(m_ptrSettings)); - const ProviderPtr order_by_deviation(new OrderByDeviationProvider(m_ptrSettings->deviationProvider())); + const auto order_by_width = make_intrusive(m_ptrSettings); + const auto order_by_height = make_intrusive(m_ptrSettings); + const auto order_by_deviation = make_intrusive(m_ptrSettings->deviationProvider()); m_pageOrderOptions.emplace_back(tr("Natural order"), default_order); m_pageOrderOptions.emplace_back(tr("Order by increasing width"), order_by_width); m_pageOrderOptions.emplace_back(tr("Order by increasing height"), order_by_height); diff --git a/filters/page_layout/Task.cpp b/filters/page_layout/Task.cpp index ca4a765f1..793ae8110 100644 --- a/filters/page_layout/Task.cpp +++ b/filters/page_layout/Task.cpp @@ -108,9 +108,9 @@ FilterResultPtr Task::process(const TaskStatus& status, return m_ptrNextTask->process(status, FilterData(data, new_xform), content_rect_phys); } else { - return FilterResultPtr(new UiUpdater(m_ptrFilter, m_ptrSettings, m_pageId, data.origImage(), data.xform(), - adapted_content_rect, agg_hard_size_before != agg_hard_size_after, - m_batchProcessing)); + return make_intrusive(m_ptrFilter, m_ptrSettings, m_pageId, data.origImage(), data.xform(), + adapted_content_rect, agg_hard_size_before != agg_hard_size_after, + m_batchProcessing); } } // Task::process diff --git a/filters/page_split/Filter.cpp b/filters/page_split/Filter.cpp index e26722656..bf49604ef 100644 --- a/filters/page_split/Filter.cpp +++ b/filters/page_split/Filter.cpp @@ -45,9 +45,9 @@ Filter::Filter(intrusive_ptr page_sequence, const PageSelectionAcc typedef PageOrderOption::ProviderPtr ProviderPtr; const ProviderPtr default_order; - const ProviderPtr order_by_splitline(new OrderBySplitTypeProvider(m_ptrSettings)); + const auto order_by_split_type = make_intrusive(m_ptrSettings); m_pageOrderOptions.emplace_back(tr("Natural order"), default_order); - m_pageOrderOptions.emplace_back(tr("Order by split type"), order_by_splitline); + m_pageOrderOptions.emplace_back(tr("Order by split type"), order_by_split_type); } Filter::~Filter() = default; diff --git a/filters/page_split/Task.cpp b/filters/page_split/Task.cpp index e24e04a54..7760b7075 100644 --- a/filters/page_split/Task.cpp +++ b/filters/page_split/Task.cpp @@ -204,8 +204,8 @@ FilterResultPtr Task::process(const TaskStatus& status, const FilterData& data) return m_ptrNextTask->process(status, FilterData(data, new_xform)); } - return FilterResultPtr(new UiUpdater(m_ptrFilter, m_ptrPages, std::move(m_ptrDbg), data.origImage(), m_pageInfo, - data.xform(), ui_data, m_batchProcessing)); + return make_intrusive(m_ptrFilter, m_ptrPages, std::move(m_ptrDbg), data.origImage(), m_pageInfo, + data.xform(), ui_data, m_batchProcessing); } // Task::process /*============================ Task::UiUpdater =========================*/ diff --git a/filters/select_content/Filter.cpp b/filters/select_content/Filter.cpp index daeee0b0d..7f0bee847 100644 --- a/filters/select_content/Filter.cpp +++ b/filters/select_content/Filter.cpp @@ -46,9 +46,9 @@ Filter::Filter(const PageSelectionAccessor& page_selection_accessor) typedef PageOrderOption::ProviderPtr ProviderPtr; const ProviderPtr default_order; - const ProviderPtr order_by_width(new OrderByWidthProvider(m_ptrSettings)); - const ProviderPtr order_by_height(new OrderByHeightProvider(m_ptrSettings)); - const ProviderPtr order_by_deviation(new OrderByDeviationProvider(m_ptrSettings->deviationProvider())); + const auto order_by_width = make_intrusive(m_ptrSettings); + const auto order_by_height = make_intrusive(m_ptrSettings); + const auto order_by_deviation = make_intrusive(m_ptrSettings->deviationProvider()); m_pageOrderOptions.emplace_back(tr("Natural order"), default_order); m_pageOrderOptions.emplace_back(tr("Order by increasing width"), order_by_width); m_pageOrderOptions.emplace_back(tr("Order by increasing height"), order_by_height); diff --git a/filters/select_content/Task.cpp b/filters/select_content/Task.cpp index 6eafdaf95..baccd25bb 100644 --- a/filters/select_content/Task.cpp +++ b/filters/select_content/Task.cpp @@ -186,9 +186,9 @@ FilterResultPtr Task::process(const TaskStatus& status, const FilterData& data) return m_ptrNextTask->process(status, FilterData(data, data.xform()), ui_data.pageRect(), ui_data.contentRect()); } else { - return FilterResultPtr(new UiUpdater(m_ptrFilter, m_pageId, std::move(m_ptrDbg), data.origImage(), data.xform(), - data.isBlackOnWhite() ? data.grayImage() : data.grayImage().inverted(), - ui_data, m_batchProcessing)); + return make_intrusive(m_ptrFilter, m_pageId, std::move(m_ptrDbg), data.origImage(), data.xform(), + data.isBlackOnWhite() ? data.grayImage() : data.grayImage().inverted(), + ui_data, m_batchProcessing); } } // Task::process diff --git a/zones/SplineVertex.cpp b/zones/SplineVertex.cpp index 7e7a8def0..5059d1fb8 100644 --- a/zones/SplineVertex.cpp +++ b/zones/SplineVertex.cpp @@ -60,7 +60,7 @@ SplineVertex::Ptr SplineVertex::next(const Loop loop) { } SplineVertex::Ptr SplineVertex::insertBefore(const QPointF& pt) { - SplineVertex::Ptr new_vertex(new RealSplineVertex(pt, m_pPrev, this)); + auto new_vertex = make_intrusive(pt, m_pPrev, this); m_pPrev->m_ptrNext = new_vertex; m_pPrev = new_vertex.get(); @@ -68,7 +68,7 @@ SplineVertex::Ptr SplineVertex::insertBefore(const QPointF& pt) { } SplineVertex::Ptr SplineVertex::insertAfter(const QPointF& pt) { - SplineVertex::Ptr new_vertex(new RealSplineVertex(pt, this, m_ptrNext.get())); + auto new_vertex = make_intrusive(pt, this, m_ptrNext.get()); m_ptrNext->m_pPrev = new_vertex.get(); m_ptrNext = new_vertex; diff --git a/zones/ZoneDefaultInteraction.cpp b/zones/ZoneDefaultInteraction.cpp index 5096e2d9f..557067e1e 100644 --- a/zones/ZoneDefaultInteraction.cpp +++ b/zones/ZoneDefaultInteraction.cpp @@ -205,7 +205,7 @@ void ZoneDefaultInteraction::onMousePressEvent(QMouseEvent* event, InteractionSt delete this; event->accept(); } else if (interaction.proximityLeader(m_zoneAreaDragCopyProximity)) { - EditableSpline::Ptr new_spline(new EditableSpline(SerializableSpline(*m_ptrUnderCursorSpline))); + auto new_spline = make_intrusive(SerializableSpline(*m_ptrUnderCursorSpline)); m_rContext.zones().addZone(new_spline, *m_rContext.zones().propertiesFor(m_ptrUnderCursorSpline)); makePeerPreceeder(*m_rContext.createZoneDragInteraction(interaction, new_spline)); delete this; @@ -238,7 +238,7 @@ void ZoneDefaultInteraction::onMouseReleaseEvent(QMouseEvent* event, Interaction serializable_spline = serializable_spline.transformed(QTransform().translate(shift.x(), shift.y())); - EditableSpline::Ptr new_spline(new EditableSpline(serializable_spline)); + auto new_spline = make_intrusive(serializable_spline); m_rContext.zones().addZone(new_spline, *(*latest_zone).properties()); m_rContext.zones().commit(); } From 53cd5efd9029e86297644389c6a0ac4e52f3b48e Mon Sep 17 00:00:00 2001 From: Alex <4lex49@zoho.com> Date: Sat, 31 Mar 2018 04:05:01 +0300 Subject: [PATCH 02/11] ~ Each math function call has been wrapped in std namespace to avoid ambiguous calls. --- BubbleAnimation.cpp | 4 ++-- Despeckle.cpp | 4 ++-- EstimateBackground.cpp | 2 +- ImageViewBase.cpp | 18 +++++++------- MainWindow.cpp | 2 +- StatusBarPanel.cpp | 24 +++++++++---------- TiffWriter.cpp | 6 ++--- dewarping/CylindricalSurfaceDewarper.cpp | 6 ++--- dewarping/DetectVertContentBounds.cpp | 10 ++++---- dewarping/DistortionModel.cpp | 2 +- dewarping/DistortionModelBuilder.cpp | 8 +++---- dewarping/RasterDewarper.cpp | 6 ++--- dewarping/TextLineRefiner.cpp | 18 +++++++------- dewarping/TextLineTracer.cpp | 14 +++++------ dewarping/TopBottomEdgeTracer.cpp | 26 ++++++++++----------- dewarping/TowardsLineTracer.cpp | 2 +- filters/deskew/ImageView.cpp | 6 ++--- filters/output/OutputImageParams.cpp | 2 +- filters/output/PictureZoneEditor.cpp | 2 +- filters/output/TabbedImageView.cpp | 8 +++---- filters/page_split/PageLayoutEstimator.cpp | 24 +++++++++---------- filters/page_split/VertLineFinder.cpp | 2 +- filters/select_content/ContentBoxFinder.cpp | 10 ++++---- filters/select_content/PageFinder.cpp | 8 +++---- foundation/GridLineTraverser.cpp | 2 +- foundation/Proximity.h | 2 +- foundation/ValueConv.h | 2 +- imageproc/Binarize.cpp | 4 ++-- imageproc/FindPeaksGeneric.h | 2 +- imageproc/GaussBlur.cpp | 2 +- imageproc/HoughLineDetector.cpp | 4 ++-- imageproc/Morphology.cpp | 2 +- imageproc/PolygonUtils.cpp | 8 +++---- imageproc/PolynomialLine.h | 2 +- imageproc/RastLineFinder.cpp | 6 ++--- imageproc/ReduceThreshold.h | 4 ++-- imageproc/SavGolKernel.cpp | 12 +++++----- imageproc/Shear.cpp | 20 ++++++++-------- imageproc/SkewFinder.cpp | 2 +- imageproc/tests/TestPolygonRasterizer.cpp | 4 ++-- imageproc/tests/TestScale.cpp | 2 +- imageproc/tests/TestSkewFinder.cpp | 2 +- interaction/DragWatcher.cpp | 2 +- interaction/InteractiveXSpline.cpp | 4 ++-- interaction/ZoomHandler.cpp | 2 +- math/ArcLengthMapper.cpp | 2 +- math/LineIntersectionScalar.cpp | 4 ++-- math/LinearSolver.h | 12 +++++----- math/PolylineIntersector.cpp | 2 +- math/ToLineProjector.cpp | 4 ++-- math/XSpline.cpp | 13 ++++++----- math/spfit/FrenetFrame.cpp | 2 +- math/spfit/LinearForceBalancer.cpp | 2 +- math/spfit/SqDistApproximant.cpp | 12 +++++----- math/spfit/tests/TestSqDistApproximant.cpp | 4 ++-- zones/ZoneVertexDragInteraction.cpp | 15 +++++++----- 56 files changed, 190 insertions(+), 186 deletions(-) diff --git a/BubbleAnimation.cpp b/BubbleAnimation.cpp index be0abfaac..2c3f7c510 100644 --- a/BubbleAnimation.cpp +++ b/BubbleAnimation.cpp @@ -64,8 +64,8 @@ bool BubbleAnimation::nextFrame(const QColor& head_color, for (int i = 0; i < m_numBubbles; ++i) { const double angle = -0.5 * PI + 2.0 * PI * (m_curFrame - i) / m_numBubbles; - const double s = sin(angle); - const double c = cos(angle); + const double s = std::sin(angle); + const double c = std::cos(angle); const QPointF vec(c * reduced_radius, s * reduced_radius); QRectF r(0.0, 0.0, 2.0 * bubble_radius, 2.0 * bubble_radius); r.moveCenter(center + vec); diff --git a/Despeckle.cpp b/Despeckle.cpp index 7b86012cd..e5506a6b6 100644 --- a/Despeckle.cpp +++ b/Despeckle.cpp @@ -48,9 +48,9 @@ namespace { * We want horizontal proximity to have greater weight, so we * multiply the vertical component distances by VERTICAL_SCALE, * so that the distance is not:\n - * sqrt(dx^2 + dy^2)\n + * std::sqrt(dx^2 + dy^2)\n * but:\n - * sqrt(dx^2 + (VERTICAL_SCALE*dy)^2)\n + * std::sqrt(dx^2 + (VERTICAL_SCALE*dy)^2)\n * Keep in mind that we actually operate on squared distances, * so we don't need to take that square root. */ diff --git a/EstimateBackground.cpp b/EstimateBackground.cpp index 68debf1d5..47d3b8d26 100644 --- a/EstimateBackground.cpp +++ b/EstimateBackground.cpp @@ -42,7 +42,7 @@ using namespace imageproc; struct AbsoluteDifference { static uint8_t transform(uint8_t src, uint8_t dst) { - return static_cast(abs(int(src) - int(dst))); + return static_cast(std::abs(int(src) - int(dst))); } }; diff --git a/ImageViewBase.cpp b/ImageViewBase.cpp index f17661cba..e16628d94 100644 --- a/ImageViewBase.cpp +++ b/ImageViewBase.cpp @@ -321,7 +321,7 @@ void ImageViewBase::moveTowardsIdealPosition(const double pixel_length) { } QPointF vec(ideal_widget_fp - m_widgetFocalPoint); - const double max_length = sqrt(vec.x() * vec.x() + vec.y() * vec.y()); + const double max_length = std::sqrt(vec.x() * vec.x() + vec.y() * vec.y()); if (pixel_length >= max_length) { m_widgetFocalPoint = ideal_widget_fp; } else { @@ -626,8 +626,8 @@ void ImageViewBase::updateScrollBars() { ymin = std::min(viewport_center.y(), viewport.bottom() - 0.5 * picture.height()); } - const auto xrange = (int) ceil(xmax - xmin); - const auto yrange = (int) ceil(ymax - ymin); + const auto xrange = (int) std::ceil(xmax - xmin); + const auto yrange = (int) std::ceil(ymax - ymin); const int xfirst = 0; const int xlast = xrange - 1; const int yfirst = 0; @@ -788,12 +788,12 @@ QPointF ImageViewBase::getIdealWidgetFocalPoint(const FocalPointMode mode) const } else if ((left_margin < 0.0) && (right_margin > 0.0)) { // Move image to the right so that either left_margin or // right_margin becomes zero, whichever requires less movement. - const double movement = std::min(fabs(left_margin), fabs(right_margin)); + const double movement = std::min(std::fabs(left_margin), std::fabs(right_margin)); widget_focal_point.rx() += movement; } else if ((right_margin < 0.0) && (left_margin > 0.0)) { // Move image to the left so that either left_margin or // right_margin becomes zero, whichever requires less movement. - const double movement = std::min(fabs(left_margin), fabs(right_margin)); + const double movement = std::min(std::fabs(left_margin), std::fabs(right_margin)); widget_focal_point.rx() -= movement; } @@ -805,12 +805,12 @@ QPointF ImageViewBase::getIdealWidgetFocalPoint(const FocalPointMode mode) const } else if ((top_margin < 0.0) && (bottom_margin > 0.0)) { // Move image down so that either top_margin or bottom_margin // becomes zero, whichever requires less movement. - const double movement = std::min(fabs(top_margin), fabs(bottom_margin)); + const double movement = std::min(std::fabs(top_margin), std::fabs(bottom_margin)); widget_focal_point.ry() += movement; } else if ((bottom_margin < 0.0) && (top_margin > 0.0)) { // Move image up so that either top_margin or bottom_margin // becomes zero, whichever requires less movement. - const double movement = std::min(fabs(top_margin), fabs(bottom_margin)); + const double movement = std::min(std::fabs(top_margin), std::fabs(bottom_margin)); widget_focal_point.ry() -= movement; } @@ -859,7 +859,7 @@ void ImageViewBase::adjustAndSetNewWidgetFP(const QPointF proposed_widget_fp, co if (towards_ideal.x() * towards_proposed.x() < 0.0) { // Wrong direction - no movement at all. movement.setX(0.0); - } else if (fabs(towards_proposed.x()) > fabs(towards_ideal.x())) { + } else if (std::fabs(towards_proposed.x()) > std::fabs(towards_ideal.x())) { // Too much movement - limit it. movement.setX(towards_ideal.x()); } @@ -867,7 +867,7 @@ void ImageViewBase::adjustAndSetNewWidgetFP(const QPointF proposed_widget_fp, co if (towards_ideal.y() * towards_proposed.y() < 0.0) { // Wrong direction - no movement at all. movement.setY(0.0); - } else if (fabs(towards_proposed.y()) > fabs(towards_ideal.y())) { + } else if (std::fabs(towards_proposed.y()) > std::fabs(towards_ideal.y())) { // Too much movement - limit it. movement.setY(towards_ideal.y()); } diff --git a/MainWindow.cpp b/MainWindow.cpp index 0befae8e2..17e58e14a 100644 --- a/MainWindow.cpp +++ b/MainWindow.cpp @@ -448,7 +448,7 @@ void MainWindow::setupThumbView() { inner_width -= thumbView->frameWidth() * 2; } const int delta_x = thumbView->size().width() - inner_width; - thumbView->setMinimumWidth((int) ceil(m_maxLogicalThumbSize.width() + delta_x)); + thumbView->setMinimumWidth((int) std::ceil(m_maxLogicalThumbSize.width() + delta_x)); m_ptrThumbSequence->attachView(thumbView); diff --git a/StatusBarPanel.cpp b/StatusBarPanel.cpp index f7d0aaf09..def6b152d 100644 --- a/StatusBarPanel.cpp +++ b/StatusBarPanel.cpp @@ -77,12 +77,12 @@ void StatusBarPanel::mousePosChanged() { switch (UnitsProvider::getInstance()->getUnits()) { case PIXELS: case MILLIMETRES: - x = ceil(x); - y = ceil(y); + x = std::ceil(x); + y = std::ceil(y); break; default: - x = ceil(x * 10) / 10; - y = ceil(y * 10) / 10; + x = std::ceil(x * 10) / 10; + y = std::ceil(y * 10) / 10; break; } @@ -103,20 +103,20 @@ void StatusBarPanel::physSizeChanged() { const Units units = UnitsProvider::getInstance()->getUnits(); switch (units) { case PIXELS: - width = round(width); - height = round(height); + width = std::round(width); + height = std::round(height); break; case MILLIMETRES: - width = round(width); - height = round(height); + width = std::round(width); + height = std::round(height); break; case CENTIMETRES: - width = round(width * 10) / 10; - height = round(height * 10) / 10; + width = std::round(width * 10) / 10; + height = std::round(height * 10) / 10; break; case INCHES: - width = round(width * 10) / 10; - height = round(height * 10) / 10; + width = std::round(width * 10) / 10; + height = std::round(height * 10) / 10; break; } diff --git a/TiffWriter.cpp b/TiffWriter.cpp index e96e573b8..1408d1ec7 100644 --- a/TiffWriter.cpp +++ b/TiffWriter.cpp @@ -199,9 +199,9 @@ void TiffWriter::setDpm(const TiffHandle& tif, const Dpm& dpm) { // write it as DPI rather than dots per cm. const double xdpi = dpm.horizontal() * DPM2DPI; const double ydpi = dpm.vertical() * DPM2DPI; - const double rounded_xdpi = floor(xdpi + 0.5); - const double rounded_ydpi = floor(ydpi + 0.5); - if ((fabs(xdpi - rounded_xdpi) < 0.02) && (fabs(ydpi - rounded_ydpi) < 0.02)) { + const double rounded_xdpi = std::floor(xdpi + 0.5); + const double rounded_ydpi = std::floor(ydpi + 0.5); + if ((std::fabs(xdpi - rounded_xdpi) < 0.02) && (std::fabs(ydpi - rounded_ydpi) < 0.02)) { xres = (float) rounded_xdpi; yres = (float) rounded_ydpi; unit = RESUNIT_INCH; diff --git a/dewarping/CylindricalSurfaceDewarper.cpp b/dewarping/CylindricalSurfaceDewarper.cpp index 07e01d13c..2b4eb903b 100644 --- a/dewarping/CylindricalSurfaceDewarper.cpp +++ b/dewarping/CylindricalSurfaceDewarper.cpp @@ -107,7 +107,7 @@ CylindricalSurfaceDewarper::Generatrix CylindricalSurfaceDewarper::mapGeneratrix boost::array, 3> pairs; pairs[0] = std::make_pair(0.0, img_directrix1_proj); pairs[1] = std::make_pair(1.0, img_directrix2_proj); - if ((fabs(m_plnStraightLineY) < 0.05) || (fabs(m_plnStraightLineY - 1.0) < 0.05)) { + if ((std::fabs(m_plnStraightLineY) < 0.05) || (std::fabs(m_plnStraightLineY - 1.0) < 0.05)) { pairs[2] = std::make_pair(0.5, 0.5 * (img_directrix1_proj + img_directrix2_proj)); } else { pairs[2] = std::make_pair(m_plnStraightLineY, img_straight_line_proj); @@ -139,7 +139,7 @@ QPointF CylindricalSurfaceDewarper::mapToDewarpedSpace(const QPointF& img_pt) co boost::array, 3> pairs; pairs[0] = std::make_pair(img_directrix1_proj, 0.0); pairs[1] = std::make_pair(img_directrix2_proj, 1.0); - if ((fabs(m_plnStraightLineY) < 0.05) || (fabs(m_plnStraightLineY - 1.0) < 0.05)) { + if ((std::fabs(m_plnStraightLineY) < 0.05) || (std::fabs(m_plnStraightLineY - 1.0) < 0.05)) { pairs[2] = std::make_pair(0.5 * (img_directrix1_proj + img_directrix2_proj), 0.5); } else { pairs[2] = std::make_pair(img_straight_line_proj, m_plnStraightLineY); @@ -193,7 +193,7 @@ double CylindricalSurfaceDewarper::calcPlnStraightLineY(const std::vector(abs(line.p1().x() - vert_line_x), abs(line.p2().x() - vert_line_x)); + return (bool) std::min(std::abs(line.p1().x() - vert_line_x), std::abs(line.p2().x() - vert_line_x)); } Segment(const QLine& line, const Vec2d& vec, int dist) : line(line), unitVec(vec), vertDist(dist) { @@ -137,7 +137,7 @@ class SequentialColumnProcessor { RansacAlgo::RansacAlgo(const std::vector& segments) - : m_rSegments(segments), m_cosThreshold(cos(4.0 * constants::DEG2RAD)) { + : m_rSegments(segments), m_cosThreshold(std::cos(4.0 * constants::DEG2RAD)) { } void RansacAlgo::buildAndAssessModel(const Segment& seed_segment) { @@ -259,12 +259,12 @@ QLineF SequentialColumnProcessor::approximateWithLine(std::vector* dbg_ assert(pt2.y() > pt1.y()); Vec2d vec(pt2 - pt1); - if (fabs(vec[0]) > fabs(vec[1])) { + if (std::fabs(vec[0]) > std::fabs(vec[1])) { // We don't want segments that are more horizontal than vertical. continue; } - vec /= sqrt(vec.squaredNorm()); + vec /= std::sqrt(vec.squaredNorm()); segments.emplace_back(QLine(pt1, pt2), vec, pt2.y() - pt1.y()); } @@ -312,7 +312,7 @@ QLineF SequentialColumnProcessor::interpolateSegments(const std::vector double accum_weight = 0; for (const Segment& seg : segments) { - const double weight = sqrt(double(seg.vertDist)); + const double weight = std::sqrt(double(seg.vertDist)); accum_vec += weight * seg.unitVec; accum_weight += weight; } diff --git a/dewarping/DistortionModel.cpp b/dewarping/DistortionModel.cpp index a86bb062f..395a2fcf6 100644 --- a/dewarping/DistortionModel.cpp +++ b/dewarping/DistortionModel.cpp @@ -75,7 +75,7 @@ bool DistortionModel::isValid() const { return false; } - if ((fabs(min_dot) < 0.01) || (fabs(max_dot) < 0.01)) { + if ((std::fabs(min_dot) < 0.01) || (std::fabs(max_dot) < 0.01)) { // Too close - possible problems with calculating homography. return false; } diff --git a/dewarping/DistortionModelBuilder.cpp b/dewarping/DistortionModelBuilder.cpp index 215f8d673..32fcbe2e5 100644 --- a/dewarping/DistortionModelBuilder.cpp +++ b/dewarping/DistortionModelBuilder.cpp @@ -487,7 +487,7 @@ void DistortionModelBuilder::RansacAlgo::buildAndAssessModel(const TracedCurve* double sum_abs_err = 0; for (size_t i = 0; i < polyline_size; ++i) { - sum_abs_err += fabs(errvec[i]) * r_reference_height; + sum_abs_err += std::fabs(errvec[i]) * r_reference_height; } // Penalty for not being straight. error += sum_abs_err / polyline_size; @@ -518,7 +518,7 @@ catch (const std::runtime_error&) { const QPointF pt1(dewarper.mapToDewarpedSpace(loc + QPointF(0.0, -10))); const QPointF pt2(dewarper.mapToDewarpedSpace(loc + QPointF(0.0, 10))); - return fabs(pt1.y() - pt2.y()); + return std::fabs(pt1.y() - pt2.y()); } #endif @@ -530,7 +530,7 @@ QImage DistortionModelBuilder::visualizeTrimmedPolylines(const QImage& backgroun const int width = background.width(); const int height = background.height(); - const double stroke_width = sqrt(double(width * width + height * height)) / 500; + const double stroke_width = std::sqrt(double(width * width + height * height)) / 500; // Extend / trim bounds. QLineF bound1(m_bound1); @@ -575,7 +575,7 @@ QImage DistortionModelBuilder::visualizeModel(const QImage& background, const int width = background.width(); const int height = background.height(); - const double stroke_width = sqrt(double(width * width + height * height)) / 500; + const double stroke_width = std::sqrt(double(width * width + height * height)) / 500; // Extend / trim bounds. QLineF bound1(m_bound1); diff --git a/dewarping/RasterDewarper.cpp b/dewarping/RasterDewarper.cpp index c8bd44c86..23e2b10fc 100644 --- a/dewarping/RasterDewarper.cpp +++ b/dewarping/RasterDewarper.cpp @@ -113,8 +113,8 @@ void dewarpGeneric(const PixelType* const src_data, const float model_y = ((float) dst_y - model_domain_top) * model_y_scale; const Vec2f src_pt(origin + vec * homog(model_y)); - const int src_x0 = (int) floor(src_pt[0] - 0.5f); - const int src_y0 = (int) floor(src_pt[1] - 0.5f); + const int src_x0 = (int) std::floor(src_pt[0] - 0.5f); + const int src_y0 = (int) std::floor(src_pt[1] - 0.5f); const int src_x1 = src_x0 + 1; const int src_y1 = src_y0 + 1; const float x = src_pt[0] - src_x0; @@ -213,7 +213,7 @@ void areaMapGeneratrix(const PixelType* const src_data, // Note: the code below is more or less the same as in transformGeneric() // in imageproc/Transform.cpp - // Note that without using floor() and ceil() + // Note that without using std::floor() and std::ceil() // we can't guarantee that src_bottom >= src_top // and src_right >= src_left. auto src32_left = (int) std::floor(f_src32_left); diff --git a/dewarping/TextLineRefiner.cpp b/dewarping/TextLineRefiner.cpp index d38afb960..b297c7a4a 100644 --- a/dewarping/TextLineRefiner.cpp +++ b/dewarping/TextLineRefiner.cpp @@ -172,8 +172,8 @@ void TextLineRefiner::calcBlurredGradient(Grid& gradient, float h_sigma, } float TextLineRefiner::externalEnergyAt(const Grid& gradient, const Vec2f& pos, float penalty_if_outside) { - const auto x_base = static_cast(floor(pos[0])); - const auto y_base = static_cast(floor(pos[1])); + const auto x_base = static_cast(std::floor(pos[0])); + const auto y_base = static_cast(std::floor(pos[1])); const auto x_base_i = (int) x_base; const auto y_base_i = (int) y_base; @@ -197,7 +197,7 @@ TextLineRefiner::Snake TextLineRefiner::makeSnake(const std::vector& po const size_t polyline_size = polyline.size(); for (size_t i = 1; i < polyline_size; ++i) { - total_length += sqrt(Vec2f(polyline[i] - polyline[i - 1]).squaredNorm()); + total_length += std::sqrt(Vec2f(polyline[i] - polyline[i - 1]).squaredNorm()); } const auto points_in_snake = static_cast(total_length / 20); @@ -210,7 +210,7 @@ TextLineRefiner::Snake TextLineRefiner::makeSnake(const std::vector& po for (size_t i = 1; i < polyline_size; ++i) { const Vec2f base(polyline[i - 1]); const Vec2f vec((polyline[i] - base)); - const auto next_t = static_cast(base_t + sqrt(vec.squaredNorm())); + const auto next_t = static_cast(base_t + std::sqrt(vec.squaredNorm())); while (next_t >= next_insert_t) { const float fraction = (next_insert_t - base_t) / (next_t - base_t); @@ -261,7 +261,7 @@ void TextLineRefiner::calcFrenetFrames(std::vector& frenet_frames, } Vec2f tangent_vec(0.5 * (prev_segment + next_segment)); - const auto len = static_cast(sqrt(tangent_vec.squaredNorm())); + const auto len = static_cast(std::sqrt(tangent_vec.squaredNorm())); if (len > std::numeric_limits::epsilon()) { tangent_vec /= len; } @@ -435,7 +435,7 @@ TextLineRefiner::SnakeLength::SnakeLength(const Snake& snake) float arc_length_accum = 0; for (size_t i = 1; i < num_nodes; ++i) { const Vec2f vec(snake.nodes[i].center - snake.nodes[i - 1].center); - arc_length_accum += sqrt(vec.squaredNorm()); + arc_length_accum += std::sqrt(vec.squaredNorm()); m_integralLength[i] = arc_length_accum; } m_totalLength = arc_length_accum; @@ -730,7 +730,7 @@ float TextLineRefiner::Optimizer::calcExternalEnergy(const Grid& gradient float TextLineRefiner::Optimizer::calcElasticityEnergy(const SnakeNode& node1, const SnakeNode& node2, float avg_dist) { const Vec2f vec(node1.center - node2.center); - const auto vec_len = static_cast(sqrt(vec.squaredNorm())); + const auto vec_len = static_cast(std::sqrt(vec.squaredNorm())); if (vec_len < 1.0f) { return 1000.0f; // Penalty for moving too close to another node. @@ -745,14 +745,14 @@ float TextLineRefiner::Optimizer::calcBendingEnergy(const SnakeNode& node, const SnakeNode& prev_node, const SnakeNode& prev_prev_node) { const Vec2f vec(node.center - prev_node.center); - const auto vec_len = static_cast(sqrt(vec.squaredNorm())); + const auto vec_len = static_cast(std::sqrt(vec.squaredNorm())); if (vec_len < 1.0f) { return 1000.0f; // Penalty for moving too close to another node. } const Vec2f prev_vec(prev_node.center - prev_prev_node.center); - const auto prev_vec_len = static_cast(sqrt(prev_vec.squaredNorm())); + const auto prev_vec_len = static_cast(std::sqrt(prev_vec.squaredNorm())); if (prev_vec_len < 1.0f) { return 1000.0f; // Penalty for moving too close to another node. } diff --git a/dewarping/TextLineTracer.cpp b/dewarping/TextLineTracer.cpp index 844eae7d7..6e29bf269 100644 --- a/dewarping/TextLineTracer.cpp +++ b/dewarping/TextLineTracer.cpp @@ -102,7 +102,7 @@ void TextLineTracer::trace(const GrayImage& input, } Vec2f unit_down_vector(calcAvgUnitVector(vert_bounds)); - unit_down_vector /= sqrt(unit_down_vector.squaredNorm()); + unit_down_vector /= std::sqrt(unit_down_vector.squaredNorm()); if (unit_down_vector[1] < 0) { unit_down_vector = -unit_down_vector; } @@ -171,7 +171,7 @@ bool TextLineTracer::isCurvatureConsistent(const std::vector& polyline) return true; } // Threshold angle between a polyline segment and a normal to the previous one. - const auto cos_threshold = static_cast(cos((90.0f - 6.0f) * constants::DEG2RAD)); + const auto cos_threshold = static_cast(std::cos((90.0f - 6.0f) * constants::DEG2RAD)); const float cos_sq_threshold = cos_threshold * cos_threshold; bool significant_positive = false; bool significant_negative = false; @@ -413,13 +413,13 @@ void TextLineTracer::extractTextLines(std::list>& out, Vec2f TextLineTracer::calcAvgUnitVector(const std::pair& bounds) { Vec2f v1(bounds.first.p2() - bounds.first.p1()); - v1 /= sqrt(v1.squaredNorm()); + v1 /= std::sqrt(v1.squaredNorm()); Vec2f v2(bounds.second.p2() - bounds.second.p1()); - v2 /= sqrt(v2.squaredNorm()); + v2 /= std::sqrt(v2.squaredNorm()); Vec2f v3(v1 + v2); - v3 /= sqrt(v3.squaredNorm()); + v3 /= std::sqrt(v3.squaredNorm()); return v3; } @@ -473,8 +473,8 @@ QLineF TextLineTracer::calcMidLine(const QLineF& line1, const QLineF& line2) { // Lines do intersect. Vec2d v1(line1.p2() - line1.p1()); Vec2d v2(line2.p2() - line2.p1()); - v1 /= sqrt(v1.squaredNorm()); - v2 /= sqrt(v2.squaredNorm()); + v1 /= std::sqrt(v1.squaredNorm()); + v2 /= std::sqrt(v2.squaredNorm()); return QLineF(intersection, intersection + 0.5 * (v1 + v2)); } diff --git a/dewarping/TopBottomEdgeTracer.cpp b/dewarping/TopBottomEdgeTracer.cpp index 657997d0f..c5bc4bfec 100644 --- a/dewarping/TopBottomEdgeTracer.cpp +++ b/dewarping/TopBottomEdgeTracer.cpp @@ -162,8 +162,8 @@ float TopBottomEdgeTracer::interpolatedGridValue(const Grid& grid, Extractor extractor, const Vec2f pos, float default_value) { - const auto x_base = static_cast(floor(pos[0])); - const auto y_base = static_cast(floor(pos[1])); + const auto x_base = static_cast(std::floor(pos[0])); + const auto y_base = static_cast(std::floor(pos[1])); const auto x_base_i = (int) x_base; const auto y_base_i = (int) y_base; @@ -427,13 +427,13 @@ void TopBottomEdgeTracer::verticalSobelInPlace(Grid& grid) { Vec2f TopBottomEdgeTracer::calcAvgUnitVector(const std::pair& bounds) { Vec2f v1(bounds.first.p2() - bounds.first.p1()); - v1 /= sqrt(v1.squaredNorm()); + v1 /= std::sqrt(v1.squaredNorm()); Vec2f v2(bounds.second.p2() - bounds.second.p1()); - v2 /= sqrt(v2.squaredNorm()); + v2 /= std::sqrt(v2.squaredNorm()); Vec2f v3(v1 + v2); - v3 /= sqrt(v3.squaredNorm()); + v3 /= std::sqrt(v3.squaredNorm()); return v3; } @@ -730,7 +730,7 @@ void TopBottomEdgeTracer::downTheHillSnake(std::vector& snake, const Gr float avg_dist = 0; for (size_t i = 1; i < num_nodes; ++i) { const Vec2f vec(snake[i] - snake[i - 1]); - avg_dist += sqrt(vec.squaredNorm()); + avg_dist += std::sqrt(vec.squaredNorm()); } avg_dist /= num_nodes - 1; @@ -782,7 +782,7 @@ void TopBottomEdgeTracer::downTheHillSnake(std::vector& snake, const Gr float cost = prev_step.pathCost + step.pathCost; const Vec2f vec(step.pt - prev_step.pt); - const auto vec_len = static_cast(sqrt(vec.squaredNorm())); + const auto vec_len = static_cast(std::sqrt(vec.squaredNorm())); if (vec_len < segment_dist_threshold) { cost += 1000; } @@ -796,12 +796,12 @@ void TopBottomEdgeTracer::downTheHillSnake(std::vector& snake, const Gr Vec2f prev_normal(prev_step.pt - prev_prev_step.pt); std::swap(prev_normal[0], prev_normal[1]); prev_normal[0] = -prev_normal[0]; - const auto prev_normal_len = static_cast(sqrt(prev_normal.squaredNorm())); + const auto prev_normal_len = static_cast(std::sqrt(prev_normal.squaredNorm())); if (prev_normal_len < segment_dist_threshold) { cost += 1000; } else { const float cos = vec.dot(prev_normal) / (vec_len * prev_normal_len); - // cost += 0.7 * fabs(cos); + // cost += 0.7 * std::fabs(cos); cost += bending_weight * cos * cos; } } @@ -859,7 +859,7 @@ void TopBottomEdgeTracer::upTheHillSnake(std::vector& snake, const Grid float avg_dist = 0; for (size_t i = 1; i < num_nodes; ++i) { const Vec2f vec(snake[i] - snake[i - 1]); - avg_dist += sqrt(vec.squaredNorm()); + avg_dist += std::sqrt(vec.squaredNorm()); } avg_dist /= num_nodes - 1; @@ -913,7 +913,7 @@ void TopBottomEdgeTracer::upTheHillSnake(std::vector& snake, const Grid float cost = prev_step.pathCost + step.pathCost; const Vec2f vec(step.pt - prev_step.pt); - const auto vec_len = static_cast(sqrt(vec.squaredNorm())); + const auto vec_len = static_cast(std::sqrt(vec.squaredNorm())); if (vec_len < segment_dist_threshold) { cost += 1000; } @@ -927,12 +927,12 @@ void TopBottomEdgeTracer::upTheHillSnake(std::vector& snake, const Grid Vec2f prev_normal(prev_step.pt - prev_prev_step.pt); std::swap(prev_normal[0], prev_normal[1]); prev_normal[0] = -prev_normal[0]; - const auto prev_normal_len = static_cast(sqrt(prev_normal.squaredNorm())); + const auto prev_normal_len = static_cast(std::sqrt(prev_normal.squaredNorm())); if (prev_normal_len < segment_dist_threshold) { cost += 1000; } else { const float cos = vec.dot(prev_normal) / (vec_len * prev_normal_len); - // cost += 0.7 * fabs(cos); + // cost += 0.7 * std::fabs(cos); cost += bending_weight * cos * cos; } } diff --git a/dewarping/TowardsLineTracer.cpp b/dewarping/TowardsLineTracer.cpp index 26fc2dbbb..598cd8696 100644 --- a/dewarping/TowardsLineTracer.cpp +++ b/dewarping/TowardsLineTracer.cpp @@ -159,7 +159,7 @@ void TowardsLineTracer::setupSteps() { Step& step = m_steps[m_numSteps]; step.vec = dir; step.unitVec = Vec2d(step.vec.x(), step.vec.y()); - step.unitVec /= sqrt(step.unitVec.squaredNorm()); + step.unitVec /= std::sqrt(step.unitVec.squaredNorm()); step.dmOffset = step.vec.y() * m_dmStride + step.vec.x(); step.pmOffset = step.vec.y() * m_pmStride + step.vec.x(); ++m_numSteps; diff --git a/filters/deskew/ImageView.cpp b/filters/deskew/ImageView.cpp index 278b3d694..e3e21e38f 100644 --- a/filters/deskew/ImageView.cpp +++ b/filters/deskew/ImageView.cpp @@ -28,7 +28,7 @@ namespace deskew { const double ImageView::m_maxRotationDeg = 45.0; -const double ImageView::m_maxRotationSin = sin(m_maxRotationDeg * imageproc::constants::DEG2RAD); +const double ImageView::m_maxRotationSin = std::sin(m_maxRotationDeg * imageproc::constants::DEG2RAD); const int ImageView::m_cellSize = 20; ImageView::ImageView(const QImage& image, const QImage& downscaled_image, const ImageTransformation& xform) @@ -194,7 +194,7 @@ void ImageView::handleMoveRequest(int idx, const QPointF& pos) { double rel_y = abs_y - arc_square.center().y(); rel_y = qBound(-arc_radius, rel_y, arc_radius); - double angle_rad = asin(rel_y / arc_radius); + double angle_rad = std::asin(rel_y / arc_radius); if (idx == 0) { angle_rad = -angle_rad; } @@ -219,7 +219,7 @@ void ImageView::dragFinished() { QPointF ImageView::getImageRotationOrigin() const { const QRectF viewport_rect(maxViewportRect()); - return QPointF(floor(0.5 * viewport_rect.width()) + 0.5, floor(0.5 * viewport_rect.height()) + 0.5); + return QPointF(std::floor(0.5 * viewport_rect.width()) + 0.5, std::floor(0.5 * viewport_rect.height()) + 0.5); } /** diff --git a/filters/output/OutputImageParams.cpp b/filters/output/OutputImageParams.cpp index c019dfaa8..dcb551687 100644 --- a/filters/output/OutputImageParams.cpp +++ b/filters/output/OutputImageParams.cpp @@ -238,6 +238,6 @@ bool OutputImageParams::PartialXform::matches(const PartialXform& other) const { } bool OutputImageParams::PartialXform::closeEnough(double v1, double v2) { - return fabs(v1 - v2) < 0.0001; + return std::fabs(v1 - v2) < 0.0001; } } // namespace output \ No newline at end of file diff --git a/filters/output/PictureZoneEditor.cpp b/filters/output/PictureZoneEditor.cpp index 630c31d2f..c074c4922 100644 --- a/filters/output/PictureZoneEditor.cpp +++ b/filters/output/PictureZoneEditor.cpp @@ -149,7 +149,7 @@ void PictureZoneEditor::onPaint(QPainter& painter, const InteractionState& inter if (!validateScreenPictureMask()) { schedulePictureMaskRebuild(); } else { - const double sn = sin(constants::DEG2RAD * m_pictureMaskAnimationPhase); + const double sn = std::sin(constants::DEG2RAD * m_pictureMaskAnimationPhase); const double scale = 0.5 * (sn + 1.0); // 0 .. 1 const double opacity = 0.35 * scale + 0.15; diff --git a/filters/output/TabbedImageView.cpp b/filters/output/TabbedImageView.cpp index 320d2ac26..f84739d28 100644 --- a/filters/output/TabbedImageView.cpp +++ b/filters/output/TabbedImageView.cpp @@ -126,10 +126,10 @@ void TabbedImageView::setFocus(QScrollBar& hor_bar, const int hor_bar_length = hor_bar.maximum() - hor_bar.minimum() + hor_bar.pageStep(); const int ver_bar_length = ver_bar.maximum() - ver_bar.minimum() + ver_bar.pageStep(); - auto hor_value - = (int) round(((focal.x() - rect.left()) / rect.width()) * hor_bar_length - (hor_bar.pageStep() / 2.0)); - auto ver_value - = (int) round(((focal.y() - rect.top()) / rect.height()) * ver_bar_length - (ver_bar.pageStep() / 2.0)); + auto hor_value = (int) std::round(((focal.x() - rect.left()) / rect.width()) * hor_bar_length + - (hor_bar.pageStep() / 2.0)); + auto ver_value = (int) std::round(((focal.y() - rect.top()) / rect.height()) * ver_bar_length + - (ver_bar.pageStep() / 2.0)); hor_value = qBound(hor_bar.minimum(), hor_value, hor_bar.maximum()); ver_value = qBound(ver_bar.minimum(), ver_value, ver_bar.maximum()); diff --git a/filters/page_split/PageLayoutEstimator.cpp b/filters/page_split/PageLayoutEstimator.cpp index 9b10a8424..ce916c1ff 100644 --- a/filters/page_split/PageLayoutEstimator.cpp +++ b/filters/page_split/PageLayoutEstimator.cpp @@ -98,14 +98,14 @@ std::unique_ptr autoDetectSinglePageLayout(const LayoutType layout_t if (!ltr_lines.empty()) { const QLineF& first_line = ltr_lines.front(); const double line_center = lineCenterX(first_line); - if (fabs(image_center - line_center) > 0.65 * image_center) { + if (std::fabs(image_center - line_center) > 0.65 * image_center) { break; } } if (ltr_lines.size() > 1) { const QLineF& last_line = ltr_lines.back(); const double line_center = lineCenterX(last_line); - if (fabs(image_center - line_center) > 0.65 * image_center) { + if (std::fabs(image_center - line_center) > 0.65 * image_center) { break; } } @@ -157,7 +157,7 @@ std::unique_ptr autoDetectTwoPageLayout(const std::vector& l const QLineF* best_line = nullptr; for (const QLineF& line : ltr_lines) { const double line_center = lineCenterX(line); - const double distance = fabs(line_center - image_center); + const double distance = std::fabs(line_center - image_center); if (distance < min_distance) { min_distance = distance; best_line = &line; @@ -219,7 +219,7 @@ class BadTwoPageSplitter { * to be the line splitting two pages */ bool operator()(const QLineF& line) { - const double dist = fabs(lineCenterX(line) - m_imageCenter); + const double dist = std::fabs(lineCenterX(line) - m_imageCenter); return dist > m_distFromCenterThreshold; } @@ -281,8 +281,8 @@ std::unique_ptr PageLayoutEstimator::tryCutAtFoldingLine(const Layou break; } - left_dist = fabs(left_dist); - right_dist = fabs(right_dist); + left_dist = std::fabs(left_dist); + right_dist = std::fabs(right_dist); if ((left_dist < threshold) || (right_dist < threshold)) { // At least one of them is relatively close // to the center. @@ -359,9 +359,9 @@ PageLayout PageLayoutEstimator::cutAtWhitespace(const LayoutType layout_type, const int w = img.width(); const int h = img.height(); const double angle_deg = skew.angle(); - const double tg = tan(angle_deg * constants::DEG2RAD); + const double tg = std::tan(angle_deg * constants::DEG2RAD); - const auto margin = (int) ceil(fabs(0.5 * h * tg)); + const auto margin = (int) std::ceil(std::fabs(0.5 * h * tg)); const int new_width = w - margin * 2; if (new_width > 0) { hShearInPlace(img, tg, 0.5 * h, WHITE); @@ -465,15 +465,15 @@ imageproc::BinaryImage PageLayoutEstimator::to300DpiBinary(const QImage& img, const BinaryThreshold binary_threshold) { const double xfactor = (300.0 * constants::DPI2DPM) / img.dotsPerMeterX(); const double yfactor = (300.0 * constants::DPI2DPM) / img.dotsPerMeterY(); - if ((fabs(xfactor - 1.0) < 0.1) && (fabs(yfactor - 1.0) < 0.1)) { + if ((std::fabs(xfactor - 1.0) < 0.1) && (std::fabs(yfactor - 1.0) < 0.1)) { return BinaryImage(img, binary_threshold); } QTransform scale_xform; scale_xform.scale(xfactor, yfactor); xform *= scale_xform; - const QSize new_size(std::max(1, (int) ceil(xfactor * img.width())), - std::max(1, (int) ceil(yfactor * img.height()))); + const QSize new_size(std::max(1, (int) std::ceil(xfactor * img.width())), + std::max(1, (int) std::ceil(yfactor * img.height()))); const GrayImage new_image(scaleToGray(GrayImage(img), new_size)); @@ -772,7 +772,7 @@ PageLayout PageLayoutEstimator::processTwoPagesWithSingleSpan(const Span& span, const double page_center = 0.5 * width; const double box_center = span.center(); const double box_half_width = 0.5 * span.width(); - const double distance_to_page_center = fabs(page_center - box_center) - box_half_width; + const double distance_to_page_center = std::fabs(page_center - box_center) - box_half_width; double x; diff --git a/filters/page_split/VertLineFinder.cpp b/filters/page_split/VertLineFinder.cpp index ee405df5f..7dbf30b72 100644 --- a/filters/page_split/VertLineFinder.cpp +++ b/filters/page_split/VertLineFinder.cpp @@ -123,7 +123,7 @@ std::vector VertLineFinder::findLines(const QImage& image, // We don't want to process areas too close to the vertical edges. const double margin_mm = 3.5; - const auto margin = (int) floor(0.5 + margin_mm * constants::MM2INCH * dpi); + const auto margin = (int) std::floor(0.5 + margin_mm * constants::MM2INCH * dpi); const int x_limit = raster_lines.width() - margin; const int height = raster_lines.height(); diff --git a/filters/select_content/ContentBoxFinder.cpp b/filters/select_content/ContentBoxFinder.cpp index 207af7fff..475bba264 100644 --- a/filters/select_content/ContentBoxFinder.cpp +++ b/filters/select_content/ContentBoxFinder.cpp @@ -830,7 +830,7 @@ imageproc::BinaryImage ContentBoxFinder::estimateTextMask(const imageproc::Binar } // Extend the top and bottom of the text line. - while ((top > first || bottom < last) && abs((center_y - top) - (bottom - center_y)) <= 1) { + while ((top > first || bottom < last) && std::abs((center_y - top) - (bottom - center_y)) <= 1) { const int new_top = (top > first) ? top - 1 : top; const int new_bottom = (bottom < last) ? bottom + 1 : bottom; num_black += hist[new_top] + hist[new_bottom]; @@ -1149,8 +1149,8 @@ QRect ContentBoxFinder::trim(const imageproc::BinaryImage& content, double text_influence = max_text_influence; if (num_text_pixels < upper_threshold) { text_influence = min_text_influence - + (max_text_influence - min_text_influence) * log((double) num_text_pixels) - / log((double) upper_threshold); + + (max_text_influence - min_text_influence) * std::log((double) num_text_pixels) + / std::log((double) upper_threshold); } // qDebug() << "text_influence = " << text_influence; @@ -1183,8 +1183,8 @@ QRect ContentBoxFinder::trim(const imageproc::BinaryImage& content, for (int y = removed_area.top(); y <= removed_area.bottom(); ++y) { for (int x = removed_area.left(); x <= removed_area.right(); ++x) { if (cb_line[x >> 5] & (msb >> (x & 31))) { - sum_dist_to_garbage += sqrt((double) dm_garbage_line[x]); - sum_dist_to_others += sqrt((double) dm_others_line[x]); + sum_dist_to_garbage += std::sqrt((double) dm_garbage_line[x]); + sum_dist_to_others += std::sqrt((double) dm_others_line[x]); ++count; } } diff --git a/filters/select_content/PageFinder.cpp b/filters/select_content/PageFinder.cpp index 6fd5e829b..69ffba359 100644 --- a/filters/select_content/PageFinder.cpp +++ b/filters/select_content/PageFinder.cpp @@ -104,8 +104,8 @@ QRectF PageFinder::findPageBox(const TaskStatus& status, std::cout << "width = " << rects[i].width() << "; height=" << rects[i].height() << std::endl; #endif - double err_w = double(abs(exp_width - rects[i].width())) / double(exp_width); - double err_h = double(abs(exp_height - rects[i].height())) / double(exp_height); + double err_w = double(std::abs(exp_width - rects[i].width())) / double(exp_width); + double err_h = double(std::abs(exp_height - rects[i].height())) / double(exp_height); #ifdef DEBUG std::cout << "err_w=" << err_w << "; err_h" << err_h << std::endl; #endif @@ -227,8 +227,8 @@ bool PageFinder::fineTuneCorner(const QImage& img, int pixel = img.pixelIndex(x, y); int tx = x + inc_x; int ty = y + inc_y; - int w = abs(max_x - x); - int h = abs(max_y - y); + int w = std::abs(max_x - x); + int h = std::abs(max_y - y); if ((!size.isEmpty()) && ((w < width_t) || (h < height_t))) { return true; diff --git a/foundation/GridLineTraverser.cpp b/foundation/GridLineTraverser.cpp index 16ed1e573..cca5205fa 100644 --- a/foundation/GridLineTraverser.cpp +++ b/foundation/GridLineTraverser.cpp @@ -24,7 +24,7 @@ GridLineTraverser::GridLineTraverser(const QLineF& line) { const QPoint p2(line.p2().toPoint()); int h_spans, v_spans, num_spans; double s1 = 0.0, s2 = 0.0; - if ((h_spans = abs(p1.x() - p2.x())) > (v_spans = abs(p1.y() - p2.y()))) { + if ((h_spans = std::abs(p1.x() - p2.x())) > (v_spans = std::abs(p1.y() - p2.y()))) { // Major direction: horizontal. num_spans = h_spans; lineIntersectionScalar(line, QLineF(p1, QPoint(p1.x(), p1.y() + 1)), s1); diff --git a/foundation/Proximity.h b/foundation/Proximity.h index 87a923ba2..300a8a175 100644 --- a/foundation/Proximity.h +++ b/foundation/Proximity.h @@ -43,7 +43,7 @@ class Proximity { static Proximity pointAndLineSegment(const QPointF& pt, const QLineF& segment, QPointF* point_on_segment = nullptr); double dist() const { - return sqrt(m_sqDist); + return std::sqrt(m_sqDist); } double sqDist() const { diff --git a/foundation/ValueConv.h b/foundation/ValueConv.h index a4d4e84ac..0aac063d3 100644 --- a/foundation/ValueConv.h +++ b/foundation/ValueConv.h @@ -50,7 +50,7 @@ class RoundAndClipValueConv { } else if (val > FromType(m_max)) { return m_max; } else { - return static_cast(floor(val + 0.5)); + return static_cast(std::floor(val + 0.5)); } } diff --git a/imageproc/Binarize.cpp b/imageproc/Binarize.cpp index b2ba5482f..9ef983f2b 100644 --- a/imageproc/Binarize.cpp +++ b/imageproc/Binarize.cpp @@ -91,7 +91,7 @@ BinaryImage binarizeSauvola(const QImage& src, const QSize window_size, const do const double sqmean = window_sqsum * r_area; const double variance = sqmean - mean * mean; - const double deviation = sqrt(fabs(variance)); + const double deviation = std::sqrt(std::fabs(variance)); const double threshold = mean * (1.0 + k * (deviation / 128.0 - 1.0)); @@ -176,7 +176,7 @@ BinaryImage binarizeWolf(const QImage& src, const double sqmean = window_sqsum * r_area; const double variance = sqmean - mean * mean; - const double deviation = sqrt(fabs(variance)); + const double deviation = std::sqrt(std::fabs(variance)); max_deviation = std::max(max_deviation, deviation); means[w * y + x] = (float) mean; deviations[w * y + x] = (float) deviation; diff --git a/imageproc/FindPeaksGeneric.h b/imageproc/FindPeaksGeneric.h index 83da9a389..e2093d782 100644 --- a/imageproc/FindPeaksGeneric.h +++ b/imageproc/FindPeaksGeneric.h @@ -84,7 +84,7 @@ void raiseAllButPeaks(MostSignificantSelector most_significant, * \param least_significant Same as most_significant, but the oposite operation. * \param increase_significance A functor or a pointer to a free function that * takes one argument and returns the next most significant value next - * to it. Hint: for floating point data, use the nextafter() family of + * to it. Hint: for floating point data, use the std::nextafter() family of * functions. Their generic versions are available in Boost. * \param peak_mutator A functor or a pointer to a free function that will * transform a peak value. Two typical cases would be returning diff --git a/imageproc/GaussBlur.cpp b/imageproc/GaussBlur.cpp index a0e0a08da..3f31534ac 100644 --- a/imageproc/GaussBlur.cpp +++ b/imageproc/GaussBlur.cpp @@ -33,7 +33,7 @@ void find_iir_constants(float* n_p, float* n_m, float* d_p, float* d_m, float* b * using a 4th order approximation of the gaussian operator */ - const auto div = static_cast(sqrt(2.0 * constants::PI) * std_dev); + const auto div = static_cast(std::sqrt(2.0 * constants::PI) * std_dev); const auto x0 = static_cast(-1.783 / std_dev); const auto x1 = static_cast(-1.723 / std_dev); const auto x2 = static_cast(0.6318 / std_dev); diff --git a/imageproc/HoughLineDetector.cpp b/imageproc/HoughLineDetector.cpp index 17009cf35..465a67450 100644 --- a/imageproc/HoughLineDetector.cpp +++ b/imageproc/HoughLineDetector.cpp @@ -60,7 +60,7 @@ HoughLineDetector::HoughLineDetector(const QSize& input_dimensions, double angle = start_angle + angle_delta * i; angle *= constants::DEG2RAD; - const QPointF uv(cos(angle), sin(angle)); + const QPointF uv(std::cos(angle), std::sin(angle)); for (const QPoint& p : checkpoints) { const double distance = uv.x() * p.x() + uv.y() * p.y(); max_distance = std::max(max_distance, distance); @@ -122,7 +122,7 @@ QImage HoughLineDetector::visualizeHoughSpace(const unsigned lower_bound) const hist_line = &m_histogram[0]; for (int y = 0; y < m_histHeight; ++y) { for (int x = 0; x < m_histWidth; ++x) { - const auto intensity = (unsigned) floor(hist_line[x] * 255.0 / max_value + 0.5); + const auto intensity = (unsigned) std::floor(hist_line[x] * 255.0 / max_value + 0.5); intensity_line[x] = (unsigned char) intensity; } intensity_line += intensity_bpl; diff --git a/imageproc/Morphology.cpp b/imageproc/Morphology.cpp index 7beb9bbd5..87fec7f95 100644 --- a/imageproc/Morphology.cpp +++ b/imageproc/Morphology.cpp @@ -293,7 +293,7 @@ void spreadInDirection(BinaryImage& dst, return; } - const auto first_phase_steps = (int) sqrt((double) num_steps); + const auto first_phase_steps = (int) std::sqrt((double) num_steps); BinaryImage tmp(tmp_images.retrieveOrCreate(tmp_image_size)); diff --git a/imageproc/PolygonUtils.cpp b/imageproc/PolygonUtils.cpp index ae6d7bba3..c7969e88c 100644 --- a/imageproc/PolygonUtils.cpp +++ b/imageproc/PolygonUtils.cpp @@ -45,7 +45,7 @@ class PolygonUtils::Before { static int compare(const QPointF& lhs, const QPointF& rhs) { const double dx = lhs.x() - rhs.x(); const double dy = lhs.y() - rhs.y(); - if (fabs(dx) > fabs(dy)) { + if (std::fabs(dx) > std::fabs(dy)) { if (dx < 0.0) { return -1; } else if (dx > 0.0) { @@ -112,7 +112,7 @@ QPointF PolygonUtils::roundPoint(const QPointF& p) { } double PolygonUtils::roundValue(const double val) { - return floor(val * ROUNDING_MULTIPLIER + 0.5) * ROUNDING_RECIP_MULTIPLIER; + return std::floor(val * ROUNDING_MULTIPLIER + 0.5) * ROUNDING_RECIP_MULTIPLIER; } std::vector PolygonUtils::extractAndNormalizeEdges(const QPolygonF& poly) { @@ -158,8 +158,8 @@ bool PolygonUtils::fuzzyCompareImpl(const QLineF& line1, const QLineF& line2) { } bool PolygonUtils::fuzzyCompareImpl(const QPointF& p1, const QPointF& p2) { - const double dx = fabs(p1.x() - p2.x()); - const double dy = fabs(p1.y() - p2.y()); + const double dx = std::fabs(p1.x() - p2.x()); + const double dy = std::fabs(p1.y() - p2.y()); return dx <= ROUNDING_RECIP_MULTIPLIER && dy <= ROUNDING_RECIP_MULTIPLIER; } diff --git a/imageproc/PolynomialLine.h b/imageproc/PolynomialLine.h index 6b00e499a..d4e1b90f9 100644 --- a/imageproc/PolynomialLine.h +++ b/imageproc/PolynomialLine.h @@ -135,7 +135,7 @@ PolynomialLine::RoundAndClipPostProcessor::RoundAndClipPostProcessor() template inline T PolynomialLine::RoundAndClipPostProcessor::operator()(const double val) const { - const double rounded = floor(val + 0.5); + const double rounded = std::floor(val + 0.5); if (rounded < m_min) { return m_min; } else if (rounded > m_max) { diff --git a/imageproc/RastLineFinder.cpp b/imageproc/RastLineFinder.cpp index 5b9ef446a..09f780237 100644 --- a/imageproc/RastLineFinder.cpp +++ b/imageproc/RastLineFinder.cpp @@ -99,13 +99,13 @@ RastLineFinder::RastLineFinder(const std::vector& points, const RastLin } } - const auto max_dist = static_cast(sqrt(max_sqdist) + 1.0); // + 1.0 to combant rounding issues + const auto max_dist = static_cast(std::sqrt(max_sqdist) + 1.0); // + 1.0 to combant rounding issues - double delta_deg = fmod(params.maxAngleDeg() - params.minAngleDeg(), 360.0); + double delta_deg = std::fmod(params.maxAngleDeg() - params.minAngleDeg(), 360.0); if (delta_deg < 0) { delta_deg += 360; } - const double min_angle_deg = fmod(params.minAngleDeg(), 360.0); + const double min_angle_deg = std::fmod(params.minAngleDeg(), 360.0); const double max_angle_deg = min_angle_deg + delta_deg; SearchSpace ssp(*this, -max_dist, max_dist, static_cast(min_angle_deg * constants::DEG2RAD), diff --git a/imageproc/ReduceThreshold.h b/imageproc/ReduceThreshold.h index c8cb95672..166a0c797 100644 --- a/imageproc/ReduceThreshold.h +++ b/imageproc/ReduceThreshold.h @@ -27,8 +27,8 @@ namespace imageproc { * * The dimensions of the target image will be: * \code - * dst_width = max(1, floor(src_width / 2)); - * dst_height = max(1, floor(src_height / 2)); + * dst_width = max(1, std::floor(src_width / 2)); + * dst_height = max(1, std::floor(src_height / 2)); * \endcode * \n * Processing a null image results in a null image. diff --git a/imageproc/SavGolKernel.cpp b/imageproc/SavGolKernel.cpp index 2cd34a87e..83e6f2d96 100644 --- a/imageproc/SavGolKernel.cpp +++ b/imageproc/SavGolKernel.cpp @@ -16,7 +16,7 @@ along with this program. If not, see . */ -#define _ISOC99SOURCE // For copysign() +#define _ISOC99SOURCE // For std::copysign() #include "SavGolKernel.h" #include @@ -106,17 +106,17 @@ void SavGolKernel::QR() { if (a == 0.0) { cos = 0.0; - sin = copysign(1.0, b); - m_equations[jj] = fabs(b); - } else if (fabs(b) > fabs(a)) { + sin = std::copysign(1.0, b); + m_equations[jj] = std::fabs(b); + } else if (std::fabs(b) > std::fabs(a)) { const double t = a / b; - const double u = copysign(sqrt(1.0 + t * t), b); + const double u = std::copysign(std::sqrt(1.0 + t * t), b); sin = 1.0 / u; cos = sin * t; m_equations[jj] = b * u; } else { const double t = b / a; - const double u = copysign(sqrt(1.0 + t * t), a); + const double u = std::copysign(std::sqrt(1.0 + t * t), a); cos = 1.0 / u; sin = cos * t; m_equations[jj] = a * u; diff --git a/imageproc/Shear.cpp b/imageproc/Shear.cpp index b26e2c56a..e0e0206aa 100644 --- a/imageproc/Shear.cpp +++ b/imageproc/Shear.cpp @@ -37,12 +37,12 @@ void hShearFromTo(const BinaryImage& src, const int width = src.width(); const int height = src.height(); - // shift = floor(0.5 + shear * (y + 0.5 - y_origin)); + // shift = std::floor(0.5 + shear * (y + 0.5 - y_origin)); double shift = 0.5 + shear * (0.5 - y_origin); const double shift_end = 0.5 + shear * (height - 0.5 - y_origin); - auto shift1 = (int) floor(shift); + auto shift1 = (int) std::floor(shift); - if (shift1 == floor(shift_end)) { + if (shift1 == std::floor(shift_end)) { assert(shift1 == 0); dst = src; @@ -55,10 +55,10 @@ void hShearFromTo(const BinaryImage& src, for (;;) { ++y2; shift += shear; - shift2 = (int) floor(shift); + shift2 = (int) std::floor(shift); if ((shift1 != shift2) || (y2 == height)) { const int block_height = y2 - y1; - if (abs(shift1) >= width) { + if (std::abs(shift1) >= width) { // The shifted block would be completely off the image. const QRect fr(0, y1, width, block_height); dst.fill(fr, background_color); @@ -108,12 +108,12 @@ void vShearFromTo(const BinaryImage& src, const int width = src.width(); const int height = src.height(); - // shift = floor(0.5 + shear * (x + 0.5 - x_origin)); + // shift = std::floor(0.5 + shear * (x + 0.5 - x_origin)); double shift = 0.5 + shear * (0.5 - x_origin); const double shift_end = 0.5 + shear * (width - 0.5 - x_origin); - auto shift1 = (int) floor(shift); + auto shift1 = (int) std::floor(shift); - if (shift1 == floor(shift_end)) { + if (shift1 == std::floor(shift_end)) { assert(shift1 == 0); dst = src; @@ -126,10 +126,10 @@ void vShearFromTo(const BinaryImage& src, for (;;) { ++x2; shift += shear; - shift2 = (int) floor(shift); + shift2 = (int) std::floor(shift); if ((shift1 != shift2) || (x2 == width)) { const int block_width = x2 - x1; - if (abs(shift1) >= height) { + if (std::abs(shift1) >= height) { // The shifted block would be completely off the image. const QRect fr(x1, 0, block_width, height); dst.fill(fr, background_color); diff --git a/imageproc/SkewFinder.cpp b/imageproc/SkewFinder.cpp index ef4b262c7..a95616aa0 100644 --- a/imageproc/SkewFinder.cpp +++ b/imageproc/SkewFinder.cpp @@ -178,7 +178,7 @@ Skew SkewFinder::findSkew(const BinaryImage& image) const { } // SkewFinder::findSkew double SkewFinder::process(const BinaryImage& src, BinaryImage& dst, const double angle) const { - const double tg = tan(angle * constants::DEG2RAD); + const double tg = std::tan(angle * constants::DEG2RAD); const double x_center = 0.5 * dst.width(); vShearFromTo(src, dst, tg / m_resolutionRatio, x_center, WHITE); diff --git a/imageproc/tests/TestPolygonRasterizer.cpp b/imageproc/tests/TestPolygonRasterizer.cpp index 37c4829d2..12c3763b3 100644 --- a/imageproc/tests/TestPolygonRasterizer.cpp +++ b/imageproc/tests/TestPolygonRasterizer.cpp @@ -49,10 +49,10 @@ static QPolygonF createShape(const QSize& image_size, double radius) { QPolygonF poly; - poly.push_back(center + QPointF(cos(angle), sin(angle)) * radius); + poly.push_back(center + QPointF(std::cos(angle), std::sin(angle)) * radius); for (int i = 1; i < num_steps; ++i) { angle += step * 2; - poly.push_back(center + QPointF(cos(angle), sin(angle)) * radius); + poly.push_back(center + QPointF(std::cos(angle), std::sin(angle)) * radius); } return poly; diff --git a/imageproc/tests/TestScale.cpp b/imageproc/tests/TestScale.cpp index 9f761fbc1..9c398e9b1 100644 --- a/imageproc/tests/TestScale.cpp +++ b/imageproc/tests/TestScale.cpp @@ -49,7 +49,7 @@ static bool fuzzyCompare(const QImage& img1, const QImage& img2) { for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { - if (abs(int(line1[x]) - int(line2[x])) > 1) { + if (std::abs(int(line1[x]) - int(line2[x])) > 1) { return false; } } diff --git a/imageproc/tests/TestSkewFinder.cpp b/imageproc/tests/TestSkewFinder.cpp index 383d45681..7961f655a 100644 --- a/imageproc/tests/TestSkewFinder.cpp +++ b/imageproc/tests/TestSkewFinder.cpp @@ -64,7 +64,7 @@ BOOST_AUTO_TEST_CASE(test_positive_detection) { SkewFinder skew_finder; const Skew skew(skew_finder.findSkew(BinaryImage(image))); - BOOST_REQUIRE(fabs(skew.angle() - 4.5) < 0.15); + BOOST_REQUIRE(std::fabs(skew.angle() - 4.5) < 0.15); BOOST_CHECK(skew.confidence() >= Skew::GOOD_CONFIDENCE); } diff --git a/interaction/DragWatcher.cpp b/interaction/DragWatcher.cpp index 41fe2d2f4..f6ea3bc2f 100644 --- a/interaction/DragWatcher.cpp +++ b/interaction/DragWatcher.cpp @@ -36,7 +36,7 @@ bool DragWatcher::haveSignificantDrag() const { msec_passed += 60 * 60 * 24; } - const double dist_score = sqrt((double) m_dragMaxSqDist) / 12.0; + const double dist_score = std::sqrt((double) m_dragMaxSqDist) / 12.0; const double time_score = msec_passed / 500.0; return dist_score + time_score >= 1.0; diff --git a/interaction/InteractiveXSpline.cpp b/interaction/InteractiveXSpline.cpp index 854082f78..7134862c1 100644 --- a/interaction/InteractiveXSpline.cpp +++ b/interaction/InteractiveXSpline.cpp @@ -184,8 +184,8 @@ double findAngle(QPointF p1, QPointF p2) { // return angle between vector (0,0) p2 -= p1; // get angle with (1,0) - double a = p2.x() / sqrt(p2.x() * p2.x() + p2.y() * p2.y()); - return acos(a) * 180.0 / 3.14159265; + double a = p2.x() / std::sqrt(p2.x() * p2.x() + p2.y() * p2.y()); + return std::acos(a) * 180.0 / 3.14159265; } void InteractiveXSpline::controlPointMoveRequest(int idx, const QPointF& pos, Qt::KeyboardModifiers mask) { diff --git a/interaction/ZoomHandler.cpp b/interaction/ZoomHandler.cpp index bbf6ca20e..3999b554f 100644 --- a/interaction/ZoomHandler.cpp +++ b/interaction/ZoomHandler.cpp @@ -57,7 +57,7 @@ void ZoomHandler::onWheelEvent(QWheelEvent* event, InteractionState& interaction } const double degrees = event->delta() / 8.0; - zoom *= pow(2.0, degrees / 60.0); // 2 times zoom for every 60 degrees + zoom *= std::pow(2.0, degrees / 60.0); // 2 times zoom for every 60 degrees if (zoom < 1.0) { zoom = 1.0; } diff --git a/math/ArcLengthMapper.cpp b/math/ArcLengthMapper.cpp index 575d0d4c4..459e27a0d 100644 --- a/math/ArcLengthMapper.cpp +++ b/math/ArcLengthMapper.cpp @@ -38,7 +38,7 @@ void ArcLengthMapper::addSample(double x, double fx) { const double dx = x - m_samples.back().x; const double dy = fx - m_prevFX; assert(dx > 0); - arc_len = m_samples.back().arcLen + sqrt(dx * dx + dy * dy); + arc_len = m_samples.back().arcLen + std::sqrt(dx * dx + dy * dy); } m_samples.emplace_back(x, arc_len); diff --git a/math/LineIntersectionScalar.cpp b/math/LineIntersectionScalar.cpp index 80d217fa3..be9c21189 100644 --- a/math/LineIntersectionScalar.cpp +++ b/math/LineIntersectionScalar.cpp @@ -34,7 +34,7 @@ bool lineIntersectionScalar(const QLineF& line1, const QLineF& line2, double& s1 // s1 = |b -v2|/|A| // s2 = |v1 b|/|A| const double det_A = v2.x() * v1.y() - v1.x() * v2.y(); - if (fabs(det_A) < std::numeric_limits::epsilon()) { + if (std::fabs(det_A) < std::numeric_limits::epsilon()) { return false; } @@ -62,7 +62,7 @@ bool lineIntersectionScalar(const QLineF& line1, const QLineF& line2, double& s1 // s1 = |b -v2|/|A| // s2 = |v1 b|/|A| const double det_A = v2.x() * v1.y() - v1.x() * v2.y(); - if (fabs(det_A) < std::numeric_limits::epsilon()) { + if (std::fabs(det_A) < std::numeric_limits::epsilon()) { return false; } diff --git a/math/LinearSolver.h b/math/LinearSolver.h index b1b976258..91db43190 100644 --- a/math/LinearSolver.h +++ b/math/LinearSolver.h @@ -78,8 +78,8 @@ class LinearSolver { template void LinearSolver::solve(const T* A, T* X, const T* B, T* tbuffer, size_t* pbuffer) const { - using namespace std; // To catch different overloads of abs() - const T epsilon(sqrt(numeric_limits::epsilon())); + using namespace std; // To catch different overloads of std::abs() + const T epsilon(std::sqrt(numeric_limits::epsilon())); const size_t num_elements_A = m_rowsAB * m_colsArowsX; @@ -101,9 +101,9 @@ void LinearSolver::solve(const T* A, T* X, const T* B, T* tbuffer, size_t* pbuff for (size_t i = 0; i < m_colsArowsX; ++i, p_col += m_rowsAB) { // Find the largest pivot. size_t virt_pivot_row = i; - T largest_abs_pivot(abs(p_col[perm[i]])); + T largest_abs_pivot(std::abs(p_col[perm[i]])); for (size_t j = i + 1; j < m_rowsAB; ++j) { - const T abs_pivot(abs(p_col[perm[j]])); + const T abs_pivot(std::abs(p_col[perm[j]])); if (abs_pivot > largest_abs_pivot) { largest_abs_pivot = abs_pivot; virt_pivot_row = j; @@ -125,7 +125,7 @@ void LinearSolver::solve(const T* A, T* X, const T* B, T* tbuffer, size_t* pbuff for (size_t j = i + 1; j < m_rowsAB; ++j) { const T* p1 = p_pivot; T* p2 = p_col + perm[j]; - if (abs(*p2) <= epsilon) { + if (std::abs(*p2) <= epsilon) { // We consider it's already zero. *p2 = T(); continue; @@ -177,7 +177,7 @@ void LinearSolver::solve(const T* A, T* X, const T* B, T* tbuffer, size_t* pbuff right -= *p_lu * p_y_col[lu_col]; p_lu += m_rowsAB; } - if (abs(right) > epsilon) { + if (std::abs(right) > epsilon) { throw std::runtime_error("LinearSolver: inconsistent overdetermined system"); } } diff --git a/math/PolylineIntersector.cpp b/math/PolylineIntersector.cpp index 9d0066989..5851841bf 100644 --- a/math/PolylineIntersector.cpp +++ b/math/PolylineIntersector.cpp @@ -135,7 +135,7 @@ bool PolylineIntersector::tryIntersectingOutsideOfPolyline(const QLineF& line, const ToLineProjector proj(line); - if (fabs(front_dot) < fabs(back_dot)) { + if (std::fabs(front_dot) < std::fabs(back_dot)) { hint.update(-1); intersection = proj.projectionPoint(m_polyline.front()); } else { diff --git a/math/ToLineProjector.cpp b/math/ToLineProjector.cpp index 097e7c0b0..70625d758 100644 --- a/math/ToLineProjector.cpp +++ b/math/ToLineProjector.cpp @@ -24,7 +24,7 @@ ToLineProjector::ToLineProjector(const QLineF& line) : m_origin(line.p1()), m_ve // At*A*x = At*b const double AtA = m_mat.dot(m_mat); - if (abs(AtA) > numeric_limits::epsilon()) { + if (std::abs(AtA) > numeric_limits::epsilon()) { // x = (At*A)-1 * At m_mat /= AtA; } else { @@ -48,7 +48,7 @@ QPointF ToLineProjector::projectionVector(const QPointF& pt) const { } double ToLineProjector::projectionDist(const QPointF& pt) const { - return sqrt(projectionSqDist(pt)); + return std::sqrt(projectionSqDist(pt)); } double ToLineProjector::projectionSqDist(const QPointF& pt) const { diff --git a/math/XSpline.cpp b/math/XSpline.cpp index e55f3bcff..b198daf0f 100644 --- a/math/XSpline.cpp +++ b/math/XSpline.cpp @@ -91,7 +91,8 @@ struct XSpline::DecomposedDerivs { int numControlPoints; bool hasNonZeroCoeffs(int idx) const { - double sum = fabs(zeroDerivCoeffs[idx]) + fabs(firstDerivCoeffs[idx]) + fabs(secondDerivCoeffs[idx]); + double sum = std::fabs(zeroDerivCoeffs[idx]) + std::fabs(firstDerivCoeffs[idx]) + + std::fabs(secondDerivCoeffs[idx]); return sum > std::numeric_limits::epsilon(); } @@ -157,7 +158,7 @@ QPointF XSpline::pointAt(double t) const { return pointAtImpl(num_segments - 1, 1.0); } else { const double t2 = t * num_segments; - const double segment = floor(t2); + const double segment = std::floor(t2); return pointAtImpl((int) segment, t2 - segment); } @@ -227,7 +228,7 @@ void XSpline::maybeAddMoreSamples(VirtualFunction3 0) @@ -273,7 +274,7 @@ void XSpline::linearCombinationAt(double t, std::vector& coef num_coeffs = linearCombinationFor(static_coeffs, num_segments - 1, 1.0); } else { const double t2 = t * num_segments; - const double segment = floor(t2); + const double segment = std::floor(t2); num_coeffs = linearCombinationFor(static_coeffs, (int) segment, t2 - segment); } @@ -365,7 +366,7 @@ XSpline::DecomposedDerivs XSpline::decomposedDerivs(const double t) const { return decomposedDerivsImpl(num_segments - 1, 1.0); } else { const double t2 = t * num_segments; - const double segment = floor(t2); + const double segment = std::floor(t2); return decomposedDerivsImpl((int) segment, t2 - segment); } @@ -841,7 +842,7 @@ double XSpline::HBlendFunc::secondDerivative(double u) const { double XSpline::PointAndDerivs::signedCurvature() const { const double cross = firstDeriv.x() * secondDeriv.y() - firstDeriv.y() * secondDeriv.x(); - double tlen = sqrt(firstDeriv.x() * firstDeriv.x() + firstDeriv.y() * firstDeriv.y()); + double tlen = std::sqrt(firstDeriv.x() * firstDeriv.x() + firstDeriv.y() * firstDeriv.y()); return cross / (tlen * tlen * tlen); } diff --git a/math/spfit/FrenetFrame.cpp b/math/spfit/FrenetFrame.cpp index 804750e3b..d983db4bc 100644 --- a/math/spfit/FrenetFrame.cpp +++ b/math/spfit/FrenetFrame.cpp @@ -23,7 +23,7 @@ namespace spfit { FrenetFrame::FrenetFrame(const Vec2d& origin, const Vec2d& tangent_vector, YAxisDirection ydir) : m_origin(origin) { const double sqlen = tangent_vector.squaredNorm(); if (sqlen > 1e-6) { - m_unitTangent = tangent_vector / sqrt(sqlen); + m_unitTangent = tangent_vector / std::sqrt(sqlen); if (ydir == Y_POINTS_UP) { m_unitNormal[0] = -m_unitTangent[1]; m_unitNormal[1] = m_unitTangent[0]; diff --git a/math/spfit/LinearForceBalancer.cpp b/math/spfit/LinearForceBalancer.cpp index f3747793a..f3e5b6376 100644 --- a/math/spfit/LinearForceBalancer.cpp +++ b/math/spfit/LinearForceBalancer.cpp @@ -46,7 +46,7 @@ double LinearForceBalancer::calcInternalForceWeight(double internal_force, doubl // (internal * lambda) / external = ratio // internal * lambda = external * ratio double lambda = 0; - if (fabs(internal_force) > 1e-6) { + if (std::fabs(internal_force) > 1e-6) { lambda = m_currentRatio * external_force / internal_force; } diff --git a/math/spfit/SqDistApproximant.cpp b/math/spfit/SqDistApproximant.cpp index ebd6506d3..5b666e46f 100644 --- a/math/spfit/SqDistApproximant.cpp +++ b/math/spfit/SqDistApproximant.cpp @@ -22,9 +22,9 @@ namespace spfit { SqDistApproximant::SqDistApproximant(const Vec2d& origin, const Vec2d& u, const Vec2d& v, double m, double n) { - assert(fabs(u.squaredNorm() - 1.0) < 1e-06 && "u is not normalized"); - assert(fabs(v.squaredNorm() - 1.0) < 1e-06 && "v is not normalized"); - assert(fabs(u.dot(v)) < 1e-06 && "u and v are not orthogonal"); + assert(std::fabs(u.squaredNorm() - 1.0) < 1e-06 && "u is not normalized"); + assert(std::fabs(v.squaredNorm() - 1.0) < 1e-06 && "v is not normalized"); + assert(std::fabs(u.dot(v)) < 1e-06 && "u and v are not orthogonal"); // Consider the following equation: // w = R*x + t @@ -69,7 +69,7 @@ SqDistApproximant SqDistApproximant::weightedLineDistance(const QLineF& line, do Vec2d u(line.p2() - line.p1()); const double sqlen = u.squaredNorm(); if (sqlen > 1e-6) { - u /= sqrt(sqlen); + u /= std::sqrt(sqlen); } else { return pointDistance(line.p1()); } @@ -90,13 +90,13 @@ SqDistApproximant SqDistApproximant::weightedCurveDistance(const Vec2d& referenc const FrenetFrame& frenet_frame, const double signed_curvature, const double weight) { - const double abs_curvature = fabs(signed_curvature); + const double abs_curvature = std::fabs(signed_curvature); double m = 0; if (abs_curvature > std::numeric_limits::epsilon()) { const Vec2d to_reference_point(reference_point - frenet_frame.origin()); const double p = 1.0 / abs_curvature; - const double d = fabs(frenet_frame.unitNormal().dot(to_reference_point)); + const double d = std::fabs(frenet_frame.unitNormal().dot(to_reference_point)); m = d / (d + p); // Formula 7 in [2]. } diff --git a/math/spfit/tests/TestSqDistApproximant.cpp b/math/spfit/tests/TestSqDistApproximant.cpp index e39d8fc3e..0457619b0 100644 --- a/math/spfit/tests/TestSqDistApproximant.cpp +++ b/math/spfit/tests/TestSqDistApproximant.cpp @@ -53,7 +53,7 @@ BOOST_AUTO_TEST_CASE(test_line_distance) { for (int i = 0; i < 100; ++i) { const Vec2d pt1(frand(-50, 50), frand(-50, 50)); const double angle = frand(0, 2.0 * PI); - const Vec2d delta(cos(angle), sin(angle)); + const Vec2d delta(std::cos(angle), std::sin(angle)); const QLineF line(pt1, pt1 + delta); const SqDistApproximant approx(SqDistApproximant::lineDistance(line)); const ToLineProjector proj(line); @@ -69,7 +69,7 @@ BOOST_AUTO_TEST_CASE(test_general_case) { for (int i = 0; i < 100; ++i) { const Vec2d origin(frand(-50, 50), frand(-50, 50)); const double angle = frand(0, 2.0 * PI); - const Vec2d u(cos(angle), sin(angle)); + const Vec2d u(std::cos(angle), std::sin(angle)); Vec2d v(-u[1], u[0]); if (rand() & 1) { v = -v; diff --git a/zones/ZoneVertexDragInteraction.cpp b/zones/ZoneVertexDragInteraction.cpp index 05b5fafca..c68e8b14d 100644 --- a/zones/ZoneVertexDragInteraction.cpp +++ b/zones/ZoneVertexDragInteraction.cpp @@ -118,14 +118,17 @@ void ZoneVertexDragInteraction::onMouseMoveEvent(QMouseEvent* event, Interaction QPointF next = to_screen.map(m_ptrVertex->next(SplineVertex::LOOP)->point()); if (!((current == prev) && (current == next))) { - double prev_angle_cos = abs((prev.x() - current.x()) - / sqrt(pow((prev.y() - current.y()), 2) + pow((prev.x() - current.x()), 2))); - double next_angle_cos = abs((next.x() - current.x()) - / sqrt(pow((next.y() - current.y()), 2) + pow((next.x() - current.x()), 2))); + double prev_angle_cos = std::abs( + (prev.x() - current.x()) + / std::sqrt(std::pow((prev.y() - current.y()), 2) + std::pow((prev.x() - current.x()), 2))); + double next_angle_cos = std::abs( + (next.x() - current.x()) + / std::sqrt(std::pow((next.y() - current.y()), 2) + std::pow((next.x() - current.x()), 2))); - if ((prev_angle_cos < next_angle_cos) || (std::isnan(prev_angle_cos) && (next_angle_cos > (1.0 / sqrt(2)))) - || (std::isnan(next_angle_cos) && (prev_angle_cos < (1.0 / sqrt(2))))) { + if ((prev_angle_cos < next_angle_cos) + || (std::isnan(prev_angle_cos) && (next_angle_cos > (1.0 / std::sqrt(2)))) + || (std::isnan(next_angle_cos) && (prev_angle_cos < (1.0 / std::sqrt(2))))) { prev.setX(current.x()); next.setY(current.y()); } else { From c00a4344d508193dc764e3113eefa72f9793417f Mon Sep 17 00:00:00 2001 From: Alex <4lex49@zoho.com> Date: Tue, 3 Apr 2018 06:15:57 +0300 Subject: [PATCH 03/11] ~ Code refactoring and fixes. Multiple variations of classes are replaced with variadic templates. --- AbstractCommand.h | 27 ++--------- BackgroundExecutor.h | 4 +- BackgroundTask.h | 2 +- ContentSpanFinder.cpp | 2 +- ContentSpanFinder.h | 4 +- DebugImageView.cpp | 4 +- DeviationProvider.h | 2 +- FilterUiInterface.h | 2 +- ImageMetadataLoader.cpp | 4 +- ImageMetadataLoader.h | 10 ++-- ImageViewBase.cpp | 8 ++-- JpegMetadataLoader.cpp | 2 +- JpegMetadataLoader.h | 2 +- LoadFileTask.cpp | 4 +- MainWindow.cpp | 4 +- MainWindow.h | 2 +- PngMetadataLoader.cpp | 2 +- PngMetadataLoader.h | 2 +- ProjectPages.cpp | 2 +- ProjectPages.h | 2 +- ProjectWriter.cpp | 4 +- ProjectWriter.h | 8 ++-- RelinkingDialog.h | 2 +- RelinkingModel.h | 2 +- ThumbnailBase.cpp | 2 +- ThumbnailPixmapCache.h | 2 +- TiffMetadataLoader.cpp | 2 +- TiffMetadataLoader.h | 2 +- TiffReader.cpp | 2 +- TiffReader.h | 2 +- filters/output/DespeckleView.cpp | 4 +- filters/output/PictureZoneEditor.cpp | 8 ++-- foundation/VirtualFunction.h | 68 ++++------------------------ math/XSpline.cpp | 6 +-- math/XSpline.h | 4 +- math/spfit/FittableSpline.h | 2 +- math/spfit/SplineFitter.cpp | 2 +- 37 files changed, 73 insertions(+), 140 deletions(-) diff --git a/AbstractCommand.h b/AbstractCommand.h index 295f9f102..0377e3874 100644 --- a/AbstractCommand.h +++ b/AbstractCommand.h @@ -22,31 +22,12 @@ #include "ref_countable.h" #include "intrusive_ptr.h" -template -class AbstractCommand0 : public ref_countable { +template +class AbstractCommand : public ref_countable { public: - typedef intrusive_ptr Ptr; + typedef intrusive_ptr Ptr; - virtual R operator()() = 0; + virtual Res operator()(ArgTypes... args) = 0; }; - -template -class AbstractCommand1 : public ref_countable { -public: - typedef intrusive_ptr Ptr; - - virtual R operator()(A1 arg1) = 0; -}; - - -template -class AbstractCommand2 : public ref_countable { -public: - typedef intrusive_ptr Ptr; - - virtual R operator()(T1 arg1, T2 arg2) = 0; -}; - - #endif // ifndef ABSTRACTCOMMAND_H_ diff --git a/BackgroundExecutor.h b/BackgroundExecutor.h index a61f0bcc1..0e0dca3d2 100644 --- a/BackgroundExecutor.h +++ b/BackgroundExecutor.h @@ -29,8 +29,8 @@ class BackgroundExecutor { DECLARE_NON_COPYABLE(BackgroundExecutor) public: - typedef intrusive_ptr> TaskResultPtr; - typedef intrusive_ptr> TaskPtr; + typedef intrusive_ptr> TaskResultPtr; + typedef intrusive_ptr> TaskPtr; BackgroundExecutor(); diff --git a/BackgroundTask.h b/BackgroundTask.h index 557f8289d..41ebf071e 100644 --- a/BackgroundTask.h +++ b/BackgroundTask.h @@ -26,7 +26,7 @@ #include #include -class BackgroundTask : public AbstractCommand0, public TaskStatus { +class BackgroundTask : public AbstractCommand, public TaskStatus { public: enum Type { INTERACTIVE, BATCH }; diff --git a/ContentSpanFinder.cpp b/ContentSpanFinder.cpp index c0036092e..1224d2173 100644 --- a/ContentSpanFinder.cpp +++ b/ContentSpanFinder.cpp @@ -21,7 +21,7 @@ using namespace imageproc; -void ContentSpanFinder::findImpl(const SlicedHistogram& histogram, VirtualFunction1& handler) const { +void ContentSpanFinder::findImpl(const SlicedHistogram& histogram, VirtualFunction& handler) const { const auto hist_size = static_cast(histogram.size()); int i = 0; diff --git a/ContentSpanFinder.h b/ContentSpanFinder.h index 07942c0c5..17d1b7b4d 100644 --- a/ContentSpanFinder.h +++ b/ContentSpanFinder.h @@ -51,7 +51,7 @@ class ContentSpanFinder { void find(const imageproc::SlicedHistogram& histogram, T handler) const; private: - void findImpl(const imageproc::SlicedHistogram& histogram, VirtualFunction1& handler) const; + void findImpl(const imageproc::SlicedHistogram& histogram, VirtualFunction& handler) const; int m_minContentWidth; int m_minWhitespaceWidth; @@ -60,7 +60,7 @@ class ContentSpanFinder { template void ContentSpanFinder::find(const imageproc::SlicedHistogram& histogram, T handler) const { - ProxyFunction1 proxy(handler); + ProxyFunction proxy(handler); findImpl(histogram, proxy); } diff --git a/DebugImageView.cpp b/DebugImageView.cpp index 8b9138467..9b30da914 100644 --- a/DebugImageView.cpp +++ b/DebugImageView.cpp @@ -25,7 +25,7 @@ #include #include -class DebugImageView::ImageLoadResult : public AbstractCommand0 { +class DebugImageView::ImageLoadResult : public AbstractCommand { public: ImageLoadResult(QPointer owner, const QImage& image) : m_ptrOwner(std::move(owner)), m_image(image) { @@ -44,7 +44,7 @@ class DebugImageView::ImageLoadResult : public AbstractCommand0 { }; -class DebugImageView::ImageLoader : public AbstractCommand0 { +class DebugImageView::ImageLoader : public AbstractCommand { public: ImageLoader(DebugImageView* owner, const QString& file_path) : m_ptrOwner(owner), m_filePath(file_path) { } diff --git a/DeviationProvider.h b/DeviationProvider.h index 17835a685..c2fe18557 100644 --- a/DeviationProvider.h +++ b/DeviationProvider.h @@ -129,7 +129,7 @@ void DeviationProvider::update() const { template void DeviationProvider::setComputeValueByKey(const std::function& computeValueByKey) { - DeviationProvider::computeValueByKey = computeValueByKey; + this->computeValueByKey = std::move(computeValueByKey); } template diff --git a/FilterUiInterface.h b/FilterUiInterface.h index a6b270bef..80432667c 100644 --- a/FilterUiInterface.h +++ b/FilterUiInterface.h @@ -51,7 +51,7 @@ class FilterUiInterface { /** * Returns a callable object that when called will open a relinking dialog. */ - virtual intrusive_ptr> relinkingDialogRequester() = 0; + virtual intrusive_ptr> relinkingDialogRequester() = 0; }; diff --git a/ImageMetadataLoader.cpp b/ImageMetadataLoader.cpp index c9a9a20e3..2a603eff4 100644 --- a/ImageMetadataLoader.cpp +++ b/ImageMetadataLoader.cpp @@ -29,7 +29,7 @@ void ImageMetadataLoader::registerLoader(intrusive_ptr load } ImageMetadataLoader::Status ImageMetadataLoader::loadImpl(QIODevice& io_device, - VirtualFunction1& out) { + VirtualFunction& out) { auto it(m_sLoaders.begin()); const auto end(m_sLoaders.end()); for (; it != end; ++it) { @@ -43,7 +43,7 @@ ImageMetadataLoader::Status ImageMetadataLoader::loadImpl(QIODevice& io_device, } ImageMetadataLoader::Status ImageMetadataLoader::loadImpl(const QString& file_path, - VirtualFunction1& out) { + VirtualFunction& out) { QFile file(file_path); if (!file.open(QIODevice::ReadOnly)) { return GENERIC_ERROR; diff --git a/ImageMetadataLoader.h b/ImageMetadataLoader.h index 7e1a21255..5a8ce8f70 100644 --- a/ImageMetadataLoader.h +++ b/ImageMetadataLoader.h @@ -67,12 +67,12 @@ class ImageMetadataLoader : public ref_countable { * the image metadata. If there are multiple images (pages) in * the file, this object will be called multiple times. */ - virtual Status loadMetadata(QIODevice& io_device, VirtualFunction1& out) = 0; + virtual Status loadMetadata(QIODevice& io_device, VirtualFunction& out) = 0; private: - static Status loadImpl(QIODevice& io_device, VirtualFunction1& out); + static Status loadImpl(QIODevice& io_device, VirtualFunction& out); - static Status loadImpl(const QString& file_path, VirtualFunction1& out); + static Status loadImpl(const QString& file_path, VirtualFunction& out); typedef std::vector> LoaderList; static LoaderList m_sLoaders; @@ -81,14 +81,14 @@ class ImageMetadataLoader : public ref_countable { template ImageMetadataLoader::Status ImageMetadataLoader::load(QIODevice& io_device, OutFunc out) { - ProxyFunction1 proxy(out); + ProxyFunction proxy(out); return loadImpl(io_device, proxy); } template ImageMetadataLoader::Status ImageMetadataLoader::load(const QString& file_path, OutFunc out) { - ProxyFunction1 proxy(out); + ProxyFunction proxy(out); return loadImpl(file_path, proxy); } diff --git a/ImageViewBase.cpp b/ImageViewBase.cpp index e16628d94..ca720cd2f 100644 --- a/ImageViewBase.cpp +++ b/ImageViewBase.cpp @@ -40,7 +40,7 @@ using namespace imageproc; -class ImageViewBase::HqTransformTask : public AbstractCommand0>>, public QObject { +class ImageViewBase::HqTransformTask : public AbstractCommand>>, public QObject { DECLARE_NON_COPYABLE(HqTransformTask) public: @@ -54,10 +54,10 @@ class ImageViewBase::HqTransformTask : public AbstractCommand0isCancelled(); } - intrusive_ptr> operator()() override; + intrusive_ptr> operator()() override; private: - class Result : public AbstractCommand0 { + class Result : public AbstractCommand { public: explicit Result(ImageViewBase* image_view); @@ -1019,7 +1019,7 @@ ImageViewBase::HqTransformTask::HqTransformTask(ImageViewBase* image_view, : m_ptrResult(new Result(image_view)), m_image(image), m_xform(xform), m_targetSize(target_size) { } -intrusive_ptr> ImageViewBase::HqTransformTask::operator()() { +intrusive_ptr> ImageViewBase::HqTransformTask::operator()() { if (isCancelled()) { return nullptr; } diff --git a/JpegMetadataLoader.cpp b/JpegMetadataLoader.cpp index 3b6d4c1f8..f4e7b7abe 100644 --- a/JpegMetadataLoader.cpp +++ b/JpegMetadataLoader.cpp @@ -195,7 +195,7 @@ void JpegMetadataLoader::registerMyself() { } ImageMetadataLoader::Status JpegMetadataLoader::loadMetadata(QIODevice& io_device, - VirtualFunction1& out) { + VirtualFunction& out) { if (!io_device.isReadable()) { return GENERIC_ERROR; } diff --git a/JpegMetadataLoader.h b/JpegMetadataLoader.h index 548321e44..bf3461871 100644 --- a/JpegMetadataLoader.h +++ b/JpegMetadataLoader.h @@ -37,7 +37,7 @@ class JpegMetadataLoader : public ImageMetadataLoader { static void registerMyself(); protected: - Status loadMetadata(QIODevice& io_device, VirtualFunction1& out) override; + Status loadMetadata(QIODevice& io_device, VirtualFunction& out) override; }; diff --git a/LoadFileTask.cpp b/LoadFileTask.cpp index 88f7c119b..cd43f7e80 100644 --- a/LoadFileTask.cpp +++ b/LoadFileTask.cpp @@ -118,7 +118,7 @@ LoadFileTask::ErrorResult::ErrorResult(const QString& file_path) void LoadFileTask::ErrorResult::updateUI(FilterUiInterface* ui) { class ErrWidget : public ErrorWidget { public: - ErrWidget(intrusive_ptr> relinking_dialog_requester, + ErrWidget(intrusive_ptr> relinking_dialog_requester, const QString& text, Qt::TextFormat fmt = Qt::AutoText) : ErrorWidget(text, fmt), m_ptrRelinkingDialogRequester(std::move(relinking_dialog_requester)) { @@ -129,7 +129,7 @@ void LoadFileTask::ErrorResult::updateUI(FilterUiInterface* ui) { (*m_ptrRelinkingDialogRequester)(); } - intrusive_ptr> m_ptrRelinkingDialogRequester; + intrusive_ptr> m_ptrRelinkingDialogRequester; }; diff --git a/MainWindow.cpp b/MainWindow.cpp index 17e58e14a..916a1b107 100644 --- a/MainWindow.cpp +++ b/MainWindow.cpp @@ -710,8 +710,8 @@ void MainWindow::invalidateAllThumbnails() { m_ptrThumbSequence->invalidateAllThumbnails(); } -intrusive_ptr> MainWindow::relinkingDialogRequester() { - class Requester : public AbstractCommand0 { +intrusive_ptr> MainWindow::relinkingDialogRequester() { + class Requester : public AbstractCommand { public: Requester(MainWindow* wnd) : m_ptrWnd(wnd) { } diff --git a/MainWindow.h b/MainWindow.h index 08a10887a..39756e831 100644 --- a/MainWindow.h +++ b/MainWindow.h @@ -208,7 +208,7 @@ private slots: DebugImages* debug_images = nullptr, bool clear_image_widget = true) override; - intrusive_ptr> relinkingDialogRequester() override; + intrusive_ptr> relinkingDialogRequester() override; void switchToNewProject(const intrusive_ptr& pages, const QString& out_dir, diff --git a/PngMetadataLoader.cpp b/PngMetadataLoader.cpp index 6f4ddeaf5..4f148e9b1 100644 --- a/PngMetadataLoader.cpp +++ b/PngMetadataLoader.cpp @@ -84,7 +84,7 @@ void PngMetadataLoader::registerMyself() { } ImageMetadataLoader::Status PngMetadataLoader::loadMetadata(QIODevice& io_device, - VirtualFunction1& out) { + VirtualFunction& out) { if (!io_device.isReadable()) { return GENERIC_ERROR; } diff --git a/PngMetadataLoader.h b/PngMetadataLoader.h index a31ef15c0..b75b5cf8c 100644 --- a/PngMetadataLoader.h +++ b/PngMetadataLoader.h @@ -37,7 +37,7 @@ class PngMetadataLoader : public ImageMetadataLoader { static void registerMyself(); protected: - Status loadMetadata(QIODevice& io_device, VirtualFunction1& out) override; + Status loadMetadata(QIODevice& io_device, VirtualFunction& out) override; }; diff --git a/ProjectPages.cpp b/ProjectPages.cpp index 4dcdb4ed9..fc5ba8ccb 100644 --- a/ProjectPages.cpp +++ b/ProjectPages.cpp @@ -128,7 +128,7 @@ PageSequence ProjectPages::toPageSequence(const PageView view) const { return pages; } // ProjectPages::toPageSequence -void ProjectPages::listRelinkablePaths(VirtualFunction1& sink) const { +void ProjectPages::listRelinkablePaths(VirtualFunction& sink) const { // It's generally a bad idea to do callbacks while holding an internal mutex, // so we accumulate results into this vector first. std::vector files; diff --git a/ProjectPages.h b/ProjectPages.h index 4a5bab92c..be483acb4 100644 --- a/ProjectPages.h +++ b/ProjectPages.h @@ -65,7 +65,7 @@ class ProjectPages : public QObject, public ref_countable { PageSequence toPageSequence(PageView view) const; - void listRelinkablePaths(VirtualFunction1& sink) const; + void listRelinkablePaths(VirtualFunction& sink) const; /** * \note It's up to the caller to make sure different paths aren't collapsed into one. diff --git a/ProjectWriter.cpp b/ProjectWriter.cpp index 553ec73f5..fcf136d59 100644 --- a/ProjectWriter.cpp +++ b/ProjectWriter.cpp @@ -242,13 +242,13 @@ int ProjectWriter::pageId(const PageId& page_id) const { return it->numericId; } -void ProjectWriter::enumImagesImpl(VirtualFunction2& out) const { +void ProjectWriter::enumImagesImpl(VirtualFunction& out) const { for (const Image& image : m_images.get()) { out(image.id, image.numericId); } } -void ProjectWriter::enumPagesImpl(VirtualFunction2& out) const { +void ProjectWriter::enumPagesImpl(VirtualFunction& out) const { for (const Page& page : m_pages.get()) { out(page.id, page.numericId); } diff --git a/ProjectWriter.h b/ProjectWriter.h index 538c454d1..a6232b12b 100644 --- a/ProjectWriter.h +++ b/ProjectWriter.h @@ -154,9 +154,9 @@ class ProjectWriter { int pageId(const PageId& page_id) const; - void enumImagesImpl(VirtualFunction2& out) const; + void enumImagesImpl(VirtualFunction& out) const; - void enumPagesImpl(VirtualFunction2& out) const; + void enumPagesImpl(VirtualFunction& out) const; PageSequence m_pageSequence; OutputFileNameGenerator m_outFileNameGen; @@ -172,13 +172,13 @@ class ProjectWriter { template void ProjectWriter::enumImages(OutFunc out) const { - ProxyFunction2 proxy(out); + ProxyFunction proxy(out); enumImagesImpl(proxy); } template void ProjectWriter::enumPages(OutFunc out) const { - ProxyFunction2 proxy(out); + ProxyFunction proxy(out); enumPagesImpl(proxy); } diff --git a/RelinkingDialog.h b/RelinkingDialog.h index c759cfb4b..5e954c5d1 100644 --- a/RelinkingDialog.h +++ b/RelinkingDialog.h @@ -36,7 +36,7 @@ class RelinkingDialog : public QDialog { public: explicit RelinkingDialog(const QString& project_file_path, QWidget* parent = nullptr); - VirtualFunction1& pathCollector() { + VirtualFunction& pathCollector() { return m_model; } diff --git a/RelinkingModel.h b/RelinkingModel.h index 7b82c65ae..b47b4ca6f 100644 --- a/RelinkingModel.h +++ b/RelinkingModel.h @@ -36,7 +36,7 @@ #include #include -class RelinkingModel : public QAbstractListModel, public VirtualFunction1 { +class RelinkingModel : public QAbstractListModel, public VirtualFunction { DECLARE_NON_COPYABLE(RelinkingModel) public: diff --git a/ThumbnailBase.cpp b/ThumbnailBase.cpp index d74e5d173..ad5e81159 100644 --- a/ThumbnailBase.cpp +++ b/ThumbnailBase.cpp @@ -29,7 +29,7 @@ using namespace imageproc; -class ThumbnailBase::LoadCompletionHandler : public AbstractCommand1 { +class ThumbnailBase::LoadCompletionHandler : public AbstractCommand { DECLARE_NON_COPYABLE(LoadCompletionHandler) public: diff --git a/ThumbnailPixmapCache.h b/ThumbnailPixmapCache.h index c9d702ade..5cb3a56d5 100644 --- a/ThumbnailPixmapCache.h +++ b/ThumbnailPixmapCache.h @@ -38,7 +38,7 @@ class ThumbnailPixmapCache : public ref_countable { public: enum Status { LOADED, LOAD_FAILED, QUEUED }; - typedef AbstractCommand1 CompletionHandler; + typedef AbstractCommand CompletionHandler; /** * \brief Constructor. To be called from the GUI thread only. diff --git a/TiffMetadataLoader.cpp b/TiffMetadataLoader.cpp index ecef5c7fe..d7af74440 100644 --- a/TiffMetadataLoader.cpp +++ b/TiffMetadataLoader.cpp @@ -28,6 +28,6 @@ void TiffMetadataLoader::registerMyself() { } ImageMetadataLoader::Status TiffMetadataLoader::loadMetadata(QIODevice& io_device, - VirtualFunction1& out) { + VirtualFunction& out) { return TiffReader::readMetadata(io_device, out); } diff --git a/TiffMetadataLoader.h b/TiffMetadataLoader.h index 7ff80c6e0..a4f2e049a 100644 --- a/TiffMetadataLoader.h +++ b/TiffMetadataLoader.h @@ -37,7 +37,7 @@ class TiffMetadataLoader : public ImageMetadataLoader { static void registerMyself(); protected: - Status loadMetadata(QIODevice& io_device, VirtualFunction1& out) override; + Status loadMetadata(QIODevice& io_device, VirtualFunction& out) override; }; diff --git a/TiffReader.cpp b/TiffReader.cpp index a2ba5b99c..c667d0796 100644 --- a/TiffReader.cpp +++ b/TiffReader.cpp @@ -237,7 +237,7 @@ bool TiffReader::canRead(QIODevice& device) { } ImageMetadataLoader::Status TiffReader::readMetadata(QIODevice& device, - VirtualFunction1& out) { + VirtualFunction& out) { if (!device.isReadable()) { return ImageMetadataLoader::GENERIC_ERROR; } diff --git a/TiffReader.h b/TiffReader.h index 4de0dd6e8..97641e84e 100644 --- a/TiffReader.h +++ b/TiffReader.h @@ -32,7 +32,7 @@ class TiffReader { static bool canRead(QIODevice& device); static ImageMetadataLoader::Status readMetadata(QIODevice& device, - VirtualFunction1& out); + VirtualFunction& out); /** * \brief Reads the image from io device to QImage. diff --git a/filters/output/DespeckleView.cpp b/filters/output/DespeckleView.cpp index 4310e371a..33f00d4f5 100644 --- a/filters/output/DespeckleView.cpp +++ b/filters/output/DespeckleView.cpp @@ -56,7 +56,7 @@ class DespeckleView::TaskCancelHandle : public TaskStatus, public ref_countable }; -class DespeckleView::DespeckleTask : public AbstractCommand0 { +class DespeckleView::DespeckleTask : public AbstractCommand { public: DespeckleTask(DespeckleView* owner, const DespeckleState& despeckle_state, @@ -75,7 +75,7 @@ class DespeckleView::DespeckleTask : public AbstractCommand0 { +class DespeckleView::DespeckleResult : public AbstractCommand { public: DespeckleResult(QPointer owner, intrusive_ptr cancel_handle, diff --git a/filters/output/PictureZoneEditor.cpp b/filters/output/PictureZoneEditor.cpp index c074c4922..bb0ce5f6a 100644 --- a/filters/output/PictureZoneEditor.cpp +++ b/filters/output/PictureZoneEditor.cpp @@ -39,7 +39,7 @@ static const QRgb mask_color = 0xff587ff4; using namespace imageproc; -class PictureZoneEditor::MaskTransformTask : public AbstractCommand0>>, +class PictureZoneEditor::MaskTransformTask : public AbstractCommand>>, public QObject { DECLARE_NON_COPYABLE(MaskTransformTask) @@ -57,10 +57,10 @@ class PictureZoneEditor::MaskTransformTask : public AbstractCommand0isCancelled(); } - intrusive_ptr> operator()() override; + intrusive_ptr> operator()() override; private: - class Result : public AbstractCommand0 { + class Result : public AbstractCommand { public: explicit Result(PictureZoneEditor* zone_editor); @@ -306,7 +306,7 @@ PictureZoneEditor::MaskTransformTask::MaskTransformTask(PictureZoneEditor* zone_ : m_ptrResult(new Result(zone_editor)), m_origMask(mask), m_xform(xform), m_targetSize(target_size) { } -intrusive_ptr> PictureZoneEditor::MaskTransformTask::operator()() { +intrusive_ptr> PictureZoneEditor::MaskTransformTask::operator()() { if (isCancelled()) { return nullptr; } diff --git a/foundation/VirtualFunction.h b/foundation/VirtualFunction.h index 256dc6c11..f230284c8 100644 --- a/foundation/VirtualFunction.h +++ b/foundation/VirtualFunction.h @@ -19,74 +19,26 @@ #ifndef VIRTUALFUNCTION_H_ #define VIRTUALFUNCTION_H_ -template -class VirtualFunction1 { -public: - virtual ~VirtualFunction1() { - } - - virtual R operator()(A1 arg1) = 0; -}; - - -template -class ProxyFunction1 : public VirtualFunction1 { -public: - explicit ProxyFunction1(Delegate delegate) : m_delegate(delegate) { - } - - virtual R operator()(A1 arg1) { - return m_delegate(arg1); - } - -private: - Delegate m_delegate; -}; - - -template -class VirtualFunction2 { -public: - virtual ~VirtualFunction2() { - } - - virtual R operator()(A1 arg1, A2 arg2) = 0; -}; - - -template -class ProxyFunction2 : public VirtualFunction2 { -public: - explicit ProxyFunction2(Delegate delegate) : m_delegate(delegate) { - } - - virtual R operator()(A1 arg1, A2 arg2) { - return m_delegate(arg1, arg2); - } - -private: - Delegate m_delegate; -}; - +#include -template -class VirtualFunction3 { +template +class VirtualFunction { public: - virtual ~VirtualFunction3() { + virtual ~VirtualFunction() { } - virtual R operator()(A1 arg1, A2 arg2, A3 arg3) = 0; + virtual Res operator()(ArgTypes... args) = 0; }; -template -class ProxyFunction3 : public VirtualFunction3 { +template +class ProxyFunction : public VirtualFunction { public: - explicit ProxyFunction3(Delegate delegate) : m_delegate(delegate) { + explicit ProxyFunction(Delegate delegate) : m_delegate(delegate) { } - virtual R operator()(A1 arg1, A2 arg2, A3 arg3) { - return m_delegate(arg1, arg2, arg3); + Res operator()(ArgTypes... args) override { + return m_delegate(args...); } private: diff --git a/math/XSpline.cpp b/math/XSpline.cpp index b198daf0f..ba03f22dd 100644 --- a/math/XSpline.cpp +++ b/math/XSpline.cpp @@ -177,7 +177,7 @@ QPointF XSpline::pointAtImpl(int segment, double t) const { return pt; } -void XSpline::sample(VirtualFunction3& sink, +void XSpline::sample(VirtualFunction& sink, const SamplingParams& params, double from_t, double to_t) const { @@ -211,7 +211,7 @@ void XSpline::sample(VirtualFunction3& sink, sink(to_pt, to_t, TAIL_SAMPLE); } // XSpline::sample -void XSpline::maybeAddMoreSamples(VirtualFunction3& sink, +void XSpline::maybeAddMoreSamples(VirtualFunction& sink, double max_sqdist_to_spline, double max_sqdist_between_samples, double num_segments, @@ -702,7 +702,7 @@ QPointF XSpline::pointClosestTo(const QPointF to, double accuracy) const { } std::vector XSpline::toPolyline(const SamplingParams& params, double from_t, double to_t) const { - struct Sink : public VirtualFunction3 { + struct Sink : public VirtualFunction { std::vector polyline; void operator()(QPointF pt, double, SampleFlags) override { diff --git a/math/XSpline.h b/math/XSpline.h index 16e8f1af2..499f7f355 100644 --- a/math/XSpline.h +++ b/math/XSpline.h @@ -162,7 +162,7 @@ class XSpline : public spfit::FittableSpline { QPointF pointClosestTo(QPointF to, double accuracy = 0.2) const; /** \see spfit::FittableSpline::sample() */ - void sample(VirtualFunction3& sink, + void sample(VirtualFunction& sink, const SamplingParams& params = SamplingParams(), double from_t = 0.0, double to_t = 1.0) const override; @@ -207,7 +207,7 @@ class XSpline : public spfit::FittableSpline { DecomposedDerivs decomposedDerivsImpl(int segment, double t) const; - void maybeAddMoreSamples(VirtualFunction3& sink, + void maybeAddMoreSamples(VirtualFunction& sink, double max_sqdist_to_spline, double max_sqdist_between_samples, double num_segments, diff --git a/math/spfit/FittableSpline.h b/math/spfit/FittableSpline.h index f506fa29a..09c5ab9dd 100644 --- a/math/spfit/FittableSpline.h +++ b/math/spfit/FittableSpline.h @@ -107,7 +107,7 @@ class FittableSpline { * corresponding to them will be marked with HEAD_SAMPLE * and TAIL_SAMPLE respectably. */ - virtual void sample(VirtualFunction3& sink, + virtual void sample(VirtualFunction& sink, const SamplingParams& params, double from_t = 0.0, double to_t = 1.0) const = 0; diff --git a/math/spfit/SplineFitter.cpp b/math/spfit/SplineFitter.cpp index e624417e9..d3b7cf95e 100644 --- a/math/spfit/SplineFitter.cpp +++ b/math/spfit/SplineFitter.cpp @@ -110,7 +110,7 @@ void SplineFitter::addAttractionForce(const Vec2d& spline_point, } // SplineFitter::addAttractionForce void SplineFitter::addAttractionForces(const ModelShape& model_shape, double from_t, double to_t) { - class SampleProcessor : public VirtualFunction3 { + class SampleProcessor : public VirtualFunction { public: SampleProcessor(SplineFitter& owner, const ModelShape& model_shape) : m_rOwner(owner), m_rModelShape(model_shape) { From 6523f771ec6edd643e589044fcec5c3911836489 Mon Sep 17 00:00:00 2001 From: Alex <4lex49@zoho.com> Date: Wed, 4 Apr 2018 02:30:10 +0300 Subject: [PATCH 04/11] ~ Code refactoring and fixes. * The changes relate to VirtualFunction. --- ContentSpanFinder.cpp | 3 ++- ContentSpanFinder.h | 9 ++++----- ImageMetadataLoader.cpp | 4 ++-- ImageMetadataLoader.h | 22 +++++++++------------- JpegMetadataLoader.cpp | 2 +- JpegMetadataLoader.h | 2 +- PngMetadataLoader.cpp | 2 +- PngMetadataLoader.h | 2 +- ProjectPages.cpp | 2 +- ProjectPages.h | 2 +- ProjectWriter.cpp | 4 ++-- ProjectWriter.h | 18 ++++++++---------- RelinkingDialog.h | 4 ++-- RelinkingModel.h | 4 ++-- TiffMetadataLoader.cpp | 2 +- TiffMetadataLoader.h | 2 +- TiffReader.cpp | 2 +- TiffReader.h | 2 +- foundation/VirtualFunction.h | 4 ++-- math/XSpline.cpp | 18 ++++++------------ math/XSpline.h | 4 ++-- math/spfit/FittableSpline.h | 2 +- math/spfit/SplineFitter.cpp | 26 ++++++++------------------ 23 files changed, 60 insertions(+), 82 deletions(-) diff --git a/ContentSpanFinder.cpp b/ContentSpanFinder.cpp index 1224d2173..c5b22e7b1 100644 --- a/ContentSpanFinder.cpp +++ b/ContentSpanFinder.cpp @@ -21,7 +21,8 @@ using namespace imageproc; -void ContentSpanFinder::findImpl(const SlicedHistogram& histogram, VirtualFunction& handler) const { +void ContentSpanFinder::findImpl(const SlicedHistogram& histogram, + const VirtualFunction& handler) const { const auto hist_size = static_cast(histogram.size()); int i = 0; diff --git a/ContentSpanFinder.h b/ContentSpanFinder.h index 17d1b7b4d..b2f06268a 100644 --- a/ContentSpanFinder.h +++ b/ContentSpanFinder.h @@ -51,17 +51,16 @@ class ContentSpanFinder { void find(const imageproc::SlicedHistogram& histogram, T handler) const; private: - void findImpl(const imageproc::SlicedHistogram& histogram, VirtualFunction& handler) const; + void findImpl(const imageproc::SlicedHistogram& histogram, const VirtualFunction& handler) const; int m_minContentWidth; int m_minWhitespaceWidth; }; -template -void ContentSpanFinder::find(const imageproc::SlicedHistogram& histogram, T handler) const { - ProxyFunction proxy(handler); - findImpl(histogram, proxy); +template +void ContentSpanFinder::find(const imageproc::SlicedHistogram& histogram, Callable handler) const { + findImpl(histogram, ProxyFunction(handler)); } #endif // ifndef CONTENTSPANFINDER_H_ diff --git a/ImageMetadataLoader.cpp b/ImageMetadataLoader.cpp index 2a603eff4..e99937076 100644 --- a/ImageMetadataLoader.cpp +++ b/ImageMetadataLoader.cpp @@ -29,7 +29,7 @@ void ImageMetadataLoader::registerLoader(intrusive_ptr load } ImageMetadataLoader::Status ImageMetadataLoader::loadImpl(QIODevice& io_device, - VirtualFunction& out) { + const VirtualFunction& out) { auto it(m_sLoaders.begin()); const auto end(m_sLoaders.end()); for (; it != end; ++it) { @@ -43,7 +43,7 @@ ImageMetadataLoader::Status ImageMetadataLoader::loadImpl(QIODevice& io_device, } ImageMetadataLoader::Status ImageMetadataLoader::loadImpl(const QString& file_path, - VirtualFunction& out) { + const VirtualFunction& out) { QFile file(file_path); if (!file.open(QIODevice::ReadOnly)) { return GENERIC_ERROR; diff --git a/ImageMetadataLoader.h b/ImageMetadataLoader.h index 5a8ce8f70..e6edb087b 100644 --- a/ImageMetadataLoader.h +++ b/ImageMetadataLoader.h @@ -67,30 +67,26 @@ class ImageMetadataLoader : public ref_countable { * the image metadata. If there are multiple images (pages) in * the file, this object will be called multiple times. */ - virtual Status loadMetadata(QIODevice& io_device, VirtualFunction& out) = 0; + virtual Status loadMetadata(QIODevice& io_device, const VirtualFunction& out) = 0; private: - static Status loadImpl(QIODevice& io_device, VirtualFunction& out); + static Status loadImpl(QIODevice& io_device, const VirtualFunction& out); - static Status loadImpl(const QString& file_path, VirtualFunction& out); + static Status loadImpl(const QString& file_path, const VirtualFunction& out); typedef std::vector> LoaderList; static LoaderList m_sLoaders; }; -template -ImageMetadataLoader::Status ImageMetadataLoader::load(QIODevice& io_device, OutFunc out) { - ProxyFunction proxy(out); - - return loadImpl(io_device, proxy); +template +ImageMetadataLoader::Status ImageMetadataLoader::load(QIODevice& io_device, Callable out) { + return loadImpl(io_device, ProxyFunction(out)); } -template -ImageMetadataLoader::Status ImageMetadataLoader::load(const QString& file_path, OutFunc out) { - ProxyFunction proxy(out); - - return loadImpl(file_path, proxy); +template +ImageMetadataLoader::Status ImageMetadataLoader::load(const QString& file_path, Callable out) { + return loadImpl(file_path, ProxyFunction(out)); } #endif // ifndef IMAGEMETADATALOADER_H_ diff --git a/JpegMetadataLoader.cpp b/JpegMetadataLoader.cpp index f4e7b7abe..bd2301723 100644 --- a/JpegMetadataLoader.cpp +++ b/JpegMetadataLoader.cpp @@ -195,7 +195,7 @@ void JpegMetadataLoader::registerMyself() { } ImageMetadataLoader::Status JpegMetadataLoader::loadMetadata(QIODevice& io_device, - VirtualFunction& out) { + const VirtualFunction& out) { if (!io_device.isReadable()) { return GENERIC_ERROR; } diff --git a/JpegMetadataLoader.h b/JpegMetadataLoader.h index bf3461871..569690dba 100644 --- a/JpegMetadataLoader.h +++ b/JpegMetadataLoader.h @@ -37,7 +37,7 @@ class JpegMetadataLoader : public ImageMetadataLoader { static void registerMyself(); protected: - Status loadMetadata(QIODevice& io_device, VirtualFunction& out) override; + Status loadMetadata(QIODevice& io_device, const VirtualFunction& out) override; }; diff --git a/PngMetadataLoader.cpp b/PngMetadataLoader.cpp index 4f148e9b1..dc8bf61d9 100644 --- a/PngMetadataLoader.cpp +++ b/PngMetadataLoader.cpp @@ -84,7 +84,7 @@ void PngMetadataLoader::registerMyself() { } ImageMetadataLoader::Status PngMetadataLoader::loadMetadata(QIODevice& io_device, - VirtualFunction& out) { + const VirtualFunction& out) { if (!io_device.isReadable()) { return GENERIC_ERROR; } diff --git a/PngMetadataLoader.h b/PngMetadataLoader.h index b75b5cf8c..1413c92f2 100644 --- a/PngMetadataLoader.h +++ b/PngMetadataLoader.h @@ -37,7 +37,7 @@ class PngMetadataLoader : public ImageMetadataLoader { static void registerMyself(); protected: - Status loadMetadata(QIODevice& io_device, VirtualFunction& out) override; + Status loadMetadata(QIODevice& io_device, const VirtualFunction& out) override; }; diff --git a/ProjectPages.cpp b/ProjectPages.cpp index fc5ba8ccb..fca0182f6 100644 --- a/ProjectPages.cpp +++ b/ProjectPages.cpp @@ -128,7 +128,7 @@ PageSequence ProjectPages::toPageSequence(const PageView view) const { return pages; } // ProjectPages::toPageSequence -void ProjectPages::listRelinkablePaths(VirtualFunction& sink) const { +void ProjectPages::listRelinkablePaths(const VirtualFunction& sink) const { // It's generally a bad idea to do callbacks while holding an internal mutex, // so we accumulate results into this vector first. std::vector files; diff --git a/ProjectPages.h b/ProjectPages.h index be483acb4..ca4c04c80 100644 --- a/ProjectPages.h +++ b/ProjectPages.h @@ -65,7 +65,7 @@ class ProjectPages : public QObject, public ref_countable { PageSequence toPageSequence(PageView view) const; - void listRelinkablePaths(VirtualFunction& sink) const; + void listRelinkablePaths(const VirtualFunction& sink) const; /** * \note It's up to the caller to make sure different paths aren't collapsed into one. diff --git a/ProjectWriter.cpp b/ProjectWriter.cpp index fcf136d59..9b0fe2268 100644 --- a/ProjectWriter.cpp +++ b/ProjectWriter.cpp @@ -242,13 +242,13 @@ int ProjectWriter::pageId(const PageId& page_id) const { return it->numericId; } -void ProjectWriter::enumImagesImpl(VirtualFunction& out) const { +void ProjectWriter::enumImagesImpl(const VirtualFunction& out) const { for (const Image& image : m_images.get()) { out(image.id, image.numericId); } } -void ProjectWriter::enumPagesImpl(VirtualFunction& out) const { +void ProjectWriter::enumPagesImpl(const VirtualFunction& out) const { for (const Page& page : m_pages.get()) { out(page.id, page.numericId); } diff --git a/ProjectWriter.h b/ProjectWriter.h index a6232b12b..02ca5f1fb 100644 --- a/ProjectWriter.h +++ b/ProjectWriter.h @@ -154,9 +154,9 @@ class ProjectWriter { int pageId(const PageId& page_id) const; - void enumImagesImpl(VirtualFunction& out) const; + void enumImagesImpl(const VirtualFunction& out) const; - void enumPagesImpl(VirtualFunction& out) const; + void enumPagesImpl(const VirtualFunction& out) const; PageSequence m_pageSequence; OutputFileNameGenerator m_outFileNameGen; @@ -170,16 +170,14 @@ class ProjectWriter { }; -template -void ProjectWriter::enumImages(OutFunc out) const { - ProxyFunction proxy(out); - enumImagesImpl(proxy); +template +void ProjectWriter::enumImages(Callable out) const { + enumImagesImpl(ProxyFunction(out)); } -template -void ProjectWriter::enumPages(OutFunc out) const { - ProxyFunction proxy(out); - enumPagesImpl(proxy); +template +void ProjectWriter::enumPages(Callable out) const { + enumPagesImpl(ProxyFunction(out)); } #endif // ifndef PROJECTWRITER_H_ diff --git a/RelinkingDialog.h b/RelinkingDialog.h index 5e954c5d1..023f351c6 100644 --- a/RelinkingDialog.h +++ b/RelinkingDialog.h @@ -36,8 +36,8 @@ class RelinkingDialog : public QDialog { public: explicit RelinkingDialog(const QString& project_file_path, QWidget* parent = nullptr); - VirtualFunction& pathCollector() { - return m_model; + ProxyFunction pathCollector() { + return ProxyFunction(m_model); } /** diff --git a/RelinkingModel.h b/RelinkingModel.h index b47b4ca6f..d9f0c1f14 100644 --- a/RelinkingModel.h +++ b/RelinkingModel.h @@ -36,7 +36,7 @@ #include #include -class RelinkingModel : public QAbstractListModel, public VirtualFunction { +class RelinkingModel : public QAbstractListModel { DECLARE_NON_COPYABLE(RelinkingModel) public: @@ -65,7 +65,7 @@ class RelinkingModel : public QAbstractListModel, public VirtualFunction& out) { + const VirtualFunction& out) { return TiffReader::readMetadata(io_device, out); } diff --git a/TiffMetadataLoader.h b/TiffMetadataLoader.h index a4f2e049a..aa20a614c 100644 --- a/TiffMetadataLoader.h +++ b/TiffMetadataLoader.h @@ -37,7 +37,7 @@ class TiffMetadataLoader : public ImageMetadataLoader { static void registerMyself(); protected: - Status loadMetadata(QIODevice& io_device, VirtualFunction& out) override; + Status loadMetadata(QIODevice& io_device, const VirtualFunction& out) override; }; diff --git a/TiffReader.cpp b/TiffReader.cpp index c667d0796..fc2fab96e 100644 --- a/TiffReader.cpp +++ b/TiffReader.cpp @@ -237,7 +237,7 @@ bool TiffReader::canRead(QIODevice& device) { } ImageMetadataLoader::Status TiffReader::readMetadata(QIODevice& device, - VirtualFunction& out) { + const VirtualFunction& out) { if (!device.isReadable()) { return ImageMetadataLoader::GENERIC_ERROR; } diff --git a/TiffReader.h b/TiffReader.h index 97641e84e..424d5d785 100644 --- a/TiffReader.h +++ b/TiffReader.h @@ -32,7 +32,7 @@ class TiffReader { static bool canRead(QIODevice& device); static ImageMetadataLoader::Status readMetadata(QIODevice& device, - VirtualFunction& out); + const VirtualFunction& out); /** * \brief Reads the image from io device to QImage. diff --git a/foundation/VirtualFunction.h b/foundation/VirtualFunction.h index f230284c8..adc29a8c0 100644 --- a/foundation/VirtualFunction.h +++ b/foundation/VirtualFunction.h @@ -27,7 +27,7 @@ class VirtualFunction { virtual ~VirtualFunction() { } - virtual Res operator()(ArgTypes... args) = 0; + virtual Res operator()(ArgTypes... args) const = 0; }; @@ -37,7 +37,7 @@ class ProxyFunction : public VirtualFunction { explicit ProxyFunction(Delegate delegate) : m_delegate(delegate) { } - Res operator()(ArgTypes... args) override { + Res operator()(ArgTypes... args) const override { return m_delegate(args...); } diff --git a/math/XSpline.cpp b/math/XSpline.cpp index ba03f22dd..25a0f3f46 100644 --- a/math/XSpline.cpp +++ b/math/XSpline.cpp @@ -177,7 +177,7 @@ QPointF XSpline::pointAtImpl(int segment, double t) const { return pt; } -void XSpline::sample(VirtualFunction& sink, +void XSpline::sample(const VirtualFunction& sink, const SamplingParams& params, double from_t, double to_t) const { @@ -211,7 +211,7 @@ void XSpline::sample(VirtualFunction& sink, sink(to_pt, to_t, TAIL_SAMPLE); } // XSpline::sample -void XSpline::maybeAddMoreSamples(VirtualFunction& sink, +void XSpline::maybeAddMoreSamples(const VirtualFunction& sink, double max_sqdist_to_spline, double max_sqdist_between_samples, double num_segments, @@ -702,18 +702,12 @@ QPointF XSpline::pointClosestTo(const QPointF to, double accuracy) const { } std::vector XSpline::toPolyline(const SamplingParams& params, double from_t, double to_t) const { - struct Sink : public VirtualFunction { - std::vector polyline; + std::vector polyline; - void operator()(QPointF pt, double, SampleFlags) override { - polyline.push_back(pt); - } - }; - - Sink sink; - sample(sink, params, from_t, to_t); + auto sink = [&polyline](const QPointF& pt, double, SampleFlags) { polyline.push_back(pt); }; + sample(ProxyFunction(sink), params, from_t, to_t); - return sink.polyline; + return polyline; } double XSpline::sqDistToLine(const QPointF& pt, const QLineF& line) { diff --git a/math/XSpline.h b/math/XSpline.h index 499f7f355..534b49af0 100644 --- a/math/XSpline.h +++ b/math/XSpline.h @@ -162,7 +162,7 @@ class XSpline : public spfit::FittableSpline { QPointF pointClosestTo(QPointF to, double accuracy = 0.2) const; /** \see spfit::FittableSpline::sample() */ - void sample(VirtualFunction& sink, + void sample(const VirtualFunction& sink, const SamplingParams& params = SamplingParams(), double from_t = 0.0, double to_t = 1.0) const override; @@ -207,7 +207,7 @@ class XSpline : public spfit::FittableSpline { DecomposedDerivs decomposedDerivsImpl(int segment, double t) const; - void maybeAddMoreSamples(VirtualFunction& sink, + void maybeAddMoreSamples(const VirtualFunction& sink, double max_sqdist_to_spline, double max_sqdist_between_samples, double num_segments, diff --git a/math/spfit/FittableSpline.h b/math/spfit/FittableSpline.h index 09c5ab9dd..d890a200d 100644 --- a/math/spfit/FittableSpline.h +++ b/math/spfit/FittableSpline.h @@ -107,7 +107,7 @@ class FittableSpline { * corresponding to them will be marked with HEAD_SAMPLE * and TAIL_SAMPLE respectably. */ - virtual void sample(VirtualFunction& sink, + virtual void sample(const VirtualFunction& sink, const SamplingParams& params, double from_t = 0.0, double to_t = 1.0) const = 0; diff --git a/math/spfit/SplineFitter.cpp b/math/spfit/SplineFitter.cpp index d3b7cf95e..09c1cb58e 100644 --- a/math/spfit/SplineFitter.cpp +++ b/math/spfit/SplineFitter.cpp @@ -110,26 +110,16 @@ void SplineFitter::addAttractionForce(const Vec2d& spline_point, } // SplineFitter::addAttractionForce void SplineFitter::addAttractionForces(const ModelShape& model_shape, double from_t, double to_t) { - class SampleProcessor : public VirtualFunction { - public: - SampleProcessor(SplineFitter& owner, const ModelShape& model_shape) - : m_rOwner(owner), m_rModelShape(model_shape) { - } - - void operator()(QPointF pt, double t, FittableSpline::SampleFlags flags) override { - m_rOwner.m_pSpline->linearCombinationAt(t, m_rOwner.m_tempCoeffs); - const SqDistApproximant approx(m_rModelShape.localSqDistApproximant(pt, flags)); - m_rOwner.addAttractionForce(pt, m_rOwner.m_tempCoeffs, approx); - } - - private: - SplineFitter& m_rOwner; - const ModelShape& m_rModelShape; + auto sample_processor = [this, &model_shape](const QPointF& pt, double t, FittableSpline::SampleFlags flags) { + m_pSpline->linearCombinationAt(t, m_tempCoeffs); + const SqDistApproximant approx(model_shape.localSqDistApproximant(pt, flags)); + addAttractionForce(pt, m_tempCoeffs, approx); }; - - SampleProcessor sample_processor(*this, model_shape); - m_pSpline->sample(sample_processor, m_samplingParams, from_t, to_t); + m_pSpline->sample( + ProxyFunction( + sample_processor), + m_samplingParams, from_t, to_t); } void SplineFitter::addExternalForce(const QuadraticFunction& force) { From 91ce827cc38bdda4088eb67d8423af0de0c21134 Mon Sep 17 00:00:00 2001 From: Alex <4lex49@zoho.com> Date: Sun, 8 Apr 2018 00:25:44 +0300 Subject: [PATCH 05/11] ~ Fixed: the area for estimating whether the input image at output is black on white has been extended. Also the background color calculator now depends on the result of that estimation instead of trying to calculate that itself. --- filters/output/OutputGenerator.cpp | 70 +++++++++--------- imageproc/BackgroundColorCalculator.cpp | 96 ++++++++----------------- imageproc/BackgroundColorCalculator.h | 9 ++- 3 files changed, 75 insertions(+), 100 deletions(-) diff --git a/filters/output/OutputGenerator.cpp b/filters/output/OutputGenerator.cpp index 34a8ba3ef..6331e9bd6 100644 --- a/filters/output/OutputGenerator.cpp +++ b/filters/output/OutputGenerator.cpp @@ -474,6 +474,7 @@ QImage OutputGenerator::processWithoutDewarping(const TaskStatus& status, const QPolygonF contentArea = m_xform.resultingPreCropArea().intersected( QRectF(render_params.cutMargins() ? m_contentRect : m_outRect)); const QRect contentRect = contentArea.boundingRect().toRect(); + const QPolygonF outCropArea = m_xform.resultingPreCropArea().intersected(QRectF(m_outRect)); const QSize target_size(m_outRect.size().expandedTo(QSize(1, 1))); // If the content area is empty or outside the cropping area, return a blank page. @@ -506,18 +507,19 @@ QImage OutputGenerator::processWithoutDewarping(const TaskStatus& status, .toRect()); const QRect contentRectInWorkingCs(contentRect.translated(-workingBoundingRect.topLeft())); const QPolygonF contentAreaInWorkingCs(contentArea.translated(-workingBoundingRect.topLeft())); + const QPolygonF outCropAreaInWorkingCs(outCropArea.translated(-workingBoundingRect.topLeft())); const QPolygonF preCropAreaInOriginalCs(m_xform.transformBack().map(m_xform.resultingPreCropArea())); const QPolygonF contentAreaInOriginalCs(m_xform.transformBack().map(contentArea)); + const QPolygonF outCropAreaInOriginalCs(m_xform.transformBack().map(outCropArea)); - const bool isBlackOnWhite = BlackOnWhiteEstimator::isBlackOnWhite(input.grayImage(), contentAreaInOriginalCs); - const GrayImage inputGrayImage = isBlackOnWhite ? input.grayImage() : input.grayImage().inverted(); - const QImage inputOrigImage = [&input, isBlackOnWhite]() { + const GrayImage inputGrayImage = input.isBlackOnWhite() ? input.grayImage() : input.grayImage().inverted(); + const QImage inputOrigImage = [&input]() { QImage result = input.origImage(); if (!result.allGray() && (result.format() != QImage::Format_ARGB32) && (result.format() != QImage::Format_RGB32)) { result = result.convertToFormat(QImage::Format_RGB32); } - if (!isBlackOnWhite) { + if (!input.isBlackOnWhite()) { result.invertPixels(); } @@ -525,7 +527,7 @@ QImage OutputGenerator::processWithoutDewarping(const TaskStatus& status, }(); QColor outsideBackgroundColor = BackgroundColorCalculator::calcDominantBackgroundColor( - inputOrigImage.allGray() ? inputGrayImage : inputOrigImage, contentAreaInOriginalCs); + inputOrigImage.allGray() ? inputGrayImage : inputOrigImage, outCropAreaInOriginalCs, dbg); const bool needNormalizeIllumination = (render_params.normalizeIllumination() && render_params.needBinarization()) @@ -562,7 +564,7 @@ QImage OutputGenerator::processWithoutDewarping(const TaskStatus& status, if (needNormalizeIllumination) { outsideBackgroundColor - = BackgroundColorCalculator::calcDominantBackgroundColor(maybe_normalized, contentAreaInWorkingCs); + = BackgroundColorCalculator::calcDominantBackgroundColor(maybe_normalized, outCropAreaInWorkingCs, dbg); } status.throwIfCancelled(); @@ -614,7 +616,7 @@ QImage OutputGenerator::processWithoutDewarping(const TaskStatus& status, maybeDespeckleInPlace(dst, m_outRect, m_outRect, m_despeckleLevel, speckles_image, m_dpi, status, dbg); if (!render_params.needColorSegmentation()) { - if (!isBlackOnWhite) { + if (!input.isBlackOnWhite()) { dst.invert(); } @@ -642,7 +644,7 @@ QImage OutputGenerator::processWithoutDewarping(const TaskStatus& status, status.throwIfCancelled(); - if (!isBlackOnWhite) { + if (!input.isBlackOnWhite()) { segmented_image.invertPixels(); } @@ -785,7 +787,7 @@ QImage OutputGenerator::processWithoutDewarping(const TaskStatus& status, if (needNormalizeIllumination && !render_params.normalizeIlluminationColor()) { outsideBackgroundColor = BackgroundColorCalculator::calcDominantBackgroundColor( - inputOrigImage.allGray() ? inputGrayImage : inputOrigImage, contentAreaInOriginalCs); + inputOrigImage.allGray() ? inputGrayImage : inputOrigImage, outCropAreaInOriginalCs, dbg); if (inputOrigImage.allGray()) { maybe_normalized = transformToGray(inputGrayImage, m_xform.transform(), workingBoundingRect, @@ -812,7 +814,7 @@ QImage OutputGenerator::processWithoutDewarping(const TaskStatus& status, QColor outsideOriginalBackgroundColor = outsideBackgroundColor; if (m_colorParams.colorCommonOptions().getFillingColor() == FILL_WHITE) { - outsideOriginalBackgroundColor = isBlackOnWhite ? Qt::white : Qt::black; + outsideOriginalBackgroundColor = input.isBlackOnWhite() ? Qt::white : Qt::black; } fillMarginsInPlace(original_background, contentAreaInWorkingCs, outsideOriginalBackgroundColor); original_background_dst.fill(outsideOriginalBackgroundColor); @@ -883,7 +885,7 @@ QImage OutputGenerator::processWithoutDewarping(const TaskStatus& status, if (render_params.needBinarization()) { outsideBackgroundColor = Qt::white; } else if (m_colorParams.colorCommonOptions().getFillingColor() == FILL_WHITE) { - outsideBackgroundColor = isBlackOnWhite ? Qt::white : Qt::black; + outsideBackgroundColor = input.isBlackOnWhite() ? Qt::white : Qt::black; if (!render_params.needBinarization()) { reserveBlackAndWhite(maybe_normalized); } @@ -894,7 +896,7 @@ QImage OutputGenerator::processWithoutDewarping(const TaskStatus& status, drawOver(dst, contentRect, maybe_normalized, contentRectInWorkingCs); maybe_normalized = QImage(); - if (!isBlackOnWhite) { + if (!input.isBlackOnWhite()) { dst.invertPixels(); } @@ -919,17 +921,17 @@ QImage OutputGenerator::processWithoutDewarping(const TaskStatus& status, splitImage->setBackgroundImage(dst); if (render_params.needBinarization() && render_params.originalBackground()) { - if (!isBlackOnWhite) { + if (!input.isBlackOnWhite()) { dst.invertPixels(); } BinaryImage background_mask = BinaryImage(dst, BinaryThreshold(255)).inverted(); fillMarginsInPlace(background_mask, m_xform.resultingPreCropArea(), BLACK); - applyMask(original_background, background_mask, isBlackOnWhite ? WHITE : BLACK); + applyMask(original_background, background_mask, input.isBlackOnWhite() ? WHITE : BLACK); - applyMask(original_background, bw_content_mask_output, isBlackOnWhite ? BLACK : WHITE); + applyMask(original_background, bw_content_mask_output, input.isBlackOnWhite() ? BLACK : WHITE); - if (!isBlackOnWhite) { + if (!input.isBlackOnWhite()) { original_background.invertPixels(); } splitImage->setOriginalBackgroundImage(original_background); @@ -968,6 +970,7 @@ QImage OutputGenerator::processWithDewarping(const TaskStatus& status, const QPolygonF contentArea = m_xform.resultingPreCropArea().intersected( QRectF(render_params.cutMargins() ? m_contentRect : m_outRect)); const QRect contentRect = contentArea.boundingRect().toRect(); + const QPolygonF outCropArea = m_xform.resultingPreCropArea().intersected(QRectF(m_outRect)); const QSize target_size(m_outRect.size().expandedTo(QSize(1, 1))); // If the content area is empty or outside the cropping area, return a blank page. @@ -1000,18 +1003,19 @@ QImage OutputGenerator::processWithDewarping(const TaskStatus& status, .toRect()); const QRect contentRectInWorkingCs(contentRect.translated(-workingBoundingRect.topLeft())); const QPolygonF contentAreaInWorkingCs(contentArea.translated(-workingBoundingRect.topLeft())); + const QPolygonF outCropAreaInWorkingCs(outCropArea.translated(-workingBoundingRect.topLeft())); const QPolygonF preCropAreaInOriginalCs(m_xform.transformBack().map(m_xform.resultingPreCropArea())); const QPolygonF contentAreaInOriginalCs(m_xform.transformBack().map(contentArea)); + const QPolygonF outCropAreaInOriginalCs(m_xform.transformBack().map(outCropArea)); - const bool isBlackOnWhite = BlackOnWhiteEstimator::isBlackOnWhite(input.grayImage(), contentAreaInOriginalCs); - const GrayImage inputGrayImage = isBlackOnWhite ? input.grayImage() : input.grayImage().inverted(); - const QImage inputOrigImage = [&input, isBlackOnWhite]() { + const GrayImage inputGrayImage = input.isBlackOnWhite() ? input.grayImage() : input.grayImage().inverted(); + const QImage inputOrigImage = [&input]() { QImage result = input.origImage(); if (!result.allGray() && (result.format() != QImage::Format_ARGB32) && (result.format() != QImage::Format_RGB32)) { result = result.convertToFormat(QImage::Format_RGB32); } - if (!isBlackOnWhite) { + if (!input.isBlackOnWhite()) { result.invertPixels(); } @@ -1019,7 +1023,7 @@ QImage OutputGenerator::processWithDewarping(const TaskStatus& status, }(); QColor outsideBackgroundColor = BackgroundColorCalculator::calcDominantBackgroundColor( - inputOrigImage.allGray() ? inputGrayImage : inputOrigImage, contentAreaInOriginalCs); + inputOrigImage.allGray() ? inputGrayImage : inputOrigImage, outCropAreaInOriginalCs, dbg); const bool color_original = !inputOrigImage.allGray(); @@ -1088,8 +1092,8 @@ QImage OutputGenerator::processWithDewarping(const TaskStatus& status, } } - outsideBackgroundColor - = BackgroundColorCalculator::calcDominantBackgroundColor(normalized_original, contentAreaInOriginalCs); + outsideBackgroundColor = BackgroundColorCalculator::calcDominantBackgroundColor(normalized_original, + outCropAreaInOriginalCs, dbg); } status.throwIfCancelled(); @@ -1467,7 +1471,7 @@ QImage OutputGenerator::processWithDewarping(const TaskStatus& status, status, dbg); if (!render_params.needColorSegmentation()) { - if (!isBlackOnWhite) { + if (!input.isBlackOnWhite()) { dewarped_bw_content.invert(); } @@ -1485,7 +1489,7 @@ QImage OutputGenerator::processWithDewarping(const TaskStatus& status, status.throwIfCancelled(); - if (!isBlackOnWhite) { + if (!input.isBlackOnWhite()) { segmented_image.invertPixels(); } @@ -1594,7 +1598,7 @@ QImage OutputGenerator::processWithDewarping(const TaskStatus& status, if (needNormalizeIllumination && !render_params.normalizeIlluminationColor()) { outsideBackgroundColor = BackgroundColorCalculator::calcDominantBackgroundColor( - inputOrigImage.allGray() ? inputGrayImage : inputOrigImage, contentAreaInOriginalCs); + inputOrigImage.allGray() ? inputGrayImage : inputOrigImage, outCropAreaInOriginalCs, dbg); QImage orig_without_illumination; if (color_original) { @@ -1625,7 +1629,7 @@ QImage OutputGenerator::processWithDewarping(const TaskStatus& status, QColor outsideOriginalBackgroundColor = outsideBackgroundColor; if (m_colorParams.colorCommonOptions().getFillingColor() == FILL_WHITE) { - outsideOriginalBackgroundColor = isBlackOnWhite ? Qt::white : Qt::black; + outsideOriginalBackgroundColor = input.isBlackOnWhite() ? Qt::white : Qt::black; } fillMarginsInPlace(original_background, dewarping_content_area_mask, outsideOriginalBackgroundColor); @@ -1677,14 +1681,14 @@ QImage OutputGenerator::processWithDewarping(const TaskStatus& status, if (render_params.needBinarization()) { outsideBackgroundColor = Qt::white; } else if (m_colorParams.colorCommonOptions().getFillingColor() == FILL_WHITE) { - outsideBackgroundColor = isBlackOnWhite ? Qt::white : Qt::black; + outsideBackgroundColor = input.isBlackOnWhite() ? Qt::white : Qt::black; if (!render_params.needBinarization()) { reserveBlackAndWhite(dewarped); } } fillMarginsInPlace(dewarped, dewarping_content_area_mask, outsideBackgroundColor); - if (!isBlackOnWhite) { + if (!input.isBlackOnWhite()) { dewarped.invertPixels(); } @@ -1710,17 +1714,17 @@ QImage OutputGenerator::processWithDewarping(const TaskStatus& status, splitImage->setBackgroundImage(dewarped); if (render_params.needBinarization() && render_params.originalBackground()) { - if (!isBlackOnWhite) { + if (!input.isBlackOnWhite()) { dewarped.invertPixels(); } BinaryImage background_mask = BinaryImage(dewarped, BinaryThreshold(255)).inverted(); fillMarginsInPlace(background_mask, dewarping_content_area_mask, BLACK); - applyMask(original_background, background_mask, isBlackOnWhite ? WHITE : BLACK); + applyMask(original_background, background_mask, input.isBlackOnWhite() ? WHITE : BLACK); - applyMask(original_background, dewarped_bw_content_mask, isBlackOnWhite ? BLACK : WHITE); + applyMask(original_background, dewarped_bw_content_mask, input.isBlackOnWhite() ? BLACK : WHITE); - if (!isBlackOnWhite) { + if (!input.isBlackOnWhite()) { original_background.invertPixels(); } splitImage->setOriginalBackgroundImage(original_background); diff --git a/imageproc/BackgroundColorCalculator.cpp b/imageproc/BackgroundColorCalculator.cpp index fa10a32b7..fd01de170 100644 --- a/imageproc/BackgroundColorCalculator.cpp +++ b/imageproc/BackgroundColorCalculator.cpp @@ -7,6 +7,7 @@ #include "RasterOp.h" #include "PolygonRasterizer.h" #include "Morphology.h" +#include "DebugImages.h" namespace imageproc { @@ -120,6 +121,16 @@ void grayHistToArray(int* raw_hist, GrayscaleHistogram hist) { raw_hist[i] = hist[i]; } } + +void checkImageIsValid(const QImage& img) { + if (!((img.format() == QImage::Format_RGB32) || (img.format() == QImage::Format_ARGB32) + || ((img.format() == QImage::Format_Indexed8) && img.isGrayscale()))) { + throw std::invalid_argument("BackgroundColorCalculator: wrong image format"); + } + if (img.isNull()) { + throw std::invalid_argument("BackgroundColorCalculator: image is null."); + } +} } // namespace uint8_t BackgroundColorCalculator::calcDominantLevel(const int* hist) { @@ -156,80 +167,38 @@ uint8_t BackgroundColorCalculator::calcDominantLevel(const int* hist) { } // BackgroundColorCalculator::calcDominantLevel QColor BackgroundColorCalculator::calcDominantBackgroundColor(const QImage& img) { - if (!((img.format() == QImage::Format_RGB32) || (img.format() == QImage::Format_ARGB32) - || ((img.format() == QImage::Format_Indexed8) && img.isGrayscale()))) { - throw std::invalid_argument("BackgroundColorCalculator: wrong image format"); - } - if (img.isNull()) { - throw std::invalid_argument("BackgroundColorCalculator: image is null."); - } + checkImageIsValid(img); BinaryImage background_mask(img, BinaryThreshold::otsuThreshold(img)); - if (2 * background_mask.countBlackPixels() < background_mask.width() * background_mask.height()) { - background_mask.invert(); - } + background_mask.invert(); - if (img.format() == QImage::Format_Indexed8) { - const GrayscaleHistogram hist(img, background_mask); - int raw_hist[256]; - grayHistToArray(raw_hist, hist); - uint8_t dominant_gray = calcDominantLevel(raw_hist); - - return QColor(dominant_gray, dominant_gray, dominant_gray); - } else { - const RgbHistogram hist(img, background_mask); - uint8_t dominant_red = calcDominantLevel(hist.redChannel()); - uint8_t dominant_green = calcDominantLevel(hist.greenChannel()); - uint8_t dominant_blue = calcDominantLevel(hist.blueChannel()); - - return QColor(dominant_red, dominant_green, dominant_blue); - } + return calcDominantColor(img, background_mask); } -QColor BackgroundColorCalculator::calcDominantBackgroundColor(const QImage& img, const BinaryImage& mask) { - if (!((img.format() == QImage::Format_RGB32) || (img.format() == QImage::Format_ARGB32) - || ((img.format() == QImage::Format_Indexed8) && img.isGrayscale()))) { - throw std::invalid_argument("BackgroundColorCalculator: wrong image format"); - } - if (img.isNull()) { - throw std::invalid_argument("BackgroundColorCalculator: image is null."); - } +QColor BackgroundColorCalculator::calcDominantBackgroundColor(const QImage& img, + const BinaryImage& mask, + DebugImages* dbg) { + checkImageIsValid(img); + if (img.size() != mask.size()) { throw std::invalid_argument("BackgroundColorCalculator: img and mask have different sizes"); } BinaryImage background_mask(img, BinaryThreshold::otsuThreshold(GrayscaleHistogram(img, mask))); + background_mask.invert(); rasterOp>(background_mask, mask); - if (2 * background_mask.countBlackPixels() <= mask.countBlackPixels()) { - background_mask.invert(); - rasterOp>(background_mask, mask); + if (dbg) { + dbg->add(background_mask, "background_mask"); } - if ((img.format() == QImage::Format_Indexed8) && img.isGrayscale()) { - const GrayscaleHistogram hist(img, background_mask); - int raw_hist[256]; - grayHistToArray(raw_hist, hist); - uint8_t dominant_gray = calcDominantLevel(raw_hist); - - return QColor(dominant_gray, dominant_gray, dominant_gray); - } else { - const RgbHistogram hist(img, background_mask); - uint8_t dominant_red = calcDominantLevel(hist.redChannel()); - uint8_t dominant_green = calcDominantLevel(hist.greenChannel()); - uint8_t dominant_blue = calcDominantLevel(hist.blueChannel()); - - return QColor(dominant_red, dominant_green, dominant_blue); - } + return calcDominantColor(img, background_mask); } -QColor BackgroundColorCalculator::calcDominantBackgroundColor(const QImage& img, const QPolygonF& crop_area) { - if (!((img.format() == QImage::Format_RGB32) || (img.format() == QImage::Format_ARGB32) - || ((img.format() == QImage::Format_Indexed8) && img.isGrayscale()))) { - throw std::invalid_argument("BackgroundColorCalculator: wrong image format"); - } - if (img.isNull()) { - throw std::invalid_argument("BackgroundColorCalculator: image is null."); - } +QColor BackgroundColorCalculator::calcDominantBackgroundColor(const QImage& img, + const QPolygonF& crop_area, + DebugImages* dbg) { + checkImageIsValid(img); + if (crop_area.intersected(QRectF(img.rect())).isEmpty()) { throw std::invalid_argument("BackgroundColorCalculator: the cropping area is wrong."); } @@ -237,13 +206,10 @@ QColor BackgroundColorCalculator::calcDominantBackgroundColor(const QImage& img, BinaryImage mask(img.size(), BLACK); PolygonRasterizer::fillExcept(mask, WHITE, crop_area, Qt::WindingFill); - BinaryImage background_mask(img, BinaryThreshold::otsuThreshold(GrayscaleHistogram(img, mask))); - rasterOp>(background_mask, mask); - if (2 * background_mask.countBlackPixels() <= mask.countBlackPixels()) { - background_mask.invert(); - rasterOp>(background_mask, mask); - } + return calcDominantBackgroundColor(img, mask, dbg); +} +QColor BackgroundColorCalculator::calcDominantColor(const QImage& img, const BinaryImage& background_mask) { if ((img.format() == QImage::Format_Indexed8) && img.isGrayscale()) { const GrayscaleHistogram hist(img, background_mask); int raw_hist[256]; diff --git a/imageproc/BackgroundColorCalculator.h b/imageproc/BackgroundColorCalculator.h index 1f000b882..94fc4e59c 100644 --- a/imageproc/BackgroundColorCalculator.h +++ b/imageproc/BackgroundColorCalculator.h @@ -8,6 +8,7 @@ class QImage; class QColor; class QPolygonF; +class DebugImages; namespace imageproc { class GrayscaleHistogram; @@ -17,12 +18,16 @@ class BackgroundColorCalculator { public: static QColor calcDominantBackgroundColor(const QImage& img); - static QColor calcDominantBackgroundColor(const QImage& img, const BinaryImage& mask); + static QColor calcDominantBackgroundColor(const QImage& img, const BinaryImage& mask, DebugImages* dbg = nullptr); - static QColor calcDominantBackgroundColor(const QImage& img, const QPolygonF& crop_area); + static QColor calcDominantBackgroundColor(const QImage& img, + const QPolygonF& crop_area, + DebugImages* dbg = nullptr); private: static uint8_t calcDominantLevel(const int* hist); + + static QColor calcDominantColor(const QImage& img, const BinaryImage& background_mask); }; } // namespace imageproc From ce79f666e58c66bb0a42f1c4e7888cd1d2eb51e0 Mon Sep 17 00:00:00 2001 From: Alex <4lex49@zoho.com> Date: Sat, 7 Apr 2018 02:42:00 +0300 Subject: [PATCH 06/11] ~ Fixed: the color segmenter state was saved incorrectly. --- filters/output/BlackWhiteOptions.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/filters/output/BlackWhiteOptions.cpp b/filters/output/BlackWhiteOptions.cpp index a90232c3e..b8bc7f4e1 100644 --- a/filters/output/BlackWhiteOptions.cpp +++ b/filters/output/BlackWhiteOptions.cpp @@ -216,7 +216,7 @@ BlackWhiteOptions::ColorSegmenterOptions::ColorSegmenterOptions(const QDomElemen QDomElement BlackWhiteOptions::ColorSegmenterOptions::toXml(QDomDocument& doc, const QString& name) const { QDomElement el(doc.createElement(name)); - el.setAttribute("colorSegmentationEnabled", enabled ? "1" : "0"); + el.setAttribute("enabled", enabled ? "1" : "0"); el.setAttribute("noiseReduction", noiseReduction); el.setAttribute("redThresholdAdjustment", redThresholdAdjustment); el.setAttribute("greenThresholdAdjustment", greenThresholdAdjustment); From 2d512d647d68c59f10728ea0948c20e26cea8bd0 Mon Sep 17 00:00:00 2001 From: Alex <4lex49@zoho.com> Date: Sun, 8 Apr 2018 01:43:40 +0300 Subject: [PATCH 07/11] ~ Fixed: some parameters on some platforms were saved into xml invalidly. Reason: QDomElement::setAttribute double and float versions are locale dependent. --- DefaultParams.cpp | 5 +++-- filters/output/BlackWhiteOptions.cpp | 5 +++-- filters/select_content/Filter.cpp | 14 ++++++-------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/DefaultParams.cpp b/DefaultParams.cpp index 04a389a13..ad6bec441 100644 --- a/DefaultParams.cpp +++ b/DefaultParams.cpp @@ -2,6 +2,7 @@ #include "DefaultParams.h" #include "XmlUnmarshaller.h" #include "XmlMarshaller.h" +#include "Utils.h" using namespace page_split; using namespace output; @@ -156,7 +157,7 @@ DefaultParams::DeskewParams::DeskewParams(const QDomElement& el) QDomElement DefaultParams::DeskewParams::toXml(QDomDocument& doc, const QString& name) const { QDomElement el(doc.createElement(name)); - el.setAttribute("deskewAngleDeg", deskewAngleDeg); + el.setAttribute("deskewAngleDeg", Utils::doubleToString(deskewAngleDeg)); el.setAttribute("mode", (mode == MODE_AUTO) ? "auto" : "manual"); return el; @@ -405,7 +406,7 @@ QDomElement DefaultParams::OutputParams::toXml(QDomDocument& doc, const QString& el.appendChild(colorParams.toXml(doc, "colorParams")); el.appendChild(splittingOptions.toXml(doc, "splittingOptions")); el.appendChild(pictureShapeOptions.toXml(doc, "pictureShapeOptions")); - el.setAttribute("depthPerception", depthPerception.value()); + el.setAttribute("depthPerception", Utils::doubleToString(depthPerception.value())); el.appendChild(dewarpingOptions.toXml(doc, "dewarpingOptions")); el.setAttribute("despeckleLevel", despeckleLevelToString(despeckleLevel)); diff --git a/filters/output/BlackWhiteOptions.cpp b/filters/output/BlackWhiteOptions.cpp index b8bc7f4e1..3ead784ce 100644 --- a/filters/output/BlackWhiteOptions.cpp +++ b/filters/output/BlackWhiteOptions.cpp @@ -17,6 +17,7 @@ */ #include "BlackWhiteOptions.h" +#include "../../Utils.h" #include #include @@ -55,10 +56,10 @@ QDomElement BlackWhiteOptions::toXml(QDomDocument& doc, const QString& name) con el.setAttribute("morphologicalSmoothing", morphologicalSmoothingEnabled ? "1" : "0"); el.setAttribute("normalizeIlluminationBW", m_normalizeIllumination ? "1" : "0"); el.setAttribute("windowSize", windowSize); - el.setAttribute("sauvolaCoef", sauvolaCoef); + el.setAttribute("sauvolaCoef", Utils::doubleToString(sauvolaCoef)); el.setAttribute("wolfLowerBound", wolfLowerBound); el.setAttribute("wolfUpperBound", wolfUpperBound); - el.setAttribute("wolfCoef", wolfCoef); + el.setAttribute("wolfCoef", Utils::doubleToString(wolfCoef)); el.setAttribute("binarizationMethod", formatBinarizationMethod(binarizationMethod)); el.appendChild(colorSegmenterOptions.toXml(doc, "color-segmenter-options")); diff --git a/filters/select_content/Filter.cpp b/filters/select_content/Filter.cpp index 7f0bee847..83461d6c2 100644 --- a/filters/select_content/Filter.cpp +++ b/filters/select_content/Filter.cpp @@ -35,6 +35,9 @@ #include #include #include +#include +#include +#include namespace select_content { Filter::Filter(const PageSelectionAccessor& page_selection_accessor) @@ -90,9 +93,8 @@ void Filter::preUpdateUI(FilterUiInterface* ui, const PageInfo& page_info) { QDomElement Filter::saveSettings(const ProjectWriter& writer, QDomDocument& doc) const { QDomElement filter_el(doc.createElement("select-content")); - filter_el.setAttribute("pageDetectionBoxWidth", m_ptrSettings->pageDetectionBox().width()); - filter_el.setAttribute("pageDetectionBoxHeight", m_ptrSettings->pageDetectionBox().height()); - filter_el.setAttribute("pageDetectionTolerance", m_ptrSettings->pageDetectionTolerance()); + filter_el.appendChild(XmlMarshaller(doc).sizeF(m_ptrSettings->pageDetectionBox(), "page-detection-box")); + filter_el.setAttribute("pageDetectionTolerance", Utils::doubleToString(m_ptrSettings->pageDetectionTolerance())); writer.enumPages([&](const PageId& page_id, int numeric_id) { this->writePageSettings(doc, filter_el, page_id, numeric_id); @@ -119,11 +121,7 @@ void Filter::loadSettings(const ProjectReader& reader, const QDomElement& filter const QDomElement filter_el(filters_el.namedItem("select-content").toElement()); - QSizeF box(0.0, 0.0); - box.setWidth(filter_el.attribute("pageDetectionBoxWidth", "0.0").toDouble()); - box.setHeight(filter_el.attribute("pageDetectionBoxHeight", "0.0").toDouble()); - m_ptrSettings->setPageDetectionBox(box); - + m_ptrSettings->setPageDetectionBox(XmlUnmarshaller::sizeF(filter_el.namedItem("page-detection-box").toElement())); m_ptrSettings->setPageDetectionTolerance(filter_el.attribute("pageDetectionTolerance", "0.1").toDouble()); const QString page_tag_name("page"); From 0a324687286ffa30bd25313ce4b4786b1ff69592 Mon Sep 17 00:00:00 2001 From: Alex <4lex49@zoho.com> Date: Sun, 8 Apr 2018 04:01:33 +0300 Subject: [PATCH 08/11] # Canceled feature "Support for processing of images with light content on dark background" (Reverts 781159aba41900ef9bbfdc2c0ee56741da5d9966) --- BlackOnWhiteEstimator.cpp | 103 -------------------- BlackOnWhiteEstimator.h | 35 ------- CMakeLists.txt | 1 - FilterData.cpp | 4 - FilterData.h | 2 - ImageSettings.cpp | 19 +--- ImageSettings.h | 7 +- README.md | 3 - filters/deskew/Task.cpp | 14 +-- filters/fix_orientation/Task.cpp | 2 +- filters/output/OutputGenerator.cpp | 67 ++----------- filters/select_content/ContentBoxFinder.cpp | 5 +- filters/select_content/PageFinder.cpp | 5 +- filters/select_content/Task.cpp | 3 +- imageproc/BackgroundColorCalculator.cpp | 8 +- 15 files changed, 31 insertions(+), 247 deletions(-) delete mode 100644 BlackOnWhiteEstimator.cpp delete mode 100644 BlackOnWhiteEstimator.h diff --git a/BlackOnWhiteEstimator.cpp b/BlackOnWhiteEstimator.cpp deleted file mode 100644 index 19166cace..000000000 --- a/BlackOnWhiteEstimator.cpp +++ /dev/null @@ -1,103 +0,0 @@ - -#include -#include -#include -#include -#include -#include -#include "BlackOnWhiteEstimator.h" -#include "Despeckle.h" -#include "DebugImages.h" -#include "TaskStatus.h" - -using namespace imageproc; - -bool BlackOnWhiteEstimator::isBlackOnWhiteRefining(const imageproc::GrayImage& grayImage, - const ImageTransformation& xform, - const TaskStatus& status, - DebugImages* dbg) { - BinaryImage bw150; - { - ImageTransformation xform150dpi(xform); - xform150dpi.preScaleToDpi(Dpi(150, 150)); - - if (xform150dpi.resultingRect().toRect().isEmpty()) { - return true; - } - - QImage gray150(transformToGray(grayImage, xform150dpi.transform(), xform150dpi.resultingRect().toRect(), - OutsidePixels::assumeColor(Qt::white))); - bw150 = binarizeOtsu(gray150); - - Despeckle::despeckleInPlace(bw150, Dpi(150, 150), Despeckle::NORMAL, status); - bw150.invert(); - Despeckle::despeckleInPlace(bw150, Dpi(150, 150), Despeckle::NORMAL, status); - bw150.invert(); - if (dbg) { - dbg->add(bw150, "bw150"); - } - } - - status.throwIfCancelled(); - - BinaryImage contentMask; - { - BinaryImage whiteTopHat = whiteTopHatTransform(bw150, QSize(13, 13)); - BinaryImage blackTopHat = blackTopHatTransform(bw150, QSize(13, 13)); - - contentMask = whiteTopHat; - rasterOp>(contentMask, blackTopHat); - - contentMask = closeBrick(contentMask, QSize(200, 200)); - contentMask = dilateBrick(contentMask, QSize(30, 30)); - if (dbg) { - dbg->add(contentMask, "content_mask"); - } - } - - status.throwIfCancelled(); - - rasterOp>(bw150, contentMask); - - return (2 * bw150.countBlackPixels() <= contentMask.countBlackPixels()); -} - -bool BlackOnWhiteEstimator::isBlackOnWhite(const imageproc::GrayImage& grayImage, - const ImageTransformation& xform, - const TaskStatus& status, - DebugImages* dbg) { - if (isBlackOnWhite(grayImage, xform.resultingPreCropArea())) { - return true; - } else { - // The black borders of the page can make the method above giving the wrong result. - return isBlackOnWhiteRefining(grayImage, xform, status, dbg); - } -} - -bool BlackOnWhiteEstimator::isBlackOnWhite(const GrayImage& img, const BinaryImage& mask) { - if (img.isNull()) { - throw std::invalid_argument("BlackOnWhiteEstimator: image is null."); - } - if (img.size() != mask.size()) { - throw std::invalid_argument("BlackOnWhiteEstimator: img and mask have different sizes"); - } - - BinaryImage bwImage(img, BinaryThreshold::otsuThreshold(GrayscaleHistogram(img, mask))); - rasterOp>(bwImage, mask); - - return (2 * bwImage.countBlackPixels() <= mask.countBlackPixels()); -} - -bool BlackOnWhiteEstimator::isBlackOnWhite(const GrayImage& img, const QPolygonF& cropArea) { - if (img.isNull()) { - throw std::invalid_argument("BlackOnWhiteEstimator: image is null."); - } - if (cropArea.intersected(QRectF(img.rect())).isEmpty()) { - throw std::invalid_argument("BlackOnWhiteEstimator: the cropping area is wrong."); - } - - BinaryImage mask(img.size(), BLACK); - PolygonRasterizer::fillExcept(mask, WHITE, cropArea, Qt::WindingFill); - - return isBlackOnWhite(img, mask); -} diff --git a/BlackOnWhiteEstimator.h b/BlackOnWhiteEstimator.h deleted file mode 100644 index 0bff46b9b..000000000 --- a/BlackOnWhiteEstimator.h +++ /dev/null @@ -1,35 +0,0 @@ - -#ifndef SCANTAILOR_BLACKONWHITEESTIMATOR_H -#define SCANTAILOR_BLACKONWHITEESTIMATOR_H - -#include -#include -#include "ImageTransformation.h" - -class TaskStatus; -class DebugImages; - -namespace imageproc { -class GrayImage; -class BinaryImage; -} // namespace imageproc - -class BlackOnWhiteEstimator { -public: - static bool isBlackOnWhite(const imageproc::GrayImage& grayImage, - const ImageTransformation& xform, - const TaskStatus& status, - DebugImages* dbg = nullptr); - - static bool isBlackOnWhiteRefining(const imageproc::GrayImage& grayImage, - const ImageTransformation& xform, - const TaskStatus& status, - DebugImages* dbg = nullptr); - - static bool isBlackOnWhite(const imageproc::GrayImage& img, const imageproc::BinaryImage& mask); - - static bool isBlackOnWhite(const imageproc::GrayImage& img, const QPolygonF& cropArea); -}; - - -#endif // SCANTAILOR_BLACKONWHITEESTIMATOR_H diff --git a/CMakeLists.txt b/CMakeLists.txt index cd3498727..e9a10faf2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -557,7 +557,6 @@ SET( DefaultParamsProvider.cpp DefaultParamsProvider.h DeviationProvider.h OrderByDeviationProvider.cpp OrderByDeviationProvider.h - BlackOnWhiteEstimator.cpp BlackOnWhiteEstimator.h ImageSettings.cpp ImageSettings.h version.h config.h.in diff --git a/FilterData.cpp b/FilterData.cpp index cad9c1ab1..0755525a7 100644 --- a/FilterData.cpp +++ b/FilterData.cpp @@ -51,10 +51,6 @@ const imageproc::GrayImage& FilterData::grayImage() const { return m_grayImage; } -bool FilterData::isBlackOnWhite() const { - return m_imageParams.isBlackOnWhite(); -} - void FilterData::updateImageParams(const ImageSettings::PageParams& imageParams) { m_imageParams = imageParams; } diff --git a/FilterData.h b/FilterData.h index 11b328aaf..4fb85f865 100644 --- a/FilterData.h +++ b/FilterData.h @@ -42,8 +42,6 @@ class FilterData { const imageproc::GrayImage& grayImage() const; - bool isBlackOnWhite() const; - void updateImageParams(const ImageSettings::PageParams& imageParams); private: diff --git a/ImageSettings.cpp b/ImageSettings.cpp index db92ae7d4..df8451819 100644 --- a/ImageSettings.cpp +++ b/ImageSettings.cpp @@ -41,21 +41,18 @@ std::unique_ptr ImageSettings::getPageParams(const Pa /*=============================== ImageSettings::Params ==================================*/ -ImageSettings::PageParams::PageParams() : bwThreshold(0), blackOnWhite(true) { +ImageSettings::PageParams::PageParams() : bwThreshold(0) { } -ImageSettings::PageParams::PageParams(const BinaryThreshold& bwThreshold, bool blackOnWhite) - : bwThreshold(bwThreshold), blackOnWhite(blackOnWhite) { +ImageSettings::PageParams::PageParams(const BinaryThreshold& bwThreshold) : bwThreshold(bwThreshold) { } -ImageSettings::PageParams::PageParams(const QDomElement& el) - : bwThreshold(el.attribute("bwThreshold").toInt()), blackOnWhite(el.attribute("blackOnWhite") == "1") { +ImageSettings::PageParams::PageParams(const QDomElement& el) : bwThreshold(el.attribute("bwThreshold").toInt()) { } QDomElement ImageSettings::PageParams::toXml(QDomDocument& doc, const QString& name) const { QDomElement el(doc.createElement(name)); el.setAttribute("bwThreshold", bwThreshold); - el.setAttribute("blackOnWhite", blackOnWhite ? "1" : "0"); return el; } @@ -66,12 +63,4 @@ const BinaryThreshold& ImageSettings::PageParams::getBwThreshold() const { void ImageSettings::PageParams::setBwThreshold(const BinaryThreshold& bwThreshold) { PageParams::bwThreshold = bwThreshold; -} - -bool ImageSettings::PageParams::isBlackOnWhite() const { - return blackOnWhite; -} - -void ImageSettings::PageParams::setBlackOnWhite(bool blackOnWhite) { - PageParams::blackOnWhite = blackOnWhite; -} +} \ No newline at end of file diff --git a/ImageSettings.h b/ImageSettings.h index a27cb8473..d9ac44ad2 100644 --- a/ImageSettings.h +++ b/ImageSettings.h @@ -19,7 +19,7 @@ class ImageSettings : public ref_countable { public: PageParams(); - PageParams(const imageproc::BinaryThreshold& bwThreshold, bool blackOnWhite); + explicit PageParams(const imageproc::BinaryThreshold& bwThreshold); explicit PageParams(const QDomElement& el); @@ -29,13 +29,8 @@ class ImageSettings : public ref_countable { void setBwThreshold(const imageproc::BinaryThreshold& bwThreshold); - bool isBlackOnWhite() const; - - void setBlackOnWhite(bool blackOnWhite); - private: imageproc::BinaryThreshold bwThreshold; - bool blackOnWhite; }; ImageSettings() = default; diff --git a/README.md b/README.md index 5d957d5c7..0804839a1 100644 --- a/README.md +++ b/README.md @@ -179,9 +179,6 @@ Features * Added option to control highlighting (with red asterisks) the thumbnails of pages with high deviation. The option refreshes the thumbnails instantly. - * Support for processing of images with light content on dark background. - Now that kind of images can correctly be handled on all the stages. Many book covers are examples of such images. - * Deviation feature reworked. 1. A deviation provider implemented. It supports caching and recalculates the values on demand. There isn't more any necessity to store deviation in page parameters and so in the project file, that approach caused some problems as the deviation is not actually a page parameter and depends on all the pages in the project. diff --git a/filters/deskew/Task.cpp b/filters/deskew/Task.cpp index fd017f438..34e146a7b 100644 --- a/filters/deskew/Task.cpp +++ b/filters/deskew/Task.cpp @@ -19,7 +19,6 @@ #include #include -#include #include "Task.h" #include "Filter.h" #include "OptionsWidget.h" @@ -123,12 +122,9 @@ FilterResultPtr Task::process(const TaskStatus& status, FilterData data) { status.throwIfCancelled(); if (bounded_image_area.isValid()) { - BinaryImage rotated_image(orthogonalRotation( - BinaryImage(data.isBlackOnWhite() ? data.grayImage() : data.grayImage().inverted(), - bounded_image_area, - data.isBlackOnWhite() ? data.bwThreshold() - : BinaryThreshold(256 - int(data.bwThreshold()))), - data.xform().preRotation().toDegrees())); + BinaryImage rotated_image( + orthogonalRotation(BinaryImage(data.grayImage(), bounded_image_area, data.bwThreshold()), + data.xform().preRotation().toDegrees())); if (m_ptrDbg) { m_ptrDbg->add(rotated_image, "bw_rotated"); } @@ -232,9 +228,7 @@ void Task::updateFilterData(const TaskStatus& status, FilterData& data, bool nee const GrayImage& img = data.grayImage(); BinaryImage mask(img.size(), BLACK); PolygonRasterizer::fillExcept(mask, WHITE, data.xform().resultingPreCropArea(), Qt::WindingFill); - ImageSettings::PageParams new_params( - BinaryThreshold::otsuThreshold(GrayscaleHistogram(img, mask)), - BlackOnWhiteEstimator::isBlackOnWhite(data.grayImage(), data.xform(), status, m_ptrDbg.get())); + ImageSettings::PageParams new_params(BinaryThreshold::otsuThreshold(GrayscaleHistogram(img, mask))); m_ptrImageSettings->setPageParams(m_pageId, new_params); data.updateImageParams(new_params); diff --git a/filters/fix_orientation/Task.cpp b/filters/fix_orientation/Task.cpp index cda40ca86..b4e7bde61 100644 --- a/filters/fix_orientation/Task.cpp +++ b/filters/fix_orientation/Task.cpp @@ -94,7 +94,7 @@ void Task::updateFilterData(FilterData& data) { if (const std::unique_ptr params = m_ptrImageSettings->getPageParams(m_pageId)) { data.updateImageParams(*params); } else { - ImageSettings::PageParams new_params(BinaryThreshold::otsuThreshold(data.grayImage()), true); + ImageSettings::PageParams new_params(BinaryThreshold::otsuThreshold(data.grayImage())); m_ptrImageSettings->setPageParams(m_pageId, new_params); data.updateImageParams(new_params); diff --git a/filters/output/OutputGenerator.cpp b/filters/output/OutputGenerator.cpp index 6331e9bd6..b5dd1f207 100644 --- a/filters/output/OutputGenerator.cpp +++ b/filters/output/OutputGenerator.cpp @@ -56,7 +56,6 @@ #include #include #include -#include #include "imageproc/OrthogonalRotation.h" using namespace imageproc; @@ -512,16 +511,13 @@ QImage OutputGenerator::processWithoutDewarping(const TaskStatus& status, const QPolygonF contentAreaInOriginalCs(m_xform.transformBack().map(contentArea)); const QPolygonF outCropAreaInOriginalCs(m_xform.transformBack().map(outCropArea)); - const GrayImage inputGrayImage = input.isBlackOnWhite() ? input.grayImage() : input.grayImage().inverted(); + const GrayImage inputGrayImage = input.grayImage(); const QImage inputOrigImage = [&input]() { QImage result = input.origImage(); if (!result.allGray() && (result.format() != QImage::Format_ARGB32) && (result.format() != QImage::Format_RGB32)) { result = result.convertToFormat(QImage::Format_RGB32); } - if (!input.isBlackOnWhite()) { - result.invertPixels(); - } return result; }(); @@ -616,10 +612,6 @@ QImage OutputGenerator::processWithoutDewarping(const TaskStatus& status, maybeDespeckleInPlace(dst, m_outRect, m_outRect, m_despeckleLevel, speckles_image, m_dpi, status, dbg); if (!render_params.needColorSegmentation()) { - if (!input.isBlackOnWhite()) { - dst.invert(); - } - applyFillZonesInPlace(dst, fill_zones); return dst.toQImage(); @@ -644,10 +636,6 @@ QImage OutputGenerator::processWithoutDewarping(const TaskStatus& status, status.throwIfCancelled(); - if (!input.isBlackOnWhite()) { - segmented_image.invertPixels(); - } - applyFillZonesInPlace(segmented_image, fill_zones, false); if (dbg) { @@ -814,7 +802,7 @@ QImage OutputGenerator::processWithoutDewarping(const TaskStatus& status, QColor outsideOriginalBackgroundColor = outsideBackgroundColor; if (m_colorParams.colorCommonOptions().getFillingColor() == FILL_WHITE) { - outsideOriginalBackgroundColor = input.isBlackOnWhite() ? Qt::white : Qt::black; + outsideOriginalBackgroundColor = Qt::white; } fillMarginsInPlace(original_background, contentAreaInWorkingCs, outsideOriginalBackgroundColor); original_background_dst.fill(outsideOriginalBackgroundColor); @@ -885,7 +873,7 @@ QImage OutputGenerator::processWithoutDewarping(const TaskStatus& status, if (render_params.needBinarization()) { outsideBackgroundColor = Qt::white; } else if (m_colorParams.colorCommonOptions().getFillingColor() == FILL_WHITE) { - outsideBackgroundColor = input.isBlackOnWhite() ? Qt::white : Qt::black; + outsideBackgroundColor = Qt::white; if (!render_params.needBinarization()) { reserveBlackAndWhite(maybe_normalized); } @@ -896,10 +884,6 @@ QImage OutputGenerator::processWithoutDewarping(const TaskStatus& status, drawOver(dst, contentRect, maybe_normalized, contentRectInWorkingCs); maybe_normalized = QImage(); - if (!input.isBlackOnWhite()) { - dst.invertPixels(); - } - if (render_params.mixedOutput() && render_params.needBinarization()) { applyFillZonesToMixedInPlace(dst, fill_zones, bw_content_mask_output, !render_params.needColorSegmentation()); } else { @@ -921,19 +905,11 @@ QImage OutputGenerator::processWithoutDewarping(const TaskStatus& status, splitImage->setBackgroundImage(dst); if (render_params.needBinarization() && render_params.originalBackground()) { - if (!input.isBlackOnWhite()) { - dst.invertPixels(); - } - BinaryImage background_mask = BinaryImage(dst, BinaryThreshold(255)).inverted(); fillMarginsInPlace(background_mask, m_xform.resultingPreCropArea(), BLACK); - applyMask(original_background, background_mask, input.isBlackOnWhite() ? WHITE : BLACK); - - applyMask(original_background, bw_content_mask_output, input.isBlackOnWhite() ? BLACK : WHITE); + applyMask(original_background, background_mask, WHITE); + applyMask(original_background, bw_content_mask_output, BLACK); - if (!input.isBlackOnWhite()) { - original_background.invertPixels(); - } splitImage->setOriginalBackgroundImage(original_background); } @@ -1008,16 +984,13 @@ QImage OutputGenerator::processWithDewarping(const TaskStatus& status, const QPolygonF contentAreaInOriginalCs(m_xform.transformBack().map(contentArea)); const QPolygonF outCropAreaInOriginalCs(m_xform.transformBack().map(outCropArea)); - const GrayImage inputGrayImage = input.isBlackOnWhite() ? input.grayImage() : input.grayImage().inverted(); + const GrayImage inputGrayImage = input.grayImage(); const QImage inputOrigImage = [&input]() { QImage result = input.origImage(); if (!result.allGray() && (result.format() != QImage::Format_ARGB32) && (result.format() != QImage::Format_RGB32)) { result = result.convertToFormat(QImage::Format_RGB32); } - if (!input.isBlackOnWhite()) { - result.invertPixels(); - } return result; }(); @@ -1471,10 +1444,6 @@ QImage OutputGenerator::processWithDewarping(const TaskStatus& status, status, dbg); if (!render_params.needColorSegmentation()) { - if (!input.isBlackOnWhite()) { - dewarped_bw_content.invert(); - } - applyFillZonesInPlace(dewarped_bw_content, fill_zones, orig_to_output, postTransform); return dewarped_bw_content.toQImage(); @@ -1489,10 +1458,6 @@ QImage OutputGenerator::processWithDewarping(const TaskStatus& status, status.throwIfCancelled(); - if (!input.isBlackOnWhite()) { - segmented_image.invertPixels(); - } - applyFillZonesInPlace(segmented_image, fill_zones, orig_to_output, postTransform, false); if (dbg) { @@ -1629,7 +1594,7 @@ QImage OutputGenerator::processWithDewarping(const TaskStatus& status, QColor outsideOriginalBackgroundColor = outsideBackgroundColor; if (m_colorParams.colorCommonOptions().getFillingColor() == FILL_WHITE) { - outsideOriginalBackgroundColor = input.isBlackOnWhite() ? Qt::white : Qt::black; + outsideOriginalBackgroundColor = Qt::white; } fillMarginsInPlace(original_background, dewarping_content_area_mask, outsideOriginalBackgroundColor); @@ -1681,17 +1646,13 @@ QImage OutputGenerator::processWithDewarping(const TaskStatus& status, if (render_params.needBinarization()) { outsideBackgroundColor = Qt::white; } else if (m_colorParams.colorCommonOptions().getFillingColor() == FILL_WHITE) { - outsideBackgroundColor = input.isBlackOnWhite() ? Qt::white : Qt::black; + outsideBackgroundColor = Qt::white; if (!render_params.needBinarization()) { reserveBlackAndWhite(dewarped); } } fillMarginsInPlace(dewarped, dewarping_content_area_mask, outsideBackgroundColor); - if (!input.isBlackOnWhite()) { - dewarped.invertPixels(); - } - if (render_params.mixedOutput() && render_params.needBinarization()) { applyFillZonesToMixedInPlace(dewarped, fill_zones, orig_to_output, postTransform, dewarped_bw_content_mask, !render_params.needColorSegmentation()); @@ -1714,19 +1675,11 @@ QImage OutputGenerator::processWithDewarping(const TaskStatus& status, splitImage->setBackgroundImage(dewarped); if (render_params.needBinarization() && render_params.originalBackground()) { - if (!input.isBlackOnWhite()) { - dewarped.invertPixels(); - } - BinaryImage background_mask = BinaryImage(dewarped, BinaryThreshold(255)).inverted(); fillMarginsInPlace(background_mask, dewarping_content_area_mask, BLACK); - applyMask(original_background, background_mask, input.isBlackOnWhite() ? WHITE : BLACK); - - applyMask(original_background, dewarped_bw_content_mask, input.isBlackOnWhite() ? BLACK : WHITE); + applyMask(original_background, background_mask, WHITE); + applyMask(original_background, dewarped_bw_content_mask, BLACK); - if (!input.isBlackOnWhite()) { - original_background.invertPixels(); - } splitImage->setOriginalBackgroundImage(original_background); } diff --git a/filters/select_content/ContentBoxFinder.cpp b/filters/select_content/ContentBoxFinder.cpp index 475bba264..559856123 100644 --- a/filters/select_content/ContentBoxFinder.cpp +++ b/filters/select_content/ContentBoxFinder.cpp @@ -92,11 +92,10 @@ QRectF ContentBoxFinder::findContentBox(const TaskStatus& status, return QRectF(); } - const GrayImage dataGrayImage = data.isBlackOnWhite() ? data.grayImage() : data.grayImage().inverted(); - const uint8_t darkest_gray_level = darkestGrayLevel(dataGrayImage); + const uint8_t darkest_gray_level = darkestGrayLevel(data.grayImage()); const QColor outside_color(darkest_gray_level, darkest_gray_level, darkest_gray_level); - QImage gray150(transformToGray(dataGrayImage, xform_150dpi.transform(), xform_150dpi.resultingRect().toRect(), + QImage gray150(transformToGray(data.grayImage(), xform_150dpi.transform(), xform_150dpi.resultingRect().toRect(), OutsidePixels::assumeColor(outside_color))); // Note that we fill new areas that appear as a result of // rotation with black, not white. Filling them with white diff --git a/filters/select_content/PageFinder.cpp b/filters/select_content/PageFinder.cpp index 69ffba359..7332136b4 100644 --- a/filters/select_content/PageFinder.cpp +++ b/filters/select_content/PageFinder.cpp @@ -55,11 +55,10 @@ QRectF PageFinder::findPageBox(const TaskStatus& status, std::cout << "exp_width = " << exp_width << "; exp_height" << exp_height << std::endl; #endif - const GrayImage dataGrayImage = data.isBlackOnWhite() ? data.grayImage() : data.grayImage().inverted(); - const uint8_t darkest_gray_level = darkestGrayLevel(dataGrayImage); + const uint8_t darkest_gray_level = darkestGrayLevel(data.grayImage()); const QColor outside_color(darkest_gray_level, darkest_gray_level, darkest_gray_level); - QImage gray150(transformToGray(dataGrayImage, xform_150dpi.transform(), xform_150dpi.resultingRect().toRect(), + QImage gray150(transformToGray(data.grayImage(), xform_150dpi.transform(), xform_150dpi.resultingRect().toRect(), OutsidePixels::assumeColor(outside_color))); if (dbg) { dbg->add(gray150, "gray150"); diff --git a/filters/select_content/Task.cpp b/filters/select_content/Task.cpp index baccd25bb..4ba6b0581 100644 --- a/filters/select_content/Task.cpp +++ b/filters/select_content/Task.cpp @@ -187,8 +187,7 @@ FilterResultPtr Task::process(const TaskStatus& status, const FilterData& data) ui_data.contentRect()); } else { return make_intrusive(m_ptrFilter, m_pageId, std::move(m_ptrDbg), data.origImage(), data.xform(), - data.isBlackOnWhite() ? data.grayImage() : data.grayImage().inverted(), - ui_data, m_batchProcessing); + data.grayImage(), ui_data, m_batchProcessing); } } // Task::process diff --git a/imageproc/BackgroundColorCalculator.cpp b/imageproc/BackgroundColorCalculator.cpp index fd01de170..e74d41114 100644 --- a/imageproc/BackgroundColorCalculator.cpp +++ b/imageproc/BackgroundColorCalculator.cpp @@ -170,7 +170,9 @@ QColor BackgroundColorCalculator::calcDominantBackgroundColor(const QImage& img) checkImageIsValid(img); BinaryImage background_mask(img, BinaryThreshold::otsuThreshold(img)); - background_mask.invert(); + if (2 * background_mask.countBlackPixels() <= (background_mask.width() * background_mask.height())) { + background_mask.invert(); + } return calcDominantColor(img, background_mask); } @@ -185,7 +187,9 @@ QColor BackgroundColorCalculator::calcDominantBackgroundColor(const QImage& img, } BinaryImage background_mask(img, BinaryThreshold::otsuThreshold(GrayscaleHistogram(img, mask))); - background_mask.invert(); + if (2 * background_mask.countBlackPixels() <= mask.countBlackPixels()) { + background_mask.invert(); + } rasterOp>(background_mask, mask); if (dbg) { dbg->add(background_mask, "background_mask"); From 08ab1e097ea39d2d015205e37659fe821fc86977 Mon Sep 17 00:00:00 2001 From: Alex <4lex49@zoho.com> Date: Mon, 9 Apr 2018 08:27:30 +0300 Subject: [PATCH 09/11] ~ Removed some old unused code. --- filters/page_layout/Task.h | 2 -- filters/select_content/Task.h | 2 -- imageproc/SavGolKernel.cpp | 4 ---- 3 files changed, 8 deletions(-) diff --git a/filters/page_layout/Task.h b/filters/page_layout/Task.h index 48f86a041..88ae84d22 100644 --- a/filters/page_layout/Task.h +++ b/filters/page_layout/Task.h @@ -59,8 +59,6 @@ class Task : public ref_countable { private: class UiUpdater; - void loadDefaultSettings(const Dpi& dpi); - intrusive_ptr m_ptrFilter; intrusive_ptr m_ptrNextTask; intrusive_ptr m_ptrSettings; diff --git a/filters/select_content/Task.h b/filters/select_content/Task.h index f52ca54ba..e6162b32b 100644 --- a/filters/select_content/Task.h +++ b/filters/select_content/Task.h @@ -59,8 +59,6 @@ class Task : public ref_countable { private: class UiUpdater; - void loadDefaultSettings(const Dpi& dpi); - intrusive_ptr m_ptrFilter; intrusive_ptr m_ptrNextTask; intrusive_ptr m_ptrSettings; diff --git a/imageproc/SavGolKernel.cpp b/imageproc/SavGolKernel.cpp index 83e6f2d96..21fa04bdf 100644 --- a/imageproc/SavGolKernel.cpp +++ b/imageproc/SavGolKernel.cpp @@ -25,10 +25,6 @@ #include #include -#ifdef _MSC_VER -#undef copysign // Just in case. -#define copysign _copysign -#endif namespace imageproc { namespace { From 822ba3f0fe2ab2b946cbef60b7c5d8788008a8e8 Mon Sep 17 00:00:00 2001 From: Alex <4lex49@zoho.com> Date: Mon, 9 Apr 2018 07:41:11 +0300 Subject: [PATCH 10/11] ~ Fixed: mixed pixels after cropping at page layout stage. (relates to 226d5ff478d04a0d341eac768524ef2316fb8553) --- filters/page_layout/CacheDrivenTask.cpp | 12 +++++++++++- filters/page_layout/CacheDrivenTask.h | 3 +++ filters/page_layout/Task.cpp | 13 +++++++++++-- filters/page_layout/Task.h | 3 +++ 4 files changed, 28 insertions(+), 3 deletions(-) diff --git a/filters/page_layout/CacheDrivenTask.cpp b/filters/page_layout/CacheDrivenTask.cpp index dc70abe6c..1129936cf 100644 --- a/filters/page_layout/CacheDrivenTask.cpp +++ b/filters/page_layout/CacheDrivenTask.cpp @@ -60,8 +60,9 @@ void CacheDrivenTask::process(const PageInfo& page_info, const QPolygonF page_rect_phys(Utils::calcPageRectPhys(xform, content_rect_phys, new_params, m_ptrSettings->getAggregateHardSizeMM(), m_ptrSettings->getAggregateContentRect())); + ImageTransformation new_xform(xform); - new_xform.setPostCropArea(xform.transform().map(page_rect_phys)); + new_xform.setPostCropArea(shiftToRoundedOrigin(new_xform.transform().map(page_rect_phys))); if (m_ptrNextTask) { m_ptrNextTask->process(page_info, collector, new_xform, content_rect_phys); @@ -80,4 +81,13 @@ void CacheDrivenTask::process(const PageInfo& page_info, m_ptrSettings->deviationProvider().isDeviant(page_info.id(), deviationCoef, deviationThreshold)))); } } // CacheDrivenTask::process + +QPolygonF CacheDrivenTask::shiftToRoundedOrigin(const QPolygonF& poly) { + const double x = poly.boundingRect().left(); + const double y = poly.boundingRect().top(); + const double shift_value_x = -(x - std::round(x)); + const double shift_value_y = -(y - std::round(y)); + + return poly.translated(shift_value_x, shift_value_y); +} } // namespace page_layout \ No newline at end of file diff --git a/filters/page_layout/CacheDrivenTask.h b/filters/page_layout/CacheDrivenTask.h index 7c5d15561..bf0b97836 100644 --- a/filters/page_layout/CacheDrivenTask.h +++ b/filters/page_layout/CacheDrivenTask.h @@ -22,6 +22,7 @@ #include "NonCopyable.h" #include "ref_countable.h" #include "intrusive_ptr.h" +#include class QRectF; class PageInfo; @@ -50,6 +51,8 @@ class CacheDrivenTask : public ref_countable { const QRectF& content_rect); private: + static QPolygonF shiftToRoundedOrigin(const QPolygonF& poly); + intrusive_ptr m_ptrNextTask; intrusive_ptr m_ptrSettings; }; diff --git a/filters/page_layout/Task.cpp b/filters/page_layout/Task.cpp index 793ae8110..ccedc78a7 100644 --- a/filters/page_layout/Task.cpp +++ b/filters/page_layout/Task.cpp @@ -104,7 +104,7 @@ FilterResultPtr Task::process(const TaskStatus& status, m_ptrSettings->getAggregateContentRect())); ImageTransformation new_xform(data.xform()); - new_xform.setPostCropArea(new_xform.transform().map(page_rect_phys)); + new_xform.setPostCropArea(shiftToRoundedOrigin(new_xform.transform().map(page_rect_phys))); return m_ptrNextTask->process(status, FilterData(data, new_xform), content_rect_phys); } else { @@ -112,7 +112,16 @@ FilterResultPtr Task::process(const TaskStatus& status, adapted_content_rect, agg_hard_size_before != agg_hard_size_after, m_batchProcessing); } -} // Task::process +} + +QPolygonF Task::shiftToRoundedOrigin(const QPolygonF& poly) { + const double x = poly.boundingRect().left(); + const double y = poly.boundingRect().top(); + const double shift_value_x = -(x - std::round(x)); + const double shift_value_y = -(y - std::round(y)); + + return poly.translated(shift_value_x, shift_value_y); +} /*============================ Task::UiUpdater ==========================*/ diff --git a/filters/page_layout/Task.h b/filters/page_layout/Task.h index 88ae84d22..7d742dc99 100644 --- a/filters/page_layout/Task.h +++ b/filters/page_layout/Task.h @@ -23,6 +23,7 @@ #include "ref_countable.h" #include "FilterResult.h" #include "PageId.h" +#include class TaskStatus; class FilterData; @@ -59,6 +60,8 @@ class Task : public ref_countable { private: class UiUpdater; + static QPolygonF shiftToRoundedOrigin(const QPolygonF& poly); + intrusive_ptr m_ptrFilter; intrusive_ptr m_ptrNextTask; intrusive_ptr m_ptrSettings; From 2937ffea62ef383c8844464bc563cb9f04cb878f Mon Sep 17 00:00:00 2001 From: Alex <4lex49@zoho.com> Date: Mon, 9 Apr 2018 07:43:40 +0300 Subject: [PATCH 11/11] ~ Update VERSION. --- version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.h b/version.h index a1babed11..e3243c85a 100644 --- a/version.h +++ b/version.h @@ -19,7 +19,7 @@ #ifndef SCANTAILOR_VERSION_H_ #define SCANTAILOR_VERSION_H_ -#define VERSION "1.0.13" +#define VERSION "1.0.14" #define VERSION_QUAD "" // Must be "x.x.x.x" or an empty string. #define PROJECT_VERSION 2