<commit_before>/// \file
/// \ingroup tutorial_roofit
/// \notebook -js
/// Validation and MC studies: a simple Toy Monte Carlo study
///
/// \macro_image
/// \macro_output
/// \macro_code
/// \author

#include "RooRealVar.h"
#include "RooDataSet.h"
#include "RooGaussian.h"
#include "RooConstVar.h"
#include "RooChebychev.h"
#include "RooAddPdf.h"
#include "RooMCStudy.h"
#include "RooPlot.h"
#include "TCanvas.h"
#include "TAxis.h"
#include "TH2.h"
#include "RooFitResult.h"
#include "TStyle.h"
#include "TDirectory.h"

using namespace RooFit;

void rf801_mcstudy()
{
   // C r e a t e   m o d e l
   // -----------------------

   // Declare observable x
   RooRealVar x("x", "x", 0, 10);
   x.setBins(40);

   // Create two Gaussian PDFs g1(x,mean1,sigma) anf g2(x,mean2,sigma) and their parameters
   RooRealVar mean("mean", "mean of gaussians", 5, 0, 10);
   RooRealVar sigma1("sigma1", "width of gaussians", 0.5);
   RooRealVar sigma2("sigma2", "width of gaussians", 1);

   RooGaussian sig1("sig1", "Signal component 1", x, mean, sigma1);
   RooGaussian sig2("sig2", "Signal component 2", x, mean, sigma2);

   // Build Chebychev polynomial p.d.f.
   RooRealVar a0("a0", "a0", 0.5, 0., 1.);
   RooRealVar a1("a1", "a1", -0.2, -1, 1.);
   RooChebychev bkg("bkg", "Background", x, RooArgSet(a0, a1));

   // Sum the signal components into a composite signal p.d.f.
   RooRealVar sig1frac("sig1frac", "fraction of component 1 in signal", 0.8, 0., 1.);
   RooAddPdf sig("sig", "Signal", RooArgList(sig1, sig2), sig1frac);

   // Sum the composite signal and background
   RooRealVar nbkg("nbkg", "number of background events,", 150, 0, 1000);
   RooRealVar nsig("nsig", "number of signal events", 150, 0, 1000);
   RooAddPdf model("model", "g1+g2+a", RooArgList(bkg, sig), RooArgList(nbkg, nsig));

   // C r e a t e   m a n a g e r
   // ---------------------------

   // Instantiate RooMCStudy manager on model with x as observable and given choice of fit options
   //
   // The Silence() option kills all messages below the PROGRESS level, leaving only a single message
   // per sample executed, and any error message that occur during fitting
   //
   // The Extended() option has two effects:
   //    1) The extended ML term is included in the likelihood and
   //    2) A poisson fluctuation is introduced on the number of generated events
   //
   // The FitOptions() given here are passed to the fitting stage of each toy experiment.
   // If Save() is specified, the fit result of each experiment is saved by the manager
   //
   // A Binned() option is added in this example to bin the data between generation and fitting
   // to speed up the study at the expense of some precision

   RooMCStudy *mcstudy =
      new RooMCStudy(model, x, Binned(kTRUE), Silence(), Extended(), FitOptions(Save(kTRUE), PrintEvalErrors(0)));

   // G e n e r a t e   a n d   f i t   e v e n t s
   // ---------------------------------------------

   // Generate and fit 1000 samples of Poisson(nExpected) events
   mcstudy->generateAndFit(1000);

   // E x p l o r e   r e s u l t s   o f   s t u d y
   // ------------------------------------------------

   // Make plots of the distributions of mean, the error on mean and the pull of mean
   RooPlot *frame1 = mcstudy->plotParam(mean, Bins(40));
   RooPlot *frame2 = mcstudy->plotError(mean, Bins(40));
   RooPlot *frame3 = mcstudy->plotPull(mean, Bins(40), FitGauss(kTRUE));

   // Plot distribution of minimized likelihood
   RooPlot *frame4 = mcstudy->plotNLL(Bins(40));

   // Make some histograms from the parameter dataset
   TH1 *hh_cor_a0_s1f = mcstudy->fitParDataSet().createHistogram("hh", a1, YVar(sig1frac));
   TH1 *hh_cor_a0_a1 = mcstudy->fitParDataSet().createHistogram("hh", a0, YVar(a1));

   // Access some of the saved fit results from individual toys
   TH2 *corrHist000 = mcstudy->fitResult(0)->correlationHist("c000");
   TH2 *corrHist127 = mcstudy->fitResult(127)->correlationHist("c127");
   TH2 *corrHist953 = mcstudy->fitResult(953)->correlationHist("c953");

   // Draw all plots on a canvas
   gStyle->SetOptStat(0);
   TCanvas *c = new TCanvas("rf801_mcstudy", "rf801_mcstudy", 900, 900);
   c->Divide(3, 3);
   c->cd(1);
   gPad->SetLeftMargin(0.15);
   frame1->GetYaxis()->SetTitleOffset(1.4);
   frame1->Draw();
   c->cd(2);
   gPad->SetLeftMargin(0.15);
   frame2->GetYaxis()->SetTitleOffset(1.4);
   frame2->Draw();
   c->cd(3);
   gPad->SetLeftMargin(0.15);
   frame3->GetYaxis()->SetTitleOffset(1.4);
   frame3->Draw();
   c->cd(4);
   gPad->SetLeftMargin(0.15);
   frame4->GetYaxis()->SetTitleOffset(1.4);
   frame4->Draw();
   c->cd(5);
   gPad->SetLeftMargin(0.15);
   hh_cor_a0_s1f->GetYaxis()->SetTitleOffset(1.4);
   hh_cor_a0_s1f->Draw("box");
   c->cd(6);
   gPad->SetLeftMargin(0.15);
   hh_cor_a0_a1->GetYaxis()->SetTitleOffset(1.4);
   hh_cor_a0_a1->Draw("box");
   c->cd(7);
   gPad->SetLeftMargin(0.15);
   corrHist000->GetYaxis()->SetTitleOffset(1.4);
   corrHist000->Draw("colz");
   c->cd(8);
   gPad->SetLeftMargin(0.15);
   corrHist127->GetYaxis()->SetTitleOffset(1.4);
   corrHist127->Draw("colz");
   c->cd(9);
   gPad->SetLeftMargin(0.15);
   corrHist953->GetYaxis()->SetTitleOffset(1.4);
   corrHist953->Draw("colz");

   // Make RooMCStudy object available on command line after
   // macro finishes
   gDirectory->Add(mcstudy);
}
<commit_msg>[RF][NFC] Complete tutorial description<commit_after>/// \file
/// \ingroup tutorial_roofit
/// \notebook -js
/// Validation and MC studies: toy Monte Carlo study that perform cycles of event generation and fitting
///
/// \macro_image
/// \macro_output
/// \macro_code
/// \author

#include "RooRealVar.h"
#include "RooDataSet.h"
#include "RooGaussian.h"
#include "RooConstVar.h"
#include "RooChebychev.h"
#include "RooAddPdf.h"
#include "RooMCStudy.h"
#include "RooPlot.h"
#include "TCanvas.h"
#include "TAxis.h"
#include "TH2.h"
#include "RooFitResult.h"
#include "TStyle.h"
#include "TDirectory.h"

using namespace RooFit;

void rf801_mcstudy()
{
   // C r e a t e   m o d e l
   // -----------------------

   // Declare observable x
   RooRealVar x("x", "x", 0, 10);
   x.setBins(40);

   // Create two Gaussian PDFs g1(x,mean1,sigma) anf g2(x,mean2,sigma) and their parameters
   RooRealVar mean("mean", "mean of gaussians", 5, 0, 10);
   RooRealVar sigma1("sigma1", "width of gaussians", 0.5);
   RooRealVar sigma2("sigma2", "width of gaussians", 1);

   RooGaussian sig1("sig1", "Signal component 1", x, mean, sigma1);
   RooGaussian sig2("sig2", "Signal component 2", x, mean, sigma2);

   // Build Chebychev polynomial p.d.f.
   RooRealVar a0("a0", "a0", 0.5, 0., 1.);
   RooRealVar a1("a1", "a1", -0.2, -1, 1.);
   RooChebychev bkg("bkg", "Background", x, RooArgSet(a0, a1));

   // Sum the signal components into a composite signal p.d.f.
   RooRealVar sig1frac("sig1frac", "fraction of component 1 in signal", 0.8, 0., 1.);
   RooAddPdf sig("sig", "Signal", RooArgList(sig1, sig2), sig1frac);

   // Sum the composite signal and background
   RooRealVar nbkg("nbkg", "number of background events,", 150, 0, 1000);
   RooRealVar nsig("nsig", "number of signal events", 150, 0, 1000);
   RooAddPdf model("model", "g1+g2+a", RooArgList(bkg, sig), RooArgList(nbkg, nsig));

   // C r e a t e   m a n a g e r
   // ---------------------------

   // Instantiate RooMCStudy manager on model with x as observable and given choice of fit options
   //
   // The Silence() option kills all messages below the PROGRESS level, leaving only a single message
   // per sample executed, and any error message that occur during fitting
   //
   // The Extended() option has two effects:
   //    1) The extended ML term is included in the likelihood and
   //    2) A poisson fluctuation is introduced on the number of generated events
   //
   // The FitOptions() given here are passed to the fitting stage of each toy experiment.
   // If Save() is specified, the fit result of each experiment is saved by the manager
   //
   // A Binned() option is added in this example to bin the data between generation and fitting
   // to speed up the study at the expense of some precision

   RooMCStudy *mcstudy =
      new RooMCStudy(model, x, Binned(kTRUE), Silence(), Extended(), FitOptions(Save(kTRUE), PrintEvalErrors(0)));

   // G e n e r a t e   a n d   f i t   e v e n t s
   // ---------------------------------------------

   // Generate and fit 1000 samples of Poisson(nExpected) events
   mcstudy->generateAndFit(1000);

   // E x p l o r e   r e s u l t s   o f   s t u d y
   // ------------------------------------------------

   // Make plots of the distributions of mean, the error on mean and the pull of mean
   RooPlot *frame1 = mcstudy->plotParam(mean, Bins(40));
   RooPlot *frame2 = mcstudy->plotError(mean, Bins(40));
   RooPlot *frame3 = mcstudy->plotPull(mean, Bins(40), FitGauss(kTRUE));

   // Plot distribution of minimized likelihood
   RooPlot *frame4 = mcstudy->plotNLL(Bins(40));

   // Make some histograms from the parameter dataset
   TH1 *hh_cor_a0_s1f = mcstudy->fitParDataSet().createHistogram("hh", a1, YVar(sig1frac));
   TH1 *hh_cor_a0_a1 = mcstudy->fitParDataSet().createHistogram("hh", a0, YVar(a1));

   // Access some of the saved fit results from individual toys
   TH2 *corrHist000 = mcstudy->fitResult(0)->correlationHist("c000");
   TH2 *corrHist127 = mcstudy->fitResult(127)->correlationHist("c127");
   TH2 *corrHist953 = mcstudy->fitResult(953)->correlationHist("c953");

   // Draw all plots on a canvas
   gStyle->SetOptStat(0);
   TCanvas *c = new TCanvas("rf801_mcstudy", "rf801_mcstudy", 900, 900);
   c->Divide(3, 3);
   c->cd(1);
   gPad->SetLeftMargin(0.15);
   frame1->GetYaxis()->SetTitleOffset(1.4);
   frame1->Draw();
   c->cd(2);
   gPad->SetLeftMargin(0.15);
   frame2->GetYaxis()->SetTitleOffset(1.4);
   frame2->Draw();
   c->cd(3);
   gPad->SetLeftMargin(0.15);
   frame3->GetYaxis()->SetTitleOffset(1.4);
   frame3->Draw();
   c->cd(4);
   gPad->SetLeftMargin(0.15);
   frame4->GetYaxis()->SetTitleOffset(1.4);
   frame4->Draw();
   c->cd(5);
   gPad->SetLeftMargin(0.15);
   hh_cor_a0_s1f->GetYaxis()->SetTitleOffset(1.4);
   hh_cor_a0_s1f->Draw("box");
   c->cd(6);
   gPad->SetLeftMargin(0.15);
   hh_cor_a0_a1->GetYaxis()->SetTitleOffset(1.4);
   hh_cor_a0_a1->Draw("box");
   c->cd(7);
   gPad->SetLeftMargin(0.15);
   corrHist000->GetYaxis()->SetTitleOffset(1.4);
   corrHist000->Draw("colz");
   c->cd(8);
   gPad->SetLeftMargin(0.15);
   corrHist127->GetYaxis()->SetTitleOffset(1.4);
   corrHist127->Draw("colz");
   c->cd(9);
   gPad->SetLeftMargin(0.15);
   corrHist953->GetYaxis()->SetTitleOffset(1.4);
   corrHist953->Draw("colz");

   // Make RooMCStudy object available on command line after
   // macro finishes
   gDirectory->Add(mcstudy);
}
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include <canvas/debug.hxx>
#include <canvas/canvastools.hxx>
#include <tools/diagnose_ex.h>

