1 /* 2 * This program source code file is part of KiCad, a free EDA CAD application. 3 * 4 * Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt> 5 * Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, you may find one here: 19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html 20 * or you may search the http://www.gnu.org website for the version 2 license, 21 * or you may write to the Free Software Foundation, Inc., 22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 23 */ 24 25 /** 26 * @file image.h 27 * @brief one 8bit-channel image definition. 28 */ 29 30 #ifndef IMAGE_H 31 #define IMAGE_H 32 33 #include <wx/string.h> 34 35 /// Image operation type 36 enum class IMAGE_OP 37 { 38 RAW, 39 ADD, 40 SUB, 41 DIF, 42 MUL, 43 AND, 44 OR, 45 XOR, 46 BLEND50, 47 MIN, 48 MAX 49 }; 50 51 52 /// Image wrap type enumeration 53 enum class IMAGE_WRAP 54 { 55 ZERO, ///< Coords that wraps are not evaluated 56 CLAMP, ///< Coords are clamped to image size 57 WRAP ///< Coords are wrapped around 58 }; 59 60 61 /// Filter type enumeration 62 enum class IMAGE_FILTER 63 { 64 HIPASS, 65 GAUSSIAN_BLUR, 66 GAUSSIAN_BLUR2, 67 INVERT_BLUR, 68 CARTOON, 69 EMBOSS, 70 SHARPEN, 71 MELT, 72 SOBEL_GX, 73 SOBEL_GY, 74 BLUR_3X3, 75 }; 76 77 /// 5x5 Filter struct parameters 78 struct S_FILTER 79 { 80 signed char kernel[5][5]; 81 unsigned int div; 82 unsigned char offset; 83 }; 84 85 86 /** 87 * Manage an 8-bit channel image. 88 */ 89 class IMAGE 90 { 91 public: 92 /** 93 * Construct a IMAGE based on image size. 94 * 95 * @param aXsize x size 96 * @param aYsize y size 97 */ 98 IMAGE( unsigned int aXsize, unsigned int aYsize ); 99 100 /** 101 * Construct a IMAGE based from an existing image. 102 * 103 * It will make a copy the \a aSrcImage. 104 * 105 * @param aSrcImage 106 */ 107 IMAGE( const IMAGE& aSrcImage ); 108 109 ~IMAGE(); 110 111 /** 112 * Set a value in a pixel position, position is clamped in accordance with the 113 * current clamp settings. 114 * 115 * @param aX x position 116 * @param aY y position 117 * @param aValue value to set the pixel 118 */ 119 void Setpixel( int aX, int aY, unsigned char aValue ); 120 121 /** 122 * Get the pixel value from pixel position, position is clamped in accord with the 123 * current clamp settings. 124 * 125 * @param aX x position 126 * @param aY y position 127 * @return unsigned char - pixel value 128 */ 129 unsigned char Getpixel( int aX, int aY ) const; 130 131 /** 132 * Draw a horizontal line. 133 * 134 * @param aXStart x start position 135 * @param aXEnd x end position 136 * @param aY y position 137 * @param aValue value to add 138 */ 139 void Hline( int aXStart, int aXEnd, int aY, unsigned char aValue ); 140 141 void CircleFilled( int aCx, int aCy, int aRadius, unsigned char aValue ); 142 143 /** 144 * Perform a copy operation based on \a aOperation type. 145 * 146 * The available image operations. 147 * - IMAGE_OP::RAW this <- aImgA 148 * - IMAGE_OP::ADD this <- CLAMP(aImgA + aImgB) 149 * - IMAGE_OP::SUB this <- CLAMP(aImgA - aImgB) 150 * - IMAGE_OP::DIF this <- abs(aImgA - aImgB) 151 * - IMAGE_OP::MUL this <- aImgA * aImgB 152 * - IMAGE_OP::AND this <- aImgA & aImgB 153 * - IMAGE_OP::OR this <- aImgA | aImgB 154 * - IMAGE_OP::XOR this <- aImgA ^ aImgB 155 * - IMAGE_OP::BLEND50 this <- (aImgA + aImgB) / 2 156 * - IMAGE_OP::MIN this <- (aImgA < aImgB) ? aImgA : aImgB 157 * - IMAGE_OP::MAX this <- (aImgA > aImgB) ? aImgA : aImgB 158 * 159 * @param aImgA an image input. 160 * @param aImgB an image input. 161 * @param aOperation operation to perform 162 */ 163 void CopyFull( const IMAGE* aImgA, const IMAGE* aImgB, IMAGE_OP aOperation ); 164 165 /** 166 * Invert the values of this image <- (255 - this) 167 */ 168 void Invert(); 169 170 /** 171 * Apply a filter to the input image and store it in the image class. 172 * 173 * @param aInImg input image 174 * @param aFilterType filter type to apply 175 */ 176 void EfxFilter( IMAGE* aInImg, IMAGE_FILTER aFilterType ); 177 178 /** 179 * Apply a filter to the input image and store it in the image class. 180 * skip the circle center defined by radius 181 * 182 * @param aInImg input image 183 * @param aFilterType filter type to apply 184 * @param aRadius center circle that the effect will not be applied 185 */ 186 void EfxFilter_SkipCenter( IMAGE* aInImg, IMAGE_FILTER aFilterType, unsigned int aRadius ); 187 188 /** 189 * Save image buffer to a PNG file into the working folder. 190 * 191 * Each RGB channel will have the 8bit-channel from the image. 192 * 193 * @param aFileName file name (without extension) 194 */ 195 void SaveAsPNG( const wxString& aFileName ) const; 196 197 /** 198 * Set the current channel from a float normalized (0.0 - 1.0) buffer. 199 * 200 * this <- CLAMP(NormalizedFloat * 255) 201 * 202 * @param aNormalizedFloatArray a float array with the same size of the image 203 */ 204 void SetPixelsFromNormalizedFloat( const float* aNormalizedFloatArray ); 205 206 /** 207 * Get the image buffer pointer. 208 * 209 * @return unsigned char* the pointer of the buffer 8bit channel. 210 */ 211 unsigned char* GetBuffer() const; 212 GetWidth()213 unsigned int GetWidth() const { return m_width; } GetHeight()214 unsigned int GetHeight() const { return m_height; } 215 216 private: 217 /** 218 * Calculate the coordinates points in accord with the current clamping settings. 219 * 220 * @param aXo X coordinate to be converted (output). 221 * @param aXo Y coordinate to be converted (output). 222 * @return bool - true if the coordinates are inside the image, false otherwise. 223 */ 224 bool wrapCoords( int* aXo, int* aYo ) const; 225 226 void plot8CircleLines( int aCx, int aCy, int aX, int aY, unsigned char aValue ); 227 228 unsigned char* m_pixels; ///< buffer to store the image 8bit-channel 229 unsigned int m_width; ///< width of the image 230 unsigned int m_height; ///< height of the image 231 unsigned int m_wxh; ///< width * height precalc value 232 IMAGE_WRAP m_wraping; ///< current wrapping type 233 }; 234 235 #endif // IMAGE_H 236