41#define CLAMP( n, min, max ) {if( n < min ) n=min; else if( n > max ) n = max;} 
   47    m_wxh    = aXsize * aYsize;
 
 
   87        x = ( x < 0 ) ? 0 : x;
 
   89        y = ( y < 0 ) ? 0 : y;
 
   94        x = ( x < 0 ) ? ( ( 
m_width - 1 ) + x ) : x;
 
   96        y = ( y < 0 ) ? ( ( 
m_height - 1 ) + y ) : y;
 
  104    if( ( x < 0 ) || ( x >= (
int) 
m_width ) || ( y < 0 ) || ( y >= (
int) 
m_height ) )
 
 
  116    Hline( aCx - aX, aCx + aX, aCy + aY, aValue );
 
  117    Hline( aCx - aX, aCx + aX, aCy - aY, aValue );
 
  118    Hline( aCx - aY, aCx + aY, aCy + aX, aValue );
 
  119    Hline( aCx - aY, aCx + aY, aCy - aX, aValue );
 
 
  139void IMAGE::Hline( 
int aXStart, 
int aXEnd, 
int aY, 
unsigned char aValue )
 
  141    if( ( aY < 0 ) || ( aY >= (
int) 
m_height ) || ( ( aXStart < 0 ) && ( aXEnd < 0 ) )
 
  142      || ( ( aXStart >= (
int) 
m_width ) && ( aXEnd >= (
int) 
m_width ) ) )
 
  145    if( aXStart > aXEnd )
 
  161    unsigned char* pixelPtrEnd = pixelPtr + (
unsigned int) ( ( aXEnd - aXStart ) + 1 );
 
  163    while( pixelPtr < pixelPtrEnd )
 
 
  177    int xChange = 1 - 2 * aRadius;
 
  185        radiusError += yChange;
 
  188        if( ( 2 * radiusError + xChange ) > 0 )
 
  191            radiusError += xChange;
 
 
  200    for( 
unsigned int it = 0; it < 
m_wxh; it++ )
 
 
  211        if( aImgA == 
nullptr )
 
  216        if( ( aImgA == 
nullptr ) || ( aImgB == 
nullptr ) )
 
  227        for( 
unsigned int it = 0;it < 
m_wxh; it++ )
 
  233            aV = (aV > 255)?255:aV;
 
  240        for( 
unsigned int it = 0;it < 
m_wxh; it++ )
 
  253        for( 
unsigned int it = 0;it < 
m_wxh; it++ )
 
  263        for( 
unsigned int it = 0;it < 
m_wxh; it++ )
 
  269                    (
unsigned char) ( ( ( (
float) aV / 255.0f ) * ( (
float) bV / 255.0f ) ) * 255 );
 
  274        for( 
unsigned int it = 0;it < 
m_wxh; it++ )
 
  281        for( 
unsigned int it = 0;it < 
m_wxh; it++ )
 
  288        for( 
unsigned int it = 0;it < 
m_wxh; it++ )
 
  295        for( 
unsigned int it = 0;it < 
m_wxh; it++ )
 
  305        for( 
unsigned int it = 0;it < 
m_wxh; it++ )
 
  315        for( 
unsigned int it = 0;it < 
m_wxh; it++ )
 
 
  337    {   { 0, -1, -1, -1,  0},
 
  339        {-1, -4, 13, -4, -1},
 
  385    {   {-1, -1, -1, -1,  0},
 
  397    {   {-1, -1, -1, -1,  0},
 
  409    {   {-1, -1, -1, -1, -1},
 
  449        {-1, -2, -4, -2, -1},
 
 
  481    std::atomic<size_t> nextRow( 0 );
 
  482    std::atomic<size_t> threadsFinished( 0 );
 
  484    size_t parallelThreadCount = std::max<size_t>( std::thread::hardware_concurrency(), 2 );
 
  486    for( 
size_t ii = 0; ii < parallelThreadCount; ++ii )
 
  488        std::thread t = std::thread( [&]()
 
  490            for( 
size_t iy = nextRow.fetch_add( 1 ); iy < 
m_height; iy = nextRow.fetch_add( 1 ) )
 
  492                for( 
size_t ix = 0; ix < 
m_width; ix++ )
 
  496                    for( 
size_t sy = 0; sy < 5; sy++ )
 
  498                        for( 
size_t sx = 0; sx < 5; sx++ )
 
  500                            int factor = 
filter.kernel[sx][sy];
 
  501                            unsigned char pixelv = aInImg->
Getpixel( ix + sx - 2, iy + sy - 2 );
 
  503                            v += pixelv * factor;
 
  522    while( threadsFinished < parallelThreadCount )
 
  523        std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) );
 
 
  536    const unsigned int radiusSquared = aRadius * aRadius;
 
  538    const unsigned int xCenter = 
m_width / 2;
 
  539    const unsigned int yCenter = 
m_height / 2;
 
  541    for( 
size_t iy = 0; iy < 
m_height; iy++ )
 
  543        int yc = iy - yCenter;
 
  545        unsigned int ycsq = yc * yc;
 
  547        for( 
size_t ix = 0; ix < 
m_width; ix++ )
 
  549            int xc = ix - xCenter;
 
  551            unsigned int xcsq = xc * xc;
 
  553            if( ( xcsq + ycsq ) < radiusSquared )
 
  555                const unsigned int offset = ix + iy * 
m_width;
 
  564            for( 
size_t sy = 0; sy < 5; sy++ )
 
  566                for( 
size_t sx = 0; sx < 5; sx++ )
 
  568                    int factor = 
filter.kernel[sx][sy];
 
  569                    unsigned char pixelv = aInImg->
Getpixel( ix + sx - 2, iy + sy - 2 );
 
  571                    v += pixelv * factor;
 
 
  587    for( 
unsigned int i = 0; i < 
m_wxh; i++ )
 
  589        int v = aNormalizedFloatArray[i] * 255;
 
 
void DBG_SaveBuffer(const wxString &aFileName, const unsigned char *aInBuffer, unsigned int aXSize, unsigned int aYSize)
 
IMAGE_WRAP m_wraping
current wrapping type
 
void CircleFilled(int aCx, int aCy, int aRadius, unsigned char aValue)
 
void EfxFilter(IMAGE *aInImg, IMAGE_FILTER aFilterType)
Apply a filter to the input image and store it in the image class.
 
void CopyFull(const IMAGE *aImgA, const IMAGE *aImgB, IMAGE_OP aOperation)
Perform a copy operation based on aOperation type.
 
unsigned int m_width
width of the image
 
void SaveAsPNG(const wxString &aFileName) const
Save image buffer to a PNG file into the working folder.
 
void EfxFilter_SkipCenter(IMAGE *aInImg, IMAGE_FILTER aFilterType, unsigned int aRadius)
Apply a filter to the input image and store it in the image class.
 
unsigned char * GetBuffer() const
Get the image buffer pointer.
 
void Setpixel(int aX, int aY, unsigned char aValue)
Set a value in a pixel position, position is clamped in accordance with the current clamp settings.
 
unsigned int m_height
height of the image
 
unsigned char * m_pixels
buffer to store the image 8bit-channel
 
void Invert()
Invert the values of this image <- (255 - this)
 
void SetPixelsFromNormalizedFloat(const float *aNormalizedFloatArray)
Set the current channel from a float normalized (0.0 - 1.0) buffer.
 
IMAGE(unsigned int aXsize, unsigned int aYsize)
Construct a IMAGE based on image size.
 
unsigned int GetHeight() const
 
void plot8CircleLines(int aCx, int aCy, int aX, int aY, unsigned char aValue)
 
void Hline(int aXStart, int aXEnd, int aY, unsigned char aValue)
Draw a horizontal line.
 
unsigned char Getpixel(int aX, int aY) const
Get the pixel value from pixel position, position is clamped in accord with the current clamp setting...
 
bool wrapCoords(int *aXo, int *aYo) const
Calculate the coordinates points in accord with the current clamping settings.
 
unsigned int GetWidth() const
 
unsigned int m_wxh
width * height precalc value
 
static const S_FILTER FILTERS[]
 
one 8bit-channel image definition.
 
@ ZERO
Coords that wraps are not evaluated.
 
@ WRAP
Coords are wrapped around.
 
@ CLAMP
Coords are clamped to image size.
 
IMAGE_FILTER
Filter type enumeration.
 
IMAGE_OP
Image operation type.
 
5x5 Filter struct parameters