#include "cairo_canvasbitmap.hxx"

#ifdef CAIRO_HAS_XLIB_SURFACE
# include "cairo_xlib_cairo.hxx"
#elif defined CAIRO_HAS_QUARTZ_SURFACE
# include "cairo_quartz_cairo.hxx"
#elif defined CAIRO_HAS_WIN32_SURFACE
# include "cairo_win32_cairo.hxx"
# include <cairo-win32.h>
#else
# error Native API needed.
#endif

using namespace ::cairo;
using namespace ::com::sun::star;

#ifdef CAIRO_HAS_WIN32_SURFACE
namespace
{
    HBITMAP surface2HBitmap( const SurfaceSharedPtr& rSurface, const basegfx::B2ISize& rSize )
    {
        // cant seem to retrieve HBITMAP from cairo. copy content then
        HDC hScreenDC=GetDC(NULL);
        HBITMAP hBmpBitmap = CreateCompatibleBitmap( hScreenDC,
                                                     rSize.getX(),
                                                     rSize.getY() );

        HDC     hBmpDC = CreateCompatibleDC( 0 );
        HBITMAP hBmpOld = (HBITMAP) SelectObject( hBmpDC, hBmpBitmap );

        BitBlt( hBmpDC, 0, 0, rSize.getX(), rSize.getX(),
                cairo_win32_surface_get_dc(rSurface->getCairoSurface().get()),
                0, 0, SRCCOPY );

        SelectObject( hBmpDC, hBmpOld );
        DeleteDC( hBmpDC );

        return hBmpBitmap;
    }
}
#endif

namespace cairocanvas
{
    CanvasBitmap::CanvasBitmap( const ::basegfx::B2ISize&  rSize,
                                const SurfaceProviderRef&  rSurfaceProvider,
                                rendering::XGraphicDevice* pDevice,
                                bool                       bHasAlpha ) :
        mpSurfaceProvider( rSurfaceProvider ),
        mpBufferSurface(),
        mpBufferCairo(),
        maSize(rSize),
        mbHasAlpha(bHasAlpha)
    {
        ENSURE_OR_THROW( mpSurfaceProvider.is(),
                          "CanvasBitmap::CanvasBitmap(): Invalid surface or device" );

        OSL_TRACE( "bitmap size: %dx%d", rSize.getX(), rSize.getY() );

        mpBufferSurface = mpSurfaceProvider->createSurface( rSize, bHasAlpha ? CAIRO_CONTENT_COLOR_ALPHA : CAIRO_CONTENT_COLOR );
        mpBufferCairo = mpBufferSurface->getCairo();

        maCanvasHelper.init( rSize, *mpSurfaceProvider, pDevice );
        maCanvasHelper.setSurface( mpBufferSurface, bHasAlpha );

        // clear bitmap to 100% transparent
        maCanvasHelper.clear();
    }

    void CanvasBitmap::disposeThis()
    {
        mpSurfaceProvider.clear();

        mpBufferCairo.reset();
        mpBufferSurface.reset();

        // forward to parent
        CanvasBitmap_Base::disposeThis();
    }

    SurfaceSharedPtr CanvasBitmap::getSurface()
    {
        return mpBufferSurface;
    }

    SurfaceSharedPtr CanvasBitmap::createSurface( const ::basegfx::B2ISize& rSize, Content aContent )
    {
        return mpSurfaceProvider->createSurface(rSize,aContent);
    }

    SurfaceSharedPtr CanvasBitmap::createSurface( ::Bitmap& rBitmap )
    {
        return mpSurfaceProvider->createSurface(rBitmap);
    }

    SurfaceSharedPtr CanvasBitmap::changeSurface( bool, bool )
    {
        // non-modifiable surface here
        return SurfaceSharedPtr();
    }

    OutputDevice* CanvasBitmap::getOutputDevice()
    {
        return mpSurfaceProvider->getOutputDevice();
    }

    bool CanvasBitmap::repaint( const SurfaceSharedPtr&       pSurface,
                                const rendering::ViewState&   viewState,
                                const rendering::RenderState& renderState )
    {
        return maCanvasHelper.repaint( pSurface, viewState, renderState );
    }

        void SAL_CALL CanvasBitmap::setFastPropertyValue( sal_Int32 nHandle, const ::com::sun::star::uno::Any& rAny )  throw (uno::RuntimeException)
    {
        sal_Int64 nPointer = 0;

        if ( nHandle == 0 )
        {
            rAny >>= nPointer;

            if ( nPointer )
            {
                ::Bitmap *pBitmap = reinterpret_cast< ::Bitmap* >( nPointer );

                mpBufferSurface = createSurface( *pBitmap );
                mpBufferCairo = mpBufferSurface->getCairo();

                ::Size aSize( pBitmap->GetSizePixel() );
                maSize = ::basegfx::B2ISize( aSize.getWidth(), aSize.getHeight() );

                maCanvasHelper.setSize( maSize );
                maCanvasHelper.setSurface( mpBufferSurface, mbHasAlpha );
            }
        }
    }

    uno::Any SAL_CALL CanvasBitmap::getFastPropertyValue( sal_Int32 nHandle )  throw (uno::RuntimeException)
    {
        uno::Any aRV( sal_Int32(0) );
        // 0 ... get BitmapEx
        // 1 ... get Pixbuf with bitmap RGB content
        // 2 ... get Pixbuf with bitmap alpha mask
        switch( nHandle )
        {
            case 0:
            {
                aRV = uno::Any( reinterpret_cast<sal_Int64>( (BitmapEx*) NULL ) );
                break;
            }
            case 1:
            {
#ifdef CAIRO_HAS_XLIB_SURFACE
                X11Surface* pXlibSurface=dynamic_cast<X11Surface*>(mpBufferSurface.get());
                OSL_ASSERT(pXlibSurface);
                uno::Sequence< uno::Any > args( 4 );
                args[0] = uno::Any( false );  // do not call XFreePixmap on it
                args[1] = uno::Any( pXlibSurface->getPixmap()->mhDrawable );
                args[2] = uno::Any( sal_Int32( pXlibSurface->getDepth() ) );
                args[3] = uno::Any( sal_Int64( pXlibSurface->getVisual () ) );

                aRV = uno::Any( args );
#elif defined CAIRO_HAS_QUARTZ_SURFACE
                QuartzSurface* pQuartzSurface = dynamic_cast<QuartzSurface*>(mpBufferSurface.get());
                OSL_ASSERT(pQuartzSurface);
                uno::Sequence< uno::Any > args( 1 );
                args[0] = uno::Any( sal_IntPtr (pQuartzSurface->getCGContext()) );
                aRV = uno::Any( args );
#elif defined CAIRO_HAS_WIN32_SURFACE
                // TODO(F2): check whether under all circumstances,
                // the alpha channel is ignored here.
                uno::Sequence< uno::Any > args( 1 );
                args[1] = uno::Any( sal_Int64(surface2HBitmap(mpBufferSurface,maSize)) );

                aRV = uno::Any( args );
                // caller frees the bitmap
#else
# error Please define fast prop retrieval for your platform!
#endif
                break;
            }
            case 2:
            {
#ifdef CAIRO_HAS_XLIB_SURFACE
                uno::Sequence< uno::Any > args( 4 );
                SurfaceSharedPtr pAlphaSurface = mpSurfaceProvider->createSurface( maSize, CAIRO_CONTENT_COLOR );
                CairoSharedPtr   pAlphaCairo = pAlphaSurface->getCairo();
                X11Surface* pXlibSurface=dynamic_cast<X11Surface*>(pAlphaSurface.get());
                OSL_ASSERT(pXlibSurface);

                // create RGB image (levels of gray) of alpha channel of original picture
                cairo_set_source_rgba( pAlphaCairo.get(), 1, 1, 1, 1 );
                cairo_set_operator( pAlphaCairo.get(), CAIRO_OPERATOR_SOURCE );
                cairo_paint( pAlphaCairo.get() );
                cairo_set_source_surface( pAlphaCairo.get(), mpBufferSurface->getCairoSurface().get(), 0, 0 );
                cairo_set_operator( pAlphaCairo.get(), CAIRO_OPERATOR_XOR );
                cairo_paint( pAlphaCairo.get() );
                pAlphaCairo.reset();

                X11PixmapSharedPtr pPixmap = pXlibSurface->getPixmap();
                args[0] = uno::Any( true );
                args[1] = ::com::sun::star::uno::Any( pPixmap->mhDrawable );
                args[2] = ::com::sun::star::uno::Any( sal_Int32( pXlibSurface->getDepth () ) );
                args[3] = ::com::sun::star::uno::Any( sal_Int64( pXlibSurface->getVisual () ) );
                pPixmap->clear(); // caller takes ownership of pixmap

                // return pixmap and alphachannel pixmap - it will be used in BitmapEx
                aRV = uno::Any( args );
#elif defined CAIRO_HAS_QUARTZ_SURFACE
                SurfaceSharedPtr pAlphaSurface = mpSurfaceProvider->createSurface( maSize, CAIRO_CONTENT_COLOR );
                CairoSharedPtr   pAlphaCairo = pAlphaSurface->getCairo();
                QuartzSurface* pQuartzSurface=dynamic_cast<QuartzSurface*>(pAlphaSurface.get());
                OSL_ASSERT(pQuartzSurface);

                // create RGB image (levels of gray) of alpha channel of original picture
                cairo_set_source_rgba( pAlphaCairo.get(), 1, 1, 1, 1 );
                cairo_set_operator( pAlphaCairo.get(), CAIRO_OPERATOR_SOURCE );
                cairo_paint( pAlphaCairo.get() );
                cairo_set_source_surface( pAlphaCairo.get(), mpBufferSurface->getCairoSurface().get(), 0, 0 );
                cairo_set_operator( pAlphaCairo.get(), CAIRO_OPERATOR_XOR );
                cairo_paint( pAlphaCairo.get() );
                pAlphaCairo.reset();

                uno::Sequence< uno::Any > args( 1 );
                args[0] = uno::Any( sal_IntPtr (pQuartzSurface->getCGContext()) );
                // return ??? and alphachannel ??? - it will be used in BitmapEx
                aRV = uno::Any( args );
#elif defined CAIRO_HAS_WIN32_SURFACE
                SurfaceSharedPtr pAlphaSurface = mpSurfaceProvider->createSurface( maSize, CAIRO_CONTENT_COLOR );
                CairoSharedPtr   pAlphaCairo = pAlphaSurface->getCairo();

                // create RGB image (levels of gray) of alpha channel of original picture
                cairo_set_source_rgba( pAlphaCairo.get(), 1, 1, 1, 1 );
                cairo_set_operator( pAlphaCairo.get(), CAIRO_OPERATOR_SOURCE );
                cairo_paint( pAlphaCairo.get() );
                cairo_set_source_surface( pAlphaCairo.get(), mpBufferSurface->getCairoSurface().get(), 0, 0 );
                cairo_set_operator( pAlphaCairo.get(), CAIRO_OPERATOR_XOR );
                cairo_paint( pAlphaCairo.get() );
                pAlphaCairo.reset();

                // cant seem to retrieve HBITMAP from cairo. copy content then
                uno::Sequence< uno::Any > args( 1 );
                args[1] = uno::Any( sal_Int64(surface2HBitmap(pAlphaSurface,maSize)) );

                aRV = uno::Any( args );
                // caller frees the bitmap
#else
# error Please define fast prop retrieval for your platform!
#endif
                break;
            }
        }

        return aRV;
    }

#define IMPLEMENTATION_NAME "CairoCanvas.CanvasBitmap"
#define SERVICE_NAME "com.sun.star.rendering.CanvasBitmap"

