2015-12-08 07:31:57 +00:00
|
|
|
/*
|
|
|
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
|
|
|
*
|
2016-07-19 17:35:25 +00:00
|
|
|
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
2020-12-13 23:02:57 +00:00
|
|
|
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
2015-12-08 07:31:57 +00:00
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, you may find one here:
|
|
|
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|
|
|
* or you may search the http://www.gnu.org website for the version 2 license,
|
|
|
|
* or you may write to the Free Software Foundation, Inc.,
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
2021-01-03 22:23:00 +00:00
|
|
|
* @file image.h
|
|
|
|
* @brief one 8bit-channel image definition.
|
2015-12-08 07:31:57 +00:00
|
|
|
*/
|
|
|
|
|
2021-01-02 21:05:29 +00:00
|
|
|
#ifndef IMAGE_H
|
|
|
|
#define IMAGE_H
|
2015-12-08 07:31:57 +00:00
|
|
|
|
|
|
|
#include <wx/string.h>
|
|
|
|
|
|
|
|
/// Image operation type
|
2019-12-30 13:01:06 +00:00
|
|
|
enum class IMAGE_OP
|
|
|
|
{
|
|
|
|
RAW,
|
|
|
|
ADD,
|
|
|
|
SUB,
|
|
|
|
DIF,
|
|
|
|
MUL,
|
|
|
|
AND,
|
|
|
|
OR,
|
|
|
|
XOR,
|
|
|
|
BLEND50,
|
|
|
|
MIN,
|
|
|
|
MAX
|
2015-12-08 07:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/// Image wrap type enumeration
|
2019-12-30 13:01:06 +00:00
|
|
|
enum class IMAGE_WRAP
|
|
|
|
{
|
|
|
|
ZERO, ///< Coords that wraps are not evaluated
|
|
|
|
CLAMP, ///< Coords are clamped to image size
|
2020-12-13 23:02:57 +00:00
|
|
|
WRAP ///< Coords are wrapped around
|
2015-12-08 07:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/// Filter type enumeration
|
2019-12-30 13:01:06 +00:00
|
|
|
enum class IMAGE_FILTER
|
|
|
|
{
|
|
|
|
HIPASS,
|
|
|
|
GAUSSIAN_BLUR,
|
|
|
|
GAUSSIAN_BLUR2,
|
|
|
|
INVERT_BLUR,
|
|
|
|
CARTOON,
|
|
|
|
EMBOSS,
|
|
|
|
SHARPEN,
|
|
|
|
MELT,
|
|
|
|
SOBEL_GX,
|
|
|
|
SOBEL_GY,
|
|
|
|
BLUR_3X3,
|
2015-12-08 07:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/// 5x5 Filter struct parameters
|
2020-12-13 23:02:57 +00:00
|
|
|
typedef struct
|
|
|
|
{
|
2015-12-08 07:31:57 +00:00
|
|
|
signed char kernel[5][5];
|
2016-01-14 02:50:16 +00:00
|
|
|
unsigned int div;
|
2015-12-08 07:31:57 +00:00
|
|
|
unsigned char offset;
|
2020-12-13 23:02:57 +00:00
|
|
|
} S_FILTER;
|
2015-12-08 07:31:57 +00:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
2020-12-13 23:02:57 +00:00
|
|
|
* Manage an 8-bit channel image.
|
2015-12-08 07:31:57 +00:00
|
|
|
*/
|
2021-01-02 21:05:29 +00:00
|
|
|
class IMAGE
|
2015-12-08 07:31:57 +00:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
/**
|
2021-01-02 21:05:29 +00:00
|
|
|
* Construct a IMAGE based on image size.
|
2020-12-13 23:02:57 +00:00
|
|
|
*
|
2015-12-08 07:31:57 +00:00
|
|
|
* @param aXsize x size
|
|
|
|
* @param aYsize y size
|
|
|
|
*/
|
2021-01-02 21:05:29 +00:00
|
|
|
IMAGE( unsigned int aXsize, unsigned int aYsize );
|
2015-12-08 07:31:57 +00:00
|
|
|
|
|
|
|
/**
|
2021-01-02 21:05:29 +00:00
|
|
|
* Construct a IMAGE based from an existing image.
|
2020-12-13 23:02:57 +00:00
|
|
|
*
|
|
|
|
* It will make a copy the \a aSrcImage.
|
|
|
|
*
|
2015-12-08 07:31:57 +00:00
|
|
|
* @param aSrcImage
|
|
|
|
*/
|
2021-01-02 21:05:29 +00:00
|
|
|
IMAGE( const IMAGE& aSrcImage );
|
2015-12-08 07:31:57 +00:00
|
|
|
|
2021-01-02 21:05:29 +00:00
|
|
|
~IMAGE();
|
2015-12-08 07:31:57 +00:00
|
|
|
|
|
|
|
/**
|
2020-12-13 23:02:57 +00:00
|
|
|
* Set a value in a pixel position, position is clamped in accordance with the
|
|
|
|
* current clamp settings.
|
|
|
|
*
|
2015-12-08 07:31:57 +00:00
|
|
|
* @param aX x position
|
|
|
|
* @param aY y position
|
|
|
|
* @param aValue value to set the pixel
|
|
|
|
*/
|
|
|
|
void Setpixel( int aX, int aY, unsigned char aValue );
|
2015-12-10 00:31:44 +00:00
|
|
|
|
2015-12-08 07:31:57 +00:00
|
|
|
/**
|
2020-12-13 23:02:57 +00:00
|
|
|
* Get the pixel value from pixel position, position is clamped in accord with the
|
|
|
|
* current clamp settings.
|
|
|
|
*
|
2015-12-08 07:31:57 +00:00
|
|
|
* @param aX x position
|
|
|
|
* @param aY y position
|
|
|
|
* @return unsigned char - pixel value
|
|
|
|
*/
|
|
|
|
unsigned char Getpixel( int aX, int aY ) const;
|
|
|
|
|
|
|
|
/**
|
2020-12-13 23:02:57 +00:00
|
|
|
* Draw a horizontal line.
|
|
|
|
*
|
|
|
|
* @param aXStart x start position
|
|
|
|
* @param aXEnd x end position
|
|
|
|
* @param aY y position
|
|
|
|
* @param aValue value to add
|
2015-12-08 07:31:57 +00:00
|
|
|
*/
|
|
|
|
void Hline( int aXStart, int aXEnd, int aY, unsigned char aValue );
|
|
|
|
|
|
|
|
void CircleFilled( int aCx, int aCy, int aRadius, unsigned char aValue );
|
|
|
|
|
|
|
|
/**
|
2020-12-13 23:02:57 +00:00
|
|
|
* Perform a copy operation based on \a aOperation type.
|
|
|
|
*
|
|
|
|
* The available image operations.
|
|
|
|
* - IMAGE_OP::RAW this <- aImgA
|
|
|
|
* - IMAGE_OP::ADD this <- CLAMP(aImgA + aImgB)
|
|
|
|
* - IMAGE_OP::SUB this <- CLAMP(aImgA - aImgB)
|
|
|
|
* - IMAGE_OP::DIF this <- abs(aImgA - aImgB)
|
|
|
|
* - IMAGE_OP::MUL this <- aImgA * aImgB
|
|
|
|
* - IMAGE_OP::AND this <- aImgA & aImgB
|
|
|
|
* - IMAGE_OP::OR this <- aImgA | aImgB
|
|
|
|
* - IMAGE_OP::XOR this <- aImgA ^ aImgB
|
|
|
|
* - IMAGE_OP::BLEND50 this <- (aImgA + aImgB) / 2
|
|
|
|
* - IMAGE_OP::MIN this <- (aImgA < aImgB) ? aImgA : aImgB
|
|
|
|
* - IMAGE_OP::MAX this <- (aImgA > aImgB) ? aImgA : aImgB
|
|
|
|
*
|
|
|
|
* @param aImgA an image input.
|
|
|
|
* @param aImgB an image input.
|
2015-12-08 07:31:57 +00:00
|
|
|
* @param aOperation operation to perform
|
|
|
|
*/
|
2021-01-02 21:05:29 +00:00
|
|
|
void CopyFull( const IMAGE* aImgA, const IMAGE* aImgB, IMAGE_OP aOperation );
|
2015-12-08 07:31:57 +00:00
|
|
|
|
|
|
|
/**
|
2020-12-13 23:02:57 +00:00
|
|
|
* Invert the values of this image <- (255 - this)
|
2015-12-08 07:31:57 +00:00
|
|
|
*/
|
|
|
|
void Invert();
|
|
|
|
|
|
|
|
/**
|
2020-12-13 23:02:57 +00:00
|
|
|
* Apply a filter to the input image and store it in the image class.
|
|
|
|
*
|
2015-12-08 07:31:57 +00:00
|
|
|
* @param aInImg input image
|
|
|
|
* @param aFilterType filter type to apply
|
|
|
|
*/
|
2021-01-02 21:05:29 +00:00
|
|
|
void EfxFilter( IMAGE* aInImg, IMAGE_FILTER aFilterType );
|
2015-12-08 07:31:57 +00:00
|
|
|
|
2021-04-20 21:19:11 +00:00
|
|
|
/**
|
|
|
|
* Apply a filter to the input image and store it in the image class.
|
|
|
|
* skip the circle center defined by radius
|
|
|
|
*
|
|
|
|
* @param aInImg input image
|
|
|
|
* @param aFilterType filter type to apply
|
|
|
|
* @param aRadius center circle that the effect will not be applied
|
|
|
|
*/
|
|
|
|
void EfxFilter_SkipCenter( IMAGE* aInImg, IMAGE_FILTER aFilterType, unsigned int aRadius );
|
|
|
|
|
2015-12-08 07:31:57 +00:00
|
|
|
/**
|
2020-12-13 23:02:57 +00:00
|
|
|
* Save image buffer to a PNG file into the working folder.
|
|
|
|
*
|
|
|
|
* Each RGB channel will have the 8bit-channel from the image.
|
|
|
|
*
|
|
|
|
* @param aFileName file name (without extension)
|
2015-12-08 07:31:57 +00:00
|
|
|
*/
|
2017-09-23 09:20:10 +00:00
|
|
|
void SaveAsPNG( const wxString& aFileName ) const;
|
2015-12-08 07:31:57 +00:00
|
|
|
|
|
|
|
/**
|
2020-12-13 23:02:57 +00:00
|
|
|
* Set the current channel from a float normalized (0.0 - 1.0) buffer.
|
|
|
|
*
|
2015-12-08 07:31:57 +00:00
|
|
|
* this <- CLAMP(NormalizedFloat * 255)
|
2020-12-13 23:02:57 +00:00
|
|
|
*
|
2015-12-08 07:31:57 +00:00
|
|
|
* @param aNormalizedFloatArray a float array with the same size of the image
|
|
|
|
*/
|
2020-12-13 23:02:57 +00:00
|
|
|
void SetPixelsFromNormalizedFloat( const float* aNormalizedFloatArray );
|
2015-12-08 07:31:57 +00:00
|
|
|
|
|
|
|
/**
|
2020-12-13 23:02:57 +00:00
|
|
|
* Get the image buffer pointer.
|
|
|
|
*
|
|
|
|
* @return unsigned char* the pointer of the buffer 8bit channel.
|
2015-12-08 07:31:57 +00:00
|
|
|
*/
|
|
|
|
unsigned char* GetBuffer() const;
|
|
|
|
|
|
|
|
unsigned int GetWidth() const { return m_width; }
|
|
|
|
unsigned int GetHeight() const { return m_height; }
|
|
|
|
|
2020-12-13 23:02:57 +00:00
|
|
|
private:
|
2015-12-08 07:31:57 +00:00
|
|
|
/**
|
2020-12-13 23:02:57 +00:00
|
|
|
* Calculate the coordinates points in accord with the current clamping settings.
|
|
|
|
*
|
|
|
|
* @param aXo X coordinate to be converted (output).
|
|
|
|
* @param aXo Y coordinate to be converted (output).
|
|
|
|
* @return bool - true if the coordinates are inside the image, false otherwise.
|
2015-12-08 07:31:57 +00:00
|
|
|
*/
|
2021-01-02 21:05:29 +00:00
|
|
|
bool wrapCoords( int* aXo, int* aYo ) const;
|
2015-12-08 07:31:57 +00:00
|
|
|
|
|
|
|
void plot8CircleLines( int aCx, int aCy, int aX, int aY, unsigned char aValue );
|
|
|
|
|
|
|
|
unsigned char* m_pixels; ///< buffer to store the image 8bit-channel
|
|
|
|
unsigned int m_width; ///< width of the image
|
|
|
|
unsigned int m_height; ///< height of the image
|
|
|
|
unsigned int m_wxh; ///< width * height precalc value
|
2019-12-30 13:01:06 +00:00
|
|
|
IMAGE_WRAP m_wraping; ///< current wrapping type
|
2015-12-08 07:31:57 +00:00
|
|
|
};
|
|
|
|
|
2021-01-02 21:05:29 +00:00
|
|
|
#endif // IMAGE_H
|