    OUString SAL_CALL CanvasBitmap::getImplementationName(  ) throw (uno::RuntimeException)
    {
        return OUString( IMPLEMENTATION_NAME );
    }

    sal_Bool SAL_CALL CanvasBitmap::supportsService( const OUString& ServiceName ) throw (uno::RuntimeException)
    {
        return ServiceName == SERVICE_NAME;
    }

    uno::Sequence< OUString > SAL_CALL CanvasBitmap::getSupportedServiceNames(  ) throw (uno::RuntimeException)
    {
        uno::Sequence< OUString > aRet(1);
        aRet[0] = SERVICE_NAME;

        return aRet;
    }

}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>Fix indent.<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include <canvas/debug.hxx>
#include <canvas/canvastools.hxx>
#include <tools/diagnose_ex.h>

#include "cairo_canvasbitmap.hxx"

#ifdef CAIRO_HAS_XLIB_SURFACE
# include "cairo_xlib_cairo.hxx"
#elif defined CAIRO_HAS_QUARTZ_SURFACE
# include "cairo_quartz_cairo.hxx"
#elif defined CAIRO_HAS_WIN32_SURFACE
# include "cairo_win32_cairo.hxx"
# include <cairo-win32.h>
#else
# error Native API needed.
#endif

using namespace ::cairo;
using namespace ::com::sun::star;

#ifdef CAIRO_HAS_WIN32_SURFACE
namespace
{
    HBITMAP surface2HBitmap( const SurfaceSharedPtr& rSurface, const basegfx::B2ISize& rSize )
    {
        // cant seem to retrieve HBITMAP from cairo. copy content then
        HDC hScreenDC=GetDC(NULL);
        HBITMAP hBmpBitmap = CreateCompatibleBitmap( hScreenDC,
                                                     rSize.getX(),
                                                     rSize.getY() );

        HDC     hBmpDC = CreateCompatibleDC( 0 );
        HBITMAP hBmpOld = (HBITMAP) SelectObject( hBmpDC, hBmpBitmap );

        BitBlt( hBmpDC, 0, 0, rSize.getX(), rSize.getX(),
                cairo_win32_surface_get_dc(rSurface->getCairoSurface().get()),
                0, 0, SRCCOPY );

        SelectObject( hBmpDC, hBmpOld );
        DeleteDC( hBmpDC );

        return hBmpBitmap;
    }
}
#endif

namespace cairocanvas
{
    CanvasBitmap::CanvasBitmap( const ::basegfx::B2ISize&  rSize,
                                const SurfaceProviderRef&  rSurfaceProvider,
                                rendering::XGraphicDevice* pDevice,
                                bool                       bHasAlpha ) :
        mpSurfaceProvider( rSurfaceProvider ),
        mpBufferSurface(),
        mpBufferCairo(),
        maSize(rSize),
        mbHasAlpha(bHasAlpha)
    {
        ENSURE_OR_THROW( mpSurfaceProvider.is(),
                          "CanvasBitmap::CanvasBitmap(): Invalid surface or device" );

        OSL_TRACE( "bitmap size: %dx%d", rSize.getX(), rSize.getY() );

        mpBufferSurface = mpSurfaceProvider->createSurface( rSize, bHasAlpha ? CAIRO_CONTENT_COLOR_ALPHA : CAIRO_CONTENT_COLOR );
        mpBufferCairo = mpBufferSurface->getCairo();

        maCanvasHelper.init( rSize, *mpSurfaceProvider, pDevice );
        maCanvasHelper.setSurface( mpBufferSurface, bHasAlpha );

        // clear bitmap to 100% transparent
        maCanvasHelper.clear();
    }

    void CanvasBitmap::disposeThis()
    {
        mpSurfaceProvider.clear();

        mpBufferCairo.reset();
        mpBufferSurface.reset();

        // forward to parent
        CanvasBitmap_Base::disposeThis();
    }

    SurfaceSharedPtr CanvasBitmap::getSurface()
    {
        return mpBufferSurface;
    }

    SurfaceSharedPtr CanvasBitmap::createSurface( const ::basegfx::B2ISize& rSize, Content aContent )
    {
        return mpSurfaceProvider->createSurface(rSize,aContent);
    }

    SurfaceSharedPtr CanvasBitmap::createSurface( ::Bitmap& rBitmap )
    {
        return mpSurfaceProvider->createSurface(rBitmap);
    }

    SurfaceSharedPtr CanvasBitmap::changeSurface( bool, bool )
    {
        // non-modifiable surface here
        return SurfaceSharedPtr();
    }

    OutputDevice* CanvasBitmap::getOutputDevice()
    {
        return mpSurfaceProvider->getOutputDevice();
    }

    bool CanvasBitmap::repaint( const SurfaceSharedPtr&       pSurface,
                                const rendering::ViewState&   viewState,
                                const rendering::RenderState& renderState )
    {
        return maCanvasHelper.repaint( pSurface, viewState, renderState );
    }

    void SAL_CALL CanvasBitmap::setFastPropertyValue( sal_Int32 nHandle, const ::com::sun::star::uno::Any& rAny )  throw (uno::RuntimeException)
    {
        sal_Int64 nPointer = 0;

        if ( nHandle == 0 )
        {
            rAny >>= nPointer;

            if ( nPointer )
            {
                ::Bitmap *pBitmap = reinterpret_cast< ::Bitmap* >( nPointer );

                mpBufferSurface = createSurface( *pBitmap );
                mpBufferCairo = mpBufferSurface->getCairo();

                ::Size aSize( pBitmap->GetSizePixel() );
                maSize = ::basegfx::B2ISize( aSize.getWidth(), aSize.getHeight() );

                maCanvasHelper.setSize( maSize );
                maCanvasHelper.setSurface( mpBufferSurface, mbHasAlpha );
            }
        }
    }

    uno::Any SAL_CALL CanvasBitmap::getFastPropertyValue( sal_Int32 nHandle )  throw (uno::RuntimeException)
    {
        uno::Any aRV( sal_Int32(0) );
        // 0 ... get BitmapEx
        // 1 ... get Pixbuf with bitmap RGB content
        // 2 ... get Pixbuf with bitmap alpha mask
        switch( nHandle )
        {
            case 0:
            {
                aRV = uno::Any( reinterpret_cast<sal_Int64>( (BitmapEx*) NULL ) );
                break;
            }
            case 1:
            {
#ifdef CAIRO_HAS_XLIB_SURFACE
                X11Surface* pXlibSurface=dynamic_cast<X11Surface*>(mpBufferSurface.get());
                OSL_ASSERT(pXlibSurface);
                uno::Sequence< uno::Any > args( 4 );
                args[0] = uno::Any( false );  // do not call XFreePixmap on it
                args[1] = uno::Any( pXlibSurface->getPixmap()->mhDrawable );
                args[2] = uno::Any( sal_Int32( pXlibSurface->getDepth() ) );
                args[3] = uno::Any( sal_Int64( pXlibSurface->getVisual () ) );

                aRV = uno::Any( args );
#elif defined CAIRO_HAS_QUARTZ_SURFACE
                QuartzSurface* pQuartzSurface = dynamic_cast<QuartzSurface*>(mpBufferSurface.get());
                OSL_ASSERT(pQuartzSurface);
                uno::Sequence< uno::Any > args( 1 );
                args[0] = uno::Any( sal_IntPtr (pQuartzSurface->getCGContext()) );
                aRV = uno::Any( args );
#elif defined CAIRO_HAS_WIN32_SURFACE
                // TODO(F2): check whether under all circumstances,
                // the alpha channel is ignored here.
                uno::Sequence< uno::Any > args( 1 );
                args[1] = uno::Any( sal_Int64(surface2HBitmap(mpBufferSurface,maSize)) );

                aRV = uno::Any( args );
                // caller frees the bitmap
#else
# error Please define fast prop retrieval for your platform!
#endif
                break;
            }
            case 2:
            {
#ifdef CAIRO_HAS_XLIB_SURFACE
                uno::Sequence< uno::Any > args( 4 );
                SurfaceSharedPtr pAlphaSurface = mpSurfaceProvider->createSurface( maSize, CAIRO_CONTENT_COLOR );
                CairoSharedPtr   pAlphaCairo = pAlphaSurface->getCairo();
                X11Surface* pXlibSurface=dynamic_cast<X11Surface*>(pAlphaSurface.get());
                OSL_ASSERT(pXlibSurface);

                // create RGB image (levels of gray) of alpha channel of original picture
                cairo_set_source_rgba( pAlphaCairo.get(), 1, 1, 1, 1 );
                cairo_set_operator( pAlphaCairo.get(), CAIRO_OPERATOR_SOURCE );
                cairo_paint( pAlphaCairo.get() );
                cairo_set_source_surface( pAlphaCairo.get(), mpBufferSurface->getCairoSurface().get(), 0, 0 );
                cairo_set_operator( pAlphaCairo.get(), CAIRO_OPERATOR_XOR );
                cairo_paint( pAlphaCairo.get() );
                pAlphaCairo.reset();

                X11PixmapSharedPtr pPixmap = pXlibSurface->getPixmap();
                args[0] = uno::Any( true );
                args[1] = ::com::sun::star::uno::Any( pPixmap->mhDrawable );
                args[2] = ::com::sun::star::uno::Any( sal_Int32( pXlibSurface->getDepth () ) );
                args[3] = ::com::sun::star::uno::Any( sal_Int64( pXlibSurface->getVisual () ) );
                pPixmap->clear(); // caller takes ownership of pixmap

                // return pixmap and alphachannel pixmap - it will be used in BitmapEx
                aRV = uno::Any( args );
#elif defined CAIRO_HAS_QUARTZ_SURFACE
                SurfaceSharedPtr pAlphaSurface = mpSurfaceProvider->createSurface( maSize, CAIRO_CONTENT_COLOR );
                CairoSharedPtr   pAlphaCairo = pAlphaSurface->getCairo();
                QuartzSurface* pQuartzSurface=dynamic_cast<QuartzSurface*>(pAlphaSurface.get());
                OSL_ASSERT(pQuartzSurface);

                // create RGB image (levels of gray) of alpha channel of original picture
                cairo_set_source_rgba( pAlphaCairo.get(), 1, 1, 1, 1 );
                cairo_set_operator( pAlphaCairo.get(), CAIRO_OPERATOR_SOURCE );
                cairo_paint( pAlphaCairo.get() );
                cairo_set_source_surface( pAlphaCairo.get(), mpBufferSurface->getCairoSurface().get(), 0, 0 );
                cairo_set_operator( pAlphaCairo.get(), CAIRO_OPERATOR_XOR );
                cairo_paint( pAlphaCairo.get() );
                pAlphaCairo.reset();

                uno::Sequence< uno::Any > args( 1 );
                args[0] = uno::Any( sal_IntPtr (pQuartzSurface->getCGContext()) );
                // return ??? and alphachannel ??? - it will be used in BitmapEx
                aRV = uno::Any( args );
#elif defined CAIRO_HAS_WIN32_SURFACE
                SurfaceSharedPtr pAlphaSurface = mpSurfaceProvider->createSurface( maSize, CAIRO_CONTENT_COLOR );
                CairoSharedPtr   pAlphaCairo = pAlphaSurface->getCairo();

                // create RGB image (levels of gray) of alpha channel of original picture
                cairo_set_source_rgba( pAlphaCairo.get(), 1, 1, 1, 1 );
                cairo_set_operator( pAlphaCairo.get(), CAIRO_OPERATOR_SOURCE );
                cairo_paint( pAlphaCairo.get() );
                cairo_set_source_surface( pAlphaCairo.get(), mpBufferSurface->getCairoSurface().get(), 0, 0 );
                cairo_set_operator( pAlphaCairo.get(), CAIRO_OPERATOR_XOR );
                cairo_paint( pAlphaCairo.get() );
                pAlphaCairo.reset();

                // cant seem to retrieve HBITMAP from cairo. copy content then
                uno::Sequence< uno::Any > args( 1 );
                args[1] = uno::Any( sal_Int64(surface2HBitmap(pAlphaSurface,maSize)) );

                aRV = uno::Any( args );
                // caller frees the bitmap
#else
# error Please define fast prop retrieval for your platform!
#endif
                break;
            }
        }

        return aRV;
    }

#define IMPLEMENTATION_NAME "CairoCanvas.CanvasBitmap"
#define SERVICE_NAME "com.sun.star.rendering.CanvasBitmap"

    OUString SAL_CALL CanvasBitmap::getImplementationName(  ) throw (uno::RuntimeException)
    {
        return OUString( IMPLEMENTATION_NAME );
    }

    sal_Bool SAL_CALL CanvasBitmap::supportsService( const OUString& ServiceName ) throw (uno::RuntimeException)
    {
        return ServiceName == SERVICE_NAME;
    }

    uno::Sequence< OUString > SAL_CALL CanvasBitmap::getSupportedServiceNames(  ) throw (uno::RuntimeException)
    {
        uno::Sequence< OUString > aRet(1);
        aRet[0] = SERVICE_NAME;

        return aRet;
    }

}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>//! Copyright (c) 2013 ASMlover. All rights reserved.
//!
//! Redistribution and use in source and binary forms, with or without
//! modification, are permitted provided that the following conditions
//! are met:
//!
//!  * Redistributions of source code must retain the above copyright
//!    notice, this list ofconditions and the following disclaimer.
//!
//!  * Redistributions in binary form must reproduce the above copyright
//!    notice, this list of conditions and the following disclaimer in
//!    the documentation and/or other materialsprovided with the
//!    distribution.
//!
//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
//! "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
//! LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
//! FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
//! COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
//! INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
//! BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
//! LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
//! CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
//! LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
//! ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
//! POSSIBILITY OF SUCH DAMAGE.
#include <stdlib.h>
#include "net.h"
#include "logging.h"
#include "thread.h"
#if defined(_WINDOWS_) || defined(_MSC_VER)
# include "select_poll.h"
#elif defined(__linux__)
# include "epoll_poll.h"
#endif
#include "worker.h"

Worker::Worker(void)
  : running_(false)
  , rthread_(NULL)
  , wthread_(NULL)
  , poll_(NULL)
{
}

Worker::~Worker(void)
{
  Stop();
}

bool
Worker::Start(void)
{
  if (NULL == poll_)
    return false;

  rthread_ = new Thread(&Worker::ReadRoutine, this);
  if (NULL == rthread_) {
    LOG_FAIL("new Thread failed\n");
    return false;
  }

  wthread_ = new Thread(&Worker::WriteRoutine, this);
  if (NULL == wthread_) {
    LOG_FAIL("new Thread failed\n");
    return false;
  }

  running_ = true;
  rthread_->Start();
  wthread_->Start();

  return true;
}

void
Worker::Stop(void)
{
  running_ = false;

  if (NULL != rthread_) {
    rthread_->Join();
    delete rthread_;

    rthread_ = NULL;
  }

  if (NULL != wthread_) {
    wthread_->Join();
    delete wthread_;

    wthread_ = NULL;
  }
}

void
Worker::ReadRoutine(void* argument)
{
  Worker* self = static_cast<Worker*>(argument);
  if (NULL == self)
    return;

  while (self->running_) {
    if (!self->poll_->Polling(kEventTypeRead)) {
      Sleep(1);
      continue;
    }
  }
}

void
Worker::WriteRoutine(void* argument)
{
  Worker* self = static_cast<Worker*>(argument);
  if (NULL == self)
    return;

  while (self->running_) {
    if (!self->poll_->Polling(kEventTypeWrite)) {
      Sleep(1);
      continue;
    }
  }
}
<commit_msg>improved worker module<commit_after>//! Copyright (c) 2013 ASMlover. All rights reserved.
//!
//! Redistribution and use in source and binary forms, with or without
//! modification, are permitted provided that the following conditions
//! are met:
//!
//!  * Redistributions of source code must retain the above copyright
//!    notice, this list ofconditions and the following disclaimer.
//!
//!  * Redistributions in binary form must reproduce the above copyright
//!    notice, this list of conditions and the following disclaimer in
//!    the documentation and/or other materialsprovided with the
//!    distribution.
//!
//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
//! "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
//! LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
//! FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
//! COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
//! INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
//! BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
//! LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
//! CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
//! LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
//! ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
//! POSSIBILITY OF SUCH DAMAGE.
#include <stdlib.h>
#include "net.h"
#include "logging.h"
#include "os_tool.h"
#include "thread.h"
#if defined(_WINDOWS_) || defined(_MSC_VER)
# include "select_poll.h"
#elif defined(__linux__)
# include "epoll_poll.h"
#endif
#include "worker.h"

Worker::Worker(void)
  : running_(false)
  , rthread_(NULL)
  , wthread_(NULL)
  , poll_(NULL)
{
}

Worker::~Worker(void)
{
  Stop();
}

bool
Worker::Start(void)
{
  if (NULL == poll_)
    return false;

  rthread_ = new Thread(&Worker::ReadRoutine, this);
  if (NULL == rthread_) {
    LOG_FAIL("new Thread failed\n");
    return false;
  }

  wthread_ = new Thread(&Worker::WriteRoutine, this);
  if (NULL == wthread_) {
    LOG_FAIL("new Thread failed\n");
    return false;
  }

  running_ = true;
  rthread_->Start();
  wthread_->Start();

  return true;
}

void
Worker::Stop(void)
{
  running_ = false;

  if (NULL != rthread_) {
    rthread_->Join();
    delete rthread_;

    rthread_ = NULL;
  }

  if (NULL != wthread_) {
    wthread_->Join();
    delete wthread_;

    wthread_ = NULL;
  }
}

void
Worker::ReadRoutine(void* argument)
{
  Worker* self = static_cast<Worker*>(argument);
  if (NULL == self)
    return;

  while (self->running_) {
    if (!self->poll_->Polling(kEventTypeRead)) {
      Tools::Sleep(1);
      continue;
    }
  }
}

void
Worker::WriteRoutine(void* argument)
{
  Worker* self = static_cast<Worker*>(argument);
  if (NULL == self)
    return;

  while (self->running_) {
    if (!self->poll_->Polling(kEventTypeWrite)) {
      Tools::Sleep(1);
      continue;
    }
  }
}
<|endoftext|>


<commit_before>#pragma once
#include <string>
#include <SharedContext.hpp>

namespace DoremiEngine
{
    namespace Core
    {
        /**

        */
        class SharedContextImplementation : public SharedContext
        {
            public:
            SharedContextImplementation()
            : m_workingDirectory(""), m_preferenceDirectory(""), m_audio(nullptr), m_core(nullptr),
              m_graphic(nullptr), m_memory(nullptr), m_network(nullptr), m_physics(nullptr),
              m_script(nullptr)
            {
            }

            void SetAudioModule(Audio::AudioModule* p_audioModule)
            {
                m_audio = p_audioModule;
            }
            void SetCoreModule(DoremiEngine* p_coreModule)
            {
                m_core = p_coreModule;
            }
            void SetGraphicModule(Graphic::GraphicModule* p_graphicModule)
            {
                m_graphic = p_graphicModule;
            }
            void SetMemoryModule(Memory::MemoryModule* p_memoryModule)
            {
                m_memory = p_memoryModule;
            }
            void SetNetworkModule(Network::NetworkModule* p_networkModule)
            {
                m_network = p_networkModule;
            }
            void SetPhysicsModule(Physics::PhysicsModule* p_physicsModule)
            {
                m_physics = p_physicsModule;
            }
            void SetScriptModule(Script::ScriptModule* p_scriptModule)
            {
                p_scriptModule = m_script;
            }

            const std::string GetWorkingDirectory() const
            {
                return m_workingDirectory;
            };
            const std::string GetPreferenceDirectory() const
            {
                return m_preferenceDirectory;
            };

            Audio::AudioModule& GetAudioModule() const
            {
                return *m_audio;
            }
            DoremiEngine& GetCoreModule() const
            {
                return *m_core;
            };
            Graphic::GraphicModule& GetGraphicModule() const
            {
                return *m_graphic;
            };
            Memory::MemoryModule& GetMemoryModule() const
            {
                return *m_memory;
            };
            Network::NetworkModule& GetNetworkModule() const
            {
                return *m_network;
            };
            Physics::PhysicsModule& GetPhysicsModule() const
            {
                return *m_physics;
            };
            Script::ScriptModule& GetScriptModule() const
            {
                return *m_script;
            };

            private:
            std::string m_workingDirectory;
            std::string m_preferenceDirectory;
            Audio::AudioModule* m_audio;
            DoremiEngine* m_core;
            Graphic::GraphicModule* m_graphic;
            Memory::MemoryModule* m_memory;
            Network::NetworkModule* m_network;
            Physics::PhysicsModule* m_physics;
            Script::ScriptModule* m_script;
        };
    }
}<commit_msg>Removed legacy comment brackets<commit_after>#pragma once
#include <string>
#include <SharedContext.hpp>

namespace DoremiEngine
{
    namespace Core
    {
        class SharedContextImplementation : public SharedContext
        {
            public:
            SharedContextImplementation()
            : m_workingDirectory(""), m_preferenceDirectory(""), m_audio(nullptr), m_core(nullptr),
              m_graphic(nullptr), m_memory(nullptr), m_network(nullptr), m_physics(nullptr),
              m_script(nullptr)
            {
            }

            void SetAudioModule(Audio::AudioModule* p_audioModule)
            {
                m_audio = p_audioModule;
            }
            void SetCoreModule(DoremiEngine* p_coreModule)
            {
                m_core = p_coreModule;
            }
            void SetGraphicModule(Graphic::GraphicModule* p_graphicModule)
            {
                m_graphic = p_graphicModule;
            }
            void SetMemoryModule(Memory::MemoryModule* p_memoryModule)
            {
                m_memory = p_memoryModule;
            }
            void SetNetworkModule(Network::NetworkModule* p_networkModule)
            {
                m_network = p_networkModule;
            }
            void SetPhysicsModule(Physics::PhysicsModule* p_physicsModule)
            {
                m_physics = p_physicsModule;
            }
            void SetScriptModule(Script::ScriptModule* p_scriptModule)
            {
                p_scriptModule = m_script;
            }

            const std::string GetWorkingDirectory() const
            {
                return m_workingDirectory;
            };
            const std::string GetPreferenceDirectory() const
            {
                return m_preferenceDirectory;
            };

            Audio::AudioModule& GetAudioModule() const
            {
                return *m_audio;
            }
            DoremiEngine& GetCoreModule() const
            {
                return *m_core;
            };
            Graphic::GraphicModule& GetGraphicModule() const
            {
                return *m_graphic;
            };
            Memory::MemoryModule& GetMemoryModule() const
            {
                return *m_memory;
            };
            Network::NetworkModule& GetNetworkModule() const
            {
                return *m_network;
            };
            Physics::PhysicsModule& GetPhysicsModule() const
            {
                return *m_physics;
            };
            Script::ScriptModule& GetScriptModule() const
            {
                return *m_script;
            };

            private:
            std::string m_workingDirectory;
            std::string m_preferenceDirectory;
            Audio::AudioModule* m_audio;
            DoremiEngine* m_core;
            Graphic::GraphicModule* m_graphic;
            Memory::MemoryModule* m_memory;
            Network::NetworkModule* m_network;
            Physics::PhysicsModule* m_physics;
            Script::ScriptModule* m_script;
        };
    }
}<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "video_processing_impl.h"
#include "critical_section_wrapper.h"
#include "trace.h"

#include <cassert>

namespace webrtc {

namespace
{
    void
    SetSubSampling(VideoProcessingModule::FrameStats& stats,
                   const WebRtc_Word32 width,
                   const WebRtc_Word32 height)
    {
        if (width * height >= 640 * 480)
        {
            stats.subSamplWidth = 3;
            stats.subSamplHeight = 3;
        }
        else if (width * height >= 352 * 288)
        {
            stats.subSamplWidth = 2;
            stats.subSamplHeight = 2;
        }
        else if (width * height >= 176 * 144)
        {
            stats.subSamplWidth = 1;
            stats.subSamplHeight = 1;
        }
        else
        {
            stats.subSamplWidth = 0;
            stats.subSamplHeight = 0;
        }
    }
}

VideoProcessingModule*
VideoProcessingModule::Create(const WebRtc_Word32 id)
{
    WEBRTC_TRACE(webrtc::kTraceModuleCall, webrtc::kTraceVideoPreocessing, id,
               "VideoProcessingModule::Create()");

    return new VideoProcessingModuleImpl(id);
}

void
VideoProcessingModule::Destroy(VideoProcessingModule* module)
{
    if (module)
    {
        WEBRTC_TRACE(webrtc::kTraceModuleCall, webrtc::kTraceVideoPreocessing,
            static_cast<VideoProcessingModuleImpl*>(module)->Id(),
                "VideoProcessingModule::destroy()");
        delete static_cast<VideoProcessingModuleImpl*>(module);
    }
}

WebRtc_Word32
VideoProcessingModuleImpl::ChangeUniqueId(const WebRtc_Word32 id)
{
    CriticalSectionScoped mutex(_mutex);
    WEBRTC_TRACE(webrtc::kTraceModuleCall, webrtc::kTraceVideoPreocessing, _id, "ChangeUniqueId(new id:%d)", id);
    _id = id;
    _brightnessDetection.ChangeUniqueId(id);
    _deflickering.ChangeUniqueId(id);
    _denoising.ChangeUniqueId(id);
    _framePreProcessor.ChangeUniqueId(id);
    return VPM_OK;
}

WebRtc_Word32
VideoProcessingModuleImpl::Id() const
{
    CriticalSectionScoped mutex(_mutex);
    return _id;
}

VideoProcessingModuleImpl::VideoProcessingModuleImpl(const WebRtc_Word32 id) :
    _id(id),
    _mutex(*CriticalSectionWrapper::CreateCriticalSection())
{
    _brightnessDetection.ChangeUniqueId(id);
    _deflickering.ChangeUniqueId(id);
    _denoising.ChangeUniqueId(id);
    _framePreProcessor.ChangeUniqueId(id);
    WEBRTC_TRACE(webrtc::kTraceMemory, webrtc::kTraceVideoPreocessing, _id, "Created");
}

VideoProcessingModuleImpl::~VideoProcessingModuleImpl()
{
    WEBRTC_TRACE(webrtc::kTraceMemory, webrtc::kTraceVideoPreocessing, _id, "Destroyed");

    delete &_mutex;
}

void
VideoProcessingModuleImpl::Reset()
{
    CriticalSectionScoped mutex(_mutex);
    _deflickering.Reset();
    _denoising.Reset();
    _brightnessDetection.Reset();
    _framePreProcessor.Reset();

}

WebRtc_Word32
VideoProcessingModule::GetFrameStats(FrameStats& stats,
                                         const VideoFrame& frame)
{
    return GetFrameStats(stats, frame.Buffer(), frame.Width(), frame.Height());
}

WebRtc_Word32
VideoProcessingModule::GetFrameStats(FrameStats& stats,
                                         const WebRtc_UWord8* frame,
                                         const WebRtc_UWord32 width,
                                         const WebRtc_UWord32 height)
{
    if (frame == NULL)
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoPreocessing, -1, "Null frame pointer");
        return VPM_PARAMETER_ERROR;
    }

    if (width == 0 || height == 0)
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoPreocessing, -1, "Invalid frame size");
        return VPM_PARAMETER_ERROR;
    }

    ClearFrameStats(stats); // The histogram needs to be zeroed out.
    SetSubSampling(stats, width, height);

    // Compute histogram and sum of frame
    for (WebRtc_UWord32 i = 0; i < height; i += (1 << stats.subSamplHeight))
    {
        WebRtc_Word32 k = i * width;
        for (WebRtc_UWord32 j = 0; j < width; j += (1 << stats.subSamplWidth))
        {
            stats.hist[frame[k + j]]++;
            stats.sum += frame[k + j];
        }
    }

    stats.numPixels = (width * height) / ((1 << stats.subSamplWidth) * (1 << stats.subSamplHeight));
    assert(stats.numPixels > 0);

    // Compute mean value of frame
    stats.mean = stats.sum / stats.numPixels;

    return VPM_OK;
}

bool
VideoProcessingModule::ValidFrameStats(const FrameStats& stats)
{
    if (stats.numPixels == 0)
    {
        return false;
    }

    return true;
}

void
VideoProcessingModule::ClearFrameStats(FrameStats& stats)
{
    stats.mean = 0;
    stats.sum = 0;
    stats.numPixels = 0;
    stats.subSamplWidth = 0;
    stats.subSamplHeight = 0;
    memset(stats.hist, 0, sizeof(stats.hist));
}

WebRtc_Word32
VideoProcessingModule::ColorEnhancement(VideoFrame& frame)
{
    return ColorEnhancement(frame.Buffer(), frame.Width(), frame.Height());
}

WebRtc_Word32
VideoProcessingModule::ColorEnhancement(WebRtc_UWord8* frame,
                                            const WebRtc_UWord32 width,
                                            const WebRtc_UWord32 height)
{
    return VideoProcessing::ColorEnhancement(frame, width, height);
}

WebRtc_Word32
VideoProcessingModule::Brighten(VideoFrame& frame, int delta)
{
    return Brighten(frame.Buffer(), frame.Width(), frame.Height(), delta);
}

WebRtc_Word32
VideoProcessingModule::Brighten(WebRtc_UWord8* frame,
                                    int width,
                                    int height,
                                    int delta)
{
    return VideoProcessing::Brighten(frame, width, height, delta);
}

WebRtc_Word32
VideoProcessingModuleImpl::Deflickering(VideoFrame& frame,
                                            FrameStats& stats)
{
    return Deflickering(frame.Buffer(), frame.Width(), frame.Height(),
        frame.TimeStamp(), stats);
}

WebRtc_Word32
VideoProcessingModuleImpl::Deflickering(WebRtc_UWord8* frame,
                                            const WebRtc_UWord32 width,
                                            const WebRtc_UWord32 height,
                                            const WebRtc_UWord32 timestamp,
                                            FrameStats& stats)
{
    CriticalSectionScoped mutex(_mutex);
    return _deflickering.ProcessFrame(frame, width, height, timestamp, stats);
}

WebRtc_Word32
VideoProcessingModuleImpl::Denoising(VideoFrame& frame)
{
    return Denoising(frame.Buffer(), frame.Width(), frame.Height());
}

WebRtc_Word32
VideoProcessingModuleImpl::Denoising(WebRtc_UWord8* frame,
                                         const WebRtc_UWord32 width,
                                         const WebRtc_UWord32 height)
{
    CriticalSectionScoped mutex(_mutex);
    return _denoising.ProcessFrame(frame, width, height);
}

WebRtc_Word32
VideoProcessingModuleImpl::BrightnessDetection(const VideoFrame& frame,
                                                   const FrameStats& stats)
{
    return BrightnessDetection(frame.Buffer(), frame.Width(), frame.Height(), stats);
}

WebRtc_Word32
VideoProcessingModuleImpl::BrightnessDetection(const WebRtc_UWord8* frame,
                                                   const WebRtc_UWord32 width,
                                                   const WebRtc_UWord32 height,
                                                   const FrameStats& stats)
{
    CriticalSectionScoped mutex(_mutex);
    return _brightnessDetection.ProcessFrame(frame, width, height, stats);
}

void
VideoProcessingModuleImpl::EnableTemporalDecimation(bool enable)
{
    CriticalSectionScoped mutex(_mutex);
    _framePreProcessor.EnableTemporalDecimation(enable);
}

void
VideoProcessingModuleImpl::SetInputFrameResampleMode(VideoFrameResampling resamplingMode)
{
    CriticalSectionScoped cs(_mutex);
    _framePreProcessor.SetInputFrameResampleMode(resamplingMode);
}

WebRtc_Word32
VideoProcessingModuleImpl::SetMaxFrameRate(WebRtc_UWord32 maxFrameRate)
{
    CriticalSectionScoped cs(_mutex);
    return _framePreProcessor.SetMaxFrameRate(maxFrameRate);

}

WebRtc_Word32
VideoProcessingModuleImpl::SetTargetResolution(WebRtc_UWord32 width, WebRtc_UWord32 height, WebRtc_UWord32 frameRate)
{
    CriticalSectionScoped cs(_mutex);
    return _framePreProcessor.SetTargetResolution(width, height, frameRate);
}

WebRtc_UWord32
VideoProcessingModuleImpl::DecimatedFrameRate()
{
    CriticalSectionScoped cs(_mutex);
    return  _framePreProcessor.DecimatedFrameRate();
}

WebRtc_UWord32
VideoProcessingModuleImpl::DecimatedWidth() const
{
    CriticalSectionScoped cs(_mutex);
    return _framePreProcessor.DecimatedWidth();
}

WebRtc_UWord32
VideoProcessingModuleImpl::DecimatedHeight() const
{
    CriticalSectionScoped cs(_mutex);
    return _framePreProcessor.DecimatedHeight();
}

WebRtc_Word32
VideoProcessingModuleImpl::PreprocessFrame(const VideoFrame *frame, VideoFrame **processedFrame)
{
    CriticalSectionScoped mutex(_mutex);
    return _framePreProcessor.PreprocessFrame(frame, processedFrame);
}

VideoContentMetrics*
VideoProcessingModuleImpl::ContentMetrics() const
{
    CriticalSectionScoped mutex(_mutex);
    return _framePreProcessor.ContentMetrics();
}

void
VideoProcessingModuleImpl::EnableContentAnalysis(bool enable)
{
    CriticalSectionScoped mutex(_mutex);
    _framePreProcessor.EnableContentAnalysis(enable);
}

} //namespace
<commit_msg>Remove the deprecated kTraceModuleCall trace from video processing module. Review URL: https://webrtc-codereview.appspot.com/395012<commit_after>/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "video_processing_impl.h"
#include "critical_section_wrapper.h"
#include "trace.h"

#include <cassert>

namespace webrtc {

namespace
{
    void
    SetSubSampling(VideoProcessingModule::FrameStats& stats,
                   const WebRtc_Word32 width,
                   const WebRtc_Word32 height)
    {
        if (width * height >= 640 * 480)
        {
            stats.subSamplWidth = 3;
            stats.subSamplHeight = 3;
        }
        else if (width * height >= 352 * 288)
        {
            stats.subSamplWidth = 2;
            stats.subSamplHeight = 2;
        }
        else if (width * height >= 176 * 144)
        {
            stats.subSamplWidth = 1;
            stats.subSamplHeight = 1;
        }
        else
        {
            stats.subSamplWidth = 0;
            stats.subSamplHeight = 0;
        }
    }
}

VideoProcessingModule*
VideoProcessingModule::Create(const WebRtc_Word32 id)
{

    return new VideoProcessingModuleImpl(id);
}

void
VideoProcessingModule::Destroy(VideoProcessingModule* module)
{
    if (module)
    {
        delete static_cast<VideoProcessingModuleImpl*>(module);
    }
}

WebRtc_Word32
VideoProcessingModuleImpl::ChangeUniqueId(const WebRtc_Word32 id)
{
    CriticalSectionScoped mutex(_mutex);
    _id = id;
    _brightnessDetection.ChangeUniqueId(id);
    _deflickering.ChangeUniqueId(id);
    _denoising.ChangeUniqueId(id);
    _framePreProcessor.ChangeUniqueId(id);
    return VPM_OK;
}

WebRtc_Word32
VideoProcessingModuleImpl::Id() const
{
    CriticalSectionScoped mutex(_mutex);
    return _id;
}

VideoProcessingModuleImpl::VideoProcessingModuleImpl(const WebRtc_Word32 id) :
    _id(id),
    _mutex(*CriticalSectionWrapper::CreateCriticalSection())
{
    _brightnessDetection.ChangeUniqueId(id);
    _deflickering.ChangeUniqueId(id);
    _denoising.ChangeUniqueId(id);
    _framePreProcessor.ChangeUniqueId(id);
    WEBRTC_TRACE(webrtc::kTraceMemory, webrtc::kTraceVideoPreocessing, _id, "Created");
}

VideoProcessingModuleImpl::~VideoProcessingModuleImpl()
{
    WEBRTC_TRACE(webrtc::kTraceMemory, webrtc::kTraceVideoPreocessing, _id, "Destroyed");

    delete &_mutex;
}

void
VideoProcessingModuleImpl::Reset()
{
    CriticalSectionScoped mutex(_mutex);
    _deflickering.Reset();
    _denoising.Reset();
    _brightnessDetection.Reset();
    _framePreProcessor.Reset();

}

WebRtc_Word32
VideoProcessingModule::GetFrameStats(FrameStats& stats,
                                         const VideoFrame& frame)
{
    return GetFrameStats(stats, frame.Buffer(), frame.Width(), frame.Height());
}

WebRtc_Word32
VideoProcessingModule::GetFrameStats(FrameStats& stats,
                                         const WebRtc_UWord8* frame,
                                         const WebRtc_UWord32 width,
                                         const WebRtc_UWord32 height)
{
    if (frame == NULL)
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoPreocessing, -1, "Null frame pointer");
        return VPM_PARAMETER_ERROR;
    }

    if (width == 0 || height == 0)
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoPreocessing, -1, "Invalid frame size");
        return VPM_PARAMETER_ERROR;
    }

    ClearFrameStats(stats); // The histogram needs to be zeroed out.
    SetSubSampling(stats, width, height);

    // Compute histogram and sum of frame
    for (WebRtc_UWord32 i = 0; i < height; i += (1 << stats.subSamplHeight))
    {
        WebRtc_Word32 k = i * width;
        for (WebRtc_UWord32 j = 0; j < width; j += (1 << stats.subSamplWidth))
        {
            stats.hist[frame[k + j]]++;
            stats.sum += frame[k + j];
        }
    }

    stats.numPixels = (width * height) / ((1 << stats.subSamplWidth) * (1 << stats.subSamplHeight));
    assert(stats.numPixels > 0);

    // Compute mean value of frame
    stats.mean = stats.sum / stats.numPixels;

    return VPM_OK;
}

bool
VideoProcessingModule::ValidFrameStats(const FrameStats& stats)
{
    if (stats.numPixels == 0)
    {
        return false;
    }

    return true;
}

void
VideoProcessingModule::ClearFrameStats(FrameStats& stats)
{
    stats.mean = 0;
    stats.sum = 0;
    stats.numPixels = 0;
    stats.subSamplWidth = 0;
    stats.subSamplHeight = 0;
    memset(stats.hist, 0, sizeof(stats.hist));
}

WebRtc_Word32
VideoProcessingModule::ColorEnhancement(VideoFrame& frame)
{
    return ColorEnhancement(frame.Buffer(), frame.Width(), frame.Height());
}

WebRtc_Word32
VideoProcessingModule::ColorEnhancement(WebRtc_UWord8* frame,
                                            const WebRtc_UWord32 width,
                                            const WebRtc_UWord32 height)
{
    return VideoProcessing::ColorEnhancement(frame, width, height);
}

WebRtc_Word32
VideoProcessingModule::Brighten(VideoFrame& frame, int delta)
{
    return Brighten(frame.Buffer(), frame.Width(), frame.Height(), delta);
}

WebRtc_Word32
VideoProcessingModule::Brighten(WebRtc_UWord8* frame,
                                    int width,
                                    int height,
                                    int delta)
{
    return VideoProcessing::Brighten(frame, width, height, delta);
}

WebRtc_Word32
VideoProcessingModuleImpl::Deflickering(VideoFrame& frame,
                                            FrameStats& stats)
{
    return Deflickering(frame.Buffer(), frame.Width(), frame.Height(),
        frame.TimeStamp(), stats);
}

WebRtc_Word32
VideoProcessingModuleImpl::Deflickering(WebRtc_UWord8* frame,
                                            const WebRtc_UWord32 width,
                                            const WebRtc_UWord32 height,
                                            const WebRtc_UWord32 timestamp,
                                            FrameStats& stats)
{
    CriticalSectionScoped mutex(_mutex);
    return _deflickering.ProcessFrame(frame, width, height, timestamp, stats);
}

WebRtc_Word32
VideoProcessingModuleImpl::Denoising(VideoFrame& frame)
{
    return Denoising(frame.Buffer(), frame.Width(), frame.Height());
}

WebRtc_Word32
VideoProcessingModuleImpl::Denoising(WebRtc_UWord8* frame,
                                         const WebRtc_UWord32 width,
                                         const WebRtc_UWord32 height)
{
    CriticalSectionScoped mutex(_mutex);
    return _denoising.ProcessFrame(frame, width, height);
}

WebRtc_Word32
VideoProcessingModuleImpl::BrightnessDetection(const VideoFrame& frame,
                                                   const FrameStats& stats)
{
    return BrightnessDetection(frame.Buffer(), frame.Width(), frame.Height(), stats);
}

WebRtc_Word32
VideoProcessingModuleImpl::BrightnessDetection(const WebRtc_UWord8* frame,
                                                   const WebRtc_UWord32 width,
                                                   const WebRtc_UWord32 height,
                                                   const FrameStats& stats)
{
    CriticalSectionScoped mutex(_mutex);
    return _brightnessDetection.ProcessFrame(frame, width, height, stats);
}

void
VideoProcessingModuleImpl::EnableTemporalDecimation(bool enable)
{
    CriticalSectionScoped mutex(_mutex);
    _framePreProcessor.EnableTemporalDecimation(enable);
}

void
VideoProcessingModuleImpl::SetInputFrameResampleMode(VideoFrameResampling resamplingMode)
{
    CriticalSectionScoped cs(_mutex);
    _framePreProcessor.SetInputFrameResampleMode(resamplingMode);
}

WebRtc_Word32
VideoProcessingModuleImpl::SetMaxFrameRate(WebRtc_UWord32 maxFrameRate)
{
    CriticalSectionScoped cs(_mutex);
    return _framePreProcessor.SetMaxFrameRate(maxFrameRate);

}

WebRtc_Word32
VideoProcessingModuleImpl::SetTargetResolution(WebRtc_UWord32 width, WebRtc_UWord32 height, WebRtc_UWord32 frameRate)
{
    CriticalSectionScoped cs(_mutex);
    return _framePreProcessor.SetTargetResolution(width, height, frameRate);
}

WebRtc_UWord32
VideoProcessingModuleImpl::DecimatedFrameRate()
{
    CriticalSectionScoped cs(_mutex);
    return  _framePreProcessor.DecimatedFrameRate();
}

WebRtc_UWord32
VideoProcessingModuleImpl::DecimatedWidth() const
{
    CriticalSectionScoped cs(_mutex);
    return _framePreProcessor.DecimatedWidth();
}

WebRtc_UWord32
VideoProcessingModuleImpl::DecimatedHeight() const
{
    CriticalSectionScoped cs(_mutex);
    return _framePreProcessor.DecimatedHeight();
}

WebRtc_Word32
VideoProcessingModuleImpl::PreprocessFrame(const VideoFrame *frame, VideoFrame **processedFrame)
{
    CriticalSectionScoped mutex(_mutex);
    return _framePreProcessor.PreprocessFrame(frame, processedFrame);
}

VideoContentMetrics*
VideoProcessingModuleImpl::ContentMetrics() const
{
    CriticalSectionScoped mutex(_mutex);
    return _framePreProcessor.ContentMetrics();
}

void
VideoProcessingModuleImpl::EnableContentAnalysis(bool enable)
{
    CriticalSectionScoped mutex(_mutex);
    _framePreProcessor.EnableContentAnalysis(enable);
}

} //namespace
<|endoftext|>


<commit_before>// Copyright (c) 2019 by Robert Bosch GmbH. All rights reserved.
// Copyright (c) 2021 by Apex.AI Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0

#ifndef IOX_POSH_RUNTIME_IPC_RUNTIME_INTERFACE_HPP
#define IOX_POSH_RUNTIME_IPC_RUNTIME_INTERFACE_HPP

#include "iceoryx_posh/internal/runtime/ipc_interface_creator.hpp"
#include "iceoryx_posh/internal/runtime/ipc_interface_user.hpp"

namespace iox
{
namespace runtime
{
class IpcRuntimeInterface
{
  public:
    /// @brief Runtime Interface for the own IPC channel and the one to the RouDi daemon
    /// @param[in] roudiName name of the RouDi IPC channel
    /// @param[in] appName name of the appplication and its IPC channel
    /// @param[in] roudiWaitingTimeout timeout for searching the RouDi IPC channel
    IpcRuntimeInterface(const ProcessName_t& roudiName,
                        const ProcessName_t& appName,
                        const units::Duration roudiWaitingTimeout) noexcept;
    ~IpcRuntimeInterface() = default;

    /// @brief Not needed therefore deleted
    IpcRuntimeInterface(const IpcRuntimeInterface&) = delete;
    IpcRuntimeInterface& operator=(const IpcRuntimeInterface&) = delete;
    IpcRuntimeInterface(IpcRuntimeInterface&&) = delete;
    IpcRuntimeInterface& operator=(IpcRuntimeInterface&&) = delete;

    /// @brief sends the keep alive trigger to the RouDi daemon
    /// @return true if sending was successful, false if not
    bool sendKeepalive() noexcept;

    /// @brief send a request to the RouDi daemon
    /// @param[in] msg request to RouDi
    /// @param[out] answer response from RouDi
    /// @return true if communication was successful, false if not
    bool sendRequestToRouDi(const IpcMessage& msg, IpcMessage& answer) noexcept;

    /// @brief send a message to the RouDi daemon
    /// @param[in] msg message which will be send to RouDi
    /// @return true if communication was successful, otherwise false
    bool sendMessageToRouDi(const IpcMessage& msg) noexcept;

    /// @brief get the adress offset of the segment manager
    /// @return address offset as RelativePointer::offset_t
    RelativePointer::offset_t getSegmentManagerAddressOffset() const noexcept;

    /// @brief get the size of the management shared memory object
    /// @return size in bytes
    size_t getShmTopicSize() noexcept;

    /// @brief get the segment id of the shared memory object
    /// @return segment id
    uint64_t getSegmentId() const noexcept;

  private:
    enum class RegAckResult
    {
        SUCCESS,
        TIMEOUT
    };

    /// @brief
    /// @return
    void waitForRoudi(cxx::DeadlineTimer& timer) noexcept;

    /// @brief
    /// @return
    RegAckResult waitForRegAck(int64_t transmissionTimestamp) noexcept;

  private:
    ProcessName_t m_appName;
    cxx::optional<RelativePointer::offset_t> m_segmentManagerAddressOffset;
    IpcInterfaceCreator m_AppIpcInterface;
    IpcInterfaceUser m_RoudiIpcInterface;
    size_t m_shmTopicSize{0U};
    uint64_t m_segmentId{0U};
};

} // namespace runtime
} // namespace iox

#endif // IOX_POSH_RUNTIME_IPC_RUNTIME_INTERFACE_HPP<commit_msg>iox-#381 Address review findings from Christian Eltzschig removing size_t usage and be strict about const-correctness<commit_after>// Copyright (c) 2019 by Robert Bosch GmbH. All rights reserved.
// Copyright (c) 2021 by Apex.AI Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0

#ifndef IOX_POSH_RUNTIME_IPC_RUNTIME_INTERFACE_HPP
#define IOX_POSH_RUNTIME_IPC_RUNTIME_INTERFACE_HPP

#include "iceoryx_posh/internal/runtime/ipc_interface_creator.hpp"
#include "iceoryx_posh/internal/runtime/ipc_interface_user.hpp"

namespace iox
{
namespace runtime
{
class IpcRuntimeInterface
{
  public:
    /// @brief Runtime Interface for the own IPC channel and the one to the RouDi daemon
    /// @param[in] roudiName name of the RouDi IPC channel
    /// @param[in] appName name of the appplication and its IPC channel
    /// @param[in] roudiWaitingTimeout timeout for searching the RouDi IPC channel
    IpcRuntimeInterface(const ProcessName_t& roudiName,
                        const ProcessName_t& appName,
                        const units::Duration roudiWaitingTimeout) noexcept;
    ~IpcRuntimeInterface() = default;

    /// @brief Not needed therefore deleted
    IpcRuntimeInterface(const IpcRuntimeInterface&) = delete;
    IpcRuntimeInterface& operator=(const IpcRuntimeInterface&) = delete;
    IpcRuntimeInterface(IpcRuntimeInterface&&) = delete;
    IpcRuntimeInterface& operator=(IpcRuntimeInterface&&) = delete;

    /// @brief sends the keep alive trigger to the RouDi daemon
    /// @return true if sending was successful, false if not
    bool sendKeepalive() noexcept;

    /// @brief send a request to the RouDi daemon
    /// @param[in] msg request to RouDi
    /// @param[out] answer response from RouDi
    /// @return true if communication was successful, false if not
    bool sendRequestToRouDi(const IpcMessage& msg, IpcMessage& answer) noexcept;

    /// @brief send a message to the RouDi daemon
    /// @param[in] msg message which will be send to RouDi
    /// @return true if communication was successful, otherwise false
    bool sendMessageToRouDi(const IpcMessage& msg) noexcept;

    /// @brief get the adress offset of the segment manager
    /// @return address offset as RelativePointer::offset_t
    RelativePointer::offset_t getSegmentManagerAddressOffset() const noexcept;

    /// @brief get the size of the management shared memory object
    /// @return size in bytes
    size_t getShmTopicSize() noexcept;

    /// @brief get the segment id of the shared memory object
    /// @return segment id
    uint64_t getSegmentId() const noexcept;

  private:
    enum class RegAckResult
    {
        SUCCESS,
        TIMEOUT
    };

    /// @brief
    /// @return
    void waitForRoudi(cxx::DeadlineTimer& timer) noexcept;

    /// @brief
    /// @return
    RegAckResult waitForRegAck(const int64_t transmissionTimestamp) noexcept;

  private:
    ProcessName_t m_appName;
    cxx::optional<RelativePointer::offset_t> m_segmentManagerAddressOffset;
    IpcInterfaceCreator m_AppIpcInterface;
    IpcInterfaceUser m_RoudiIpcInterface;
    uint64_t m_shmTopicSize{0U};
    uint64_t m_segmentId{0U};
};

} // namespace runtime
} // namespace iox

#endif // IOX_POSH_RUNTIME_IPC_RUNTIME_INTERFACE_HPP<|endoftext|>


<commit_before>/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                           License Agreement
//                For Open Source Computer Vision Library
//
// Copyright (C) 2013, NVIDIA Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//   * The name of the copyright holders may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the copyright holders or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/

#include "precomp.hpp"

// ----------------------------------------------------------------------
// CLAHE

namespace
{
    class CLAHE_CalcLut_Body : public cv::ParallelLoopBody
    {
    public:
        CLAHE_CalcLut_Body(const cv::Mat& src, cv::Mat& lut, cv::Size tileSize, int tilesX, int tilesY, int clipLimit, float lutScale) :
            src_(src), lut_(lut), tileSize_(tileSize), tilesX_(tilesX), tilesY_(tilesY), clipLimit_(clipLimit), lutScale_(lutScale)
        {
        }

        void operator ()(const cv::Range& range) const;

    private:
        cv::Mat src_;
        mutable cv::Mat lut_;

        cv::Size tileSize_;
        int tilesX_;
        int tilesY_;
        int clipLimit_;
        float lutScale_;
    };

    void CLAHE_CalcLut_Body::operator ()(const cv::Range& range) const
    {
        const int histSize = 256;

        uchar* tileLut = lut_.ptr(range.start);
        const size_t lut_step = lut_.step;

        for (int k = range.start; k < range.end; ++k, tileLut += lut_step)
        {
            const int ty = k / tilesX_;
            const int tx = k % tilesX_;

            // retrieve tile submatrix

            cv::Rect tileROI;
            tileROI.x = tx * tileSize_.width;
            tileROI.y = ty * tileSize_.height;
            tileROI.width = tileSize_.width;
            tileROI.height = tileSize_.height;

            const cv::Mat tile = src_(tileROI);

            // calc histogram

            int tileHist[histSize] = {0, };

            int height = tileROI.height;
            const size_t sstep = tile.step;
            for (const uchar* ptr = tile.ptr<uchar>(0); height--; ptr += sstep)
            {
                int x = 0;
                for (; x <= tileROI.width - 4; x += 4)
                {
                    int t0 = ptr[x], t1 = ptr[x+1];
                    tileHist[t0]++; tileHist[t1]++;
                    t0 = ptr[x+2]; t1 = ptr[x+3];
                    tileHist[t0]++; tileHist[t1]++;
                }

                for (; x < tileROI.width; ++x)
                    tileHist[ptr[x]]++;
            }

            // clip histogram

            if (clipLimit_ > 0)
            {
                // how many pixels were clipped
                int clipped = 0;
                for (int i = 0; i < histSize; ++i)
                {
                    if (tileHist[i] > clipLimit_)
                    {
                        clipped += tileHist[i] - clipLimit_;
                        tileHist[i] = clipLimit_;
                    }
                }

                // redistribute clipped pixels
                int redistBatch = clipped / histSize;
                int residual = clipped - redistBatch * histSize;

                for (int i = 0; i < histSize; ++i)
                    tileHist[i] += redistBatch;

                for (int i = 0; i < residual; ++i)
                    tileHist[i]++;
            }

            // calc Lut

            int sum = 0;
            for (int i = 0; i < histSize; ++i)
            {
                sum += tileHist[i];
                tileLut[i] = cv::saturate_cast<uchar>(sum * lutScale_);
            }
        }
    }

    class CLAHE_Interpolation_Body : public cv::ParallelLoopBody
    {
    public:
        CLAHE_Interpolation_Body(const cv::Mat& src, cv::Mat& dst, const cv::Mat& lut, cv::Size tileSize, int tilesX, int tilesY) :
            src_(src), dst_(dst), lut_(lut), tileSize_(tileSize), tilesX_(tilesX), tilesY_(tilesY)
        {
        }

        void operator ()(const cv::Range& range) const;

    private:
        cv::Mat src_;
        mutable cv::Mat dst_;
        cv::Mat lut_;

        cv::Size tileSize_;
        int tilesX_;
        int tilesY_;
    };

    void CLAHE_Interpolation_Body::operator ()(const cv::Range& range) const
    {
        const size_t lut_step = lut_.step;

        for (int y = range.start; y < range.end; ++y)
        {
            const uchar* srcRow = src_.ptr<uchar>(y);
            uchar* dstRow = dst_.ptr<uchar>(y);

            const float tyf = (static_cast<float>(y) / tileSize_.height) - 0.5f;

            int ty1 = cvFloor(tyf);
            int ty2 = ty1 + 1;

            const float ya = tyf - ty1;

            ty1 = std::max(ty1, 0);
            ty2 = std::min(ty2, tilesY_ - 1);

            const uchar* lutPlane1 = lut_.ptr(ty1 * tilesX_);
            const uchar* lutPlane2 = lut_.ptr(ty2 * tilesX_);

            for (int x = 0; x < src_.cols; ++x)
            {
                const float txf = (static_cast<float>(x) / tileSize_.width) - 0.5f;

                int tx1 = cvFloor(txf);
                int tx2 = tx1 + 1;

                const float xa = txf - tx1;

                tx1 = std::max(tx1, 0);
                tx2 = std::min(tx2, tilesX_ - 1);

                const int srcVal = srcRow[x];

                const size_t ind1 = tx1 * lut_step + srcVal;
                const size_t ind2 = tx2 * lut_step + srcVal;

                float res = 0;

                res += lutPlane1[ind1] * ((1.0f - xa) * (1.0f - ya));
                res += lutPlane1[ind2] * ((xa) * (1.0f - ya));
                res += lutPlane2[ind1] * ((1.0f - xa) * (ya));
                res += lutPlane2[ind2] * ((xa) * (ya));

                dstRow[x] = cv::saturate_cast<uchar>(res);
            }
        }
    }

    class CLAHE_Impl : public cv::CLAHE
    {
    public:
        CLAHE_Impl(double clipLimit = 40.0, int tilesX = 8, int tilesY = 8);

        cv::AlgorithmInfo* info() const;

        void apply(cv::InputArray src, cv::OutputArray dst);

        void setClipLimit(double clipLimit);
        double getClipLimit() const;

        void setTilesGridSize(cv::Size tileGridSize);
        cv::Size getTilesGridSize() const;

        void collectGarbage();

    private:
        double clipLimit_;
        int tilesX_;
        int tilesY_;

        cv::Mat srcExt_;
        cv::Mat lut_;
    };

    CLAHE_Impl::CLAHE_Impl(double clipLimit, int tilesX, int tilesY) :
        clipLimit_(clipLimit), tilesX_(tilesX), tilesY_(tilesY)
    {
    }

    CV_INIT_ALGORITHM(CLAHE_Impl, "CLAHE",
        obj.info()->addParam(obj, "clipLimit", obj.clipLimit_);
        obj.info()->addParam(obj, "tilesX", obj.tilesX_);
        obj.info()->addParam(obj, "tilesY", obj.tilesY_))

    void CLAHE_Impl::apply(cv::InputArray _src, cv::OutputArray _dst)
    {
        cv::Mat src = _src.getMat();

        CV_Assert( src.type() == CV_8UC1 );

        _dst.create( src.size(), src.type() );
        cv::Mat dst = _dst.getMat();

        const int histSize = 256;

        lut_.create(tilesX_ * tilesY_, histSize, CV_8UC1);

        cv::Size tileSize;
        cv::Mat srcForLut;

        if (src.cols % tilesX_ == 0 && src.rows % tilesY_ == 0)
        {
            tileSize = cv::Size(src.cols / tilesX_, src.rows / tilesY_);
            srcForLut = src;
        }
        else
        {
            cv::copyMakeBorder(src, srcExt_, 0, tilesY_ - (src.rows % tilesY_), 0, tilesX_ - (src.cols % tilesX_), cv::BORDER_REFLECT_101);

            tileSize = cv::Size(srcExt_.cols / tilesX_, srcExt_.rows / tilesY_);
            srcForLut = srcExt_;
        }

        const int tileSizeTotal = tileSize.area();
        const float lutScale = static_cast<float>(histSize - 1) / tileSizeTotal;

        int clipLimit = 0;
        if (clipLimit_ > 0.0)
        {
            clipLimit = static_cast<int>(clipLimit_ * tileSizeTotal / histSize);
            clipLimit = std::max(clipLimit, 1);
        }

        CLAHE_CalcLut_Body calcLutBody(srcForLut, lut_, tileSize, tilesX_, tilesY_, clipLimit, lutScale);
        cv::parallel_for_(cv::Range(0, tilesX_ * tilesY_), calcLutBody);

        CLAHE_Interpolation_Body interpolationBody(src, dst, lut_, tileSize, tilesX_, tilesY_);
        cv::parallel_for_(cv::Range(0, src.rows), interpolationBody);
    }

    void CLAHE_Impl::setClipLimit(double clipLimit)
    {
        clipLimit_ = clipLimit;
    }

    double CLAHE_Impl::getClipLimit() const
    {
        return clipLimit_;
    }

    void CLAHE_Impl::setTilesGridSize(cv::Size tileGridSize)
    {
        tilesX_ = tileGridSize.width;
        tilesY_ = tileGridSize.height;
    }

    cv::Size CLAHE_Impl::getTilesGridSize() const
    {
        return cv::Size(tilesX_, tilesY_);
    }

    void CLAHE_Impl::collectGarbage()
    {
        srcExt_.release();
        lut_.release();
    }
}

cv::Ptr<cv::CLAHE> cv::createCLAHE(double clipLimit, cv::Size tileGridSize)
{
    return new CLAHE_Impl(clipLimit, tileGridSize.width, tileGridSize.height);
}
<commit_msg>removed unused field<commit_after>/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                           License Agreement
//                For Open Source Computer Vision Library
//
// Copyright (C) 2013, NVIDIA Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//   * The name of the copyright holders may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the copyright holders or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/

#include "precomp.hpp"

// ----------------------------------------------------------------------
// CLAHE

namespace
{
    class CLAHE_CalcLut_Body : public cv::ParallelLoopBody
    {
    public:
        CLAHE_CalcLut_Body(const cv::Mat& src, cv::Mat& lut, cv::Size tileSize, int tilesX, int clipLimit, float lutScale) :
            src_(src), lut_(lut), tileSize_(tileSize), tilesX_(tilesX), clipLimit_(clipLimit), lutScale_(lutScale)
        {
        }

        void operator ()(const cv::Range& range) const;

    private:
        cv::Mat src_;
        mutable cv::Mat lut_;

        cv::Size tileSize_;
        int tilesX_;
        int clipLimit_;
        float lutScale_;
    };

    void CLAHE_CalcLut_Body::operator ()(const cv::Range& range) const
    {
        const int histSize = 256;

        uchar* tileLut = lut_.ptr(range.start);
        const size_t lut_step = lut_.step;

        for (int k = range.start; k < range.end; ++k, tileLut += lut_step)
        {
            const int ty = k / tilesX_;
            const int tx = k % tilesX_;

            // retrieve tile submatrix

            cv::Rect tileROI;
            tileROI.x = tx * tileSize_.width;
            tileROI.y = ty * tileSize_.height;
            tileROI.width = tileSize_.width;
            tileROI.height = tileSize_.height;

            const cv::Mat tile = src_(tileROI);

            // calc histogram

            int tileHist[histSize] = {0, };

            int height = tileROI.height;
            const size_t sstep = tile.step;
            for (const uchar* ptr = tile.ptr<uchar>(0); height--; ptr += sstep)
            {
                int x = 0;
                for (; x <= tileROI.width - 4; x += 4)
                {
                    int t0 = ptr[x], t1 = ptr[x+1];
                    tileHist[t0]++; tileHist[t1]++;
                    t0 = ptr[x+2]; t1 = ptr[x+3];
                    tileHist[t0]++; tileHist[t1]++;
                }

                for (; x < tileROI.width; ++x)
                    tileHist[ptr[x]]++;
            }

            // clip histogram

            if (clipLimit_ > 0)
            {
                // how many pixels were clipped
                int clipped = 0;
                for (int i = 0; i < histSize; ++i)
                {
                    if (tileHist[i] > clipLimit_)
                    {
                        clipped += tileHist[i] - clipLimit_;
                        tileHist[i] = clipLimit_;
                    }
                }

                // redistribute clipped pixels
                int redistBatch = clipped / histSize;
                int residual = clipped - redistBatch * histSize;

                for (int i = 0; i < histSize; ++i)
                    tileHist[i] += redistBatch;

                for (int i = 0; i < residual; ++i)
                    tileHist[i]++;
            }

            // calc Lut

            int sum = 0;
            for (int i = 0; i < histSize; ++i)
            {
                sum += tileHist[i];
                tileLut[i] = cv::saturate_cast<uchar>(sum * lutScale_);
            }
        }
    }

    class CLAHE_Interpolation_Body : public cv::ParallelLoopBody
    {
    public:
        CLAHE_Interpolation_Body(const cv::Mat& src, cv::Mat& dst, const cv::Mat& lut, cv::Size tileSize, int tilesX, int tilesY) :
            src_(src), dst_(dst), lut_(lut), tileSize_(tileSize), tilesX_(tilesX), tilesY_(tilesY)
        {
        }

        void operator ()(const cv::Range& range) const;

    private:
        cv::Mat src_;
        mutable cv::Mat dst_;
        cv::Mat lut_;

        cv::Size tileSize_;
        int tilesX_;
        int tilesY_;
    };

    void CLAHE_Interpolation_Body::operator ()(const cv::Range& range) const
    {
        const size_t lut_step = lut_.step;

        for (int y = range.start; y < range.end; ++y)
        {
            const uchar* srcRow = src_.ptr<uchar>(y);
            uchar* dstRow = dst_.ptr<uchar>(y);

            const float tyf = (static_cast<float>(y) / tileSize_.height) - 0.5f;

            int ty1 = cvFloor(tyf);
            int ty2 = ty1 + 1;

            const float ya = tyf - ty1;

            ty1 = std::max(ty1, 0);
            ty2 = std::min(ty2, tilesY_ - 1);

            const uchar* lutPlane1 = lut_.ptr(ty1 * tilesX_);
            const uchar* lutPlane2 = lut_.ptr(ty2 * tilesX_);

            for (int x = 0; x < src_.cols; ++x)
            {
                const float txf = (static_cast<float>(x) / tileSize_.width) - 0.5f;

                int tx1 = cvFloor(txf);
                int tx2 = tx1 + 1;

                const float xa = txf - tx1;

                tx1 = std::max(tx1, 0);
                tx2 = std::min(tx2, tilesX_ - 1);

                const int srcVal = srcRow[x];

                const size_t ind1 = tx1 * lut_step + srcVal;
                const size_t ind2 = tx2 * lut_step + srcVal;

                float res = 0;

                res += lutPlane1[ind1] * ((1.0f - xa) * (1.0f - ya));
                res += lutPlane1[ind2] * ((xa) * (1.0f - ya));
                res += lutPlane2[ind1] * ((1.0f - xa) * (ya));
                res += lutPlane2[ind2] * ((xa) * (ya));

                dstRow[x] = cv::saturate_cast<uchar>(res);
            }
        }
    }

    class CLAHE_Impl : public cv::CLAHE
    {
    public:
        CLAHE_Impl(double clipLimit = 40.0, int tilesX = 8, int tilesY = 8);

        cv::AlgorithmInfo* info() const;

        void apply(cv::InputArray src, cv::OutputArray dst);

        void setClipLimit(double clipLimit);
        double getClipLimit() const;

        void setTilesGridSize(cv::Size tileGridSize);
        cv::Size getTilesGridSize() const;

        void collectGarbage();

    private:
        double clipLimit_;
        int tilesX_;
        int tilesY_;

        cv::Mat srcExt_;
        cv::Mat lut_;
    };

    CLAHE_Impl::CLAHE_Impl(double clipLimit, int tilesX, int tilesY) :
        clipLimit_(clipLimit), tilesX_(tilesX), tilesY_(tilesY)
    {
    }

    CV_INIT_ALGORITHM(CLAHE_Impl, "CLAHE",
        obj.info()->addParam(obj, "clipLimit", obj.clipLimit_);
        obj.info()->addParam(obj, "tilesX", obj.tilesX_);
        obj.info()->addParam(obj, "tilesY", obj.tilesY_))

    void CLAHE_Impl::apply(cv::InputArray _src, cv::OutputArray _dst)
    {
        cv::Mat src = _src.getMat();

        CV_Assert( src.type() == CV_8UC1 );

        _dst.create( src.size(), src.type() );
        cv::Mat dst = _dst.getMat();

        const int histSize = 256;

        lut_.create(tilesX_ * tilesY_, histSize, CV_8UC1);

        cv::Size tileSize;
        cv::Mat srcForLut;

        if (src.cols % tilesX_ == 0 && src.rows % tilesY_ == 0)
        {
            tileSize = cv::Size(src.cols / tilesX_, src.rows / tilesY_);
            srcForLut = src;
        }
        else
        {
            cv::copyMakeBorder(src, srcExt_, 0, tilesY_ - (src.rows % tilesY_), 0, tilesX_ - (src.cols % tilesX_), cv::BORDER_REFLECT_101);

            tileSize = cv::Size(srcExt_.cols / tilesX_, srcExt_.rows / tilesY_);
            srcForLut = srcExt_;
        }

        const int tileSizeTotal = tileSize.area();
        const float lutScale = static_cast<float>(histSize - 1) / tileSizeTotal;

        int clipLimit = 0;
        if (clipLimit_ > 0.0)
        {
            clipLimit = static_cast<int>(clipLimit_ * tileSizeTotal / histSize);
            clipLimit = std::max(clipLimit, 1);
        }

        CLAHE_CalcLut_Body calcLutBody(srcForLut, lut_, tileSize, tilesX_, clipLimit, lutScale);
        cv::parallel_for_(cv::Range(0, tilesX_ * tilesY_), calcLutBody);

        CLAHE_Interpolation_Body interpolationBody(src, dst, lut_, tileSize, tilesX_, tilesY_);
        cv::parallel_for_(cv::Range(0, src.rows), interpolationBody);
    }

    void CLAHE_Impl::setClipLimit(double clipLimit)
    {
        clipLimit_ = clipLimit;
    }

    double CLAHE_Impl::getClipLimit() const
    {
        return clipLimit_;
    }

    void CLAHE_Impl::setTilesGridSize(cv::Size tileGridSize)
    {
        tilesX_ = tileGridSize.width;
        tilesY_ = tileGridSize.height;
    }

    cv::Size CLAHE_Impl::getTilesGridSize() const
    {
        return cv::Size(tilesX_, tilesY_);
    }

    void CLAHE_Impl::collectGarbage()
    {
        srcExt_.release();
        lut_.release();
    }
}

cv::Ptr<cv::CLAHE> cv::createCLAHE(double clipLimit, cv::Size tileGridSize)
{
    return new CLAHE_Impl(clipLimit, tileGridSize.width, tileGridSize.height);
}
<|endoftext|>