You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

235 lines
6.6 KiB

  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. * @file image.h
  26. * @brief one 8bit-channel image definition.
  27. */
  28. #ifndef IMAGE_H
  29. #define IMAGE_H
  30. #include <wx/string.h>
  31. /// Image operation type
  32. enum class IMAGE_OP
  33. {
  34. RAW,
  35. ADD,
  36. SUB,
  37. DIF,
  38. MUL,
  39. AND,
  40. OR,
  41. XOR,
  42. BLEND50,
  43. MIN,
  44. MAX
  45. };
  46. /// Image wrap type enumeration
  47. enum class IMAGE_WRAP
  48. {
  49. ZERO, ///< Coords that wraps are not evaluated
  50. CLAMP, ///< Coords are clamped to image size
  51. WRAP ///< Coords are wrapped around
  52. };
  53. /// Filter type enumeration
  54. enum class IMAGE_FILTER
  55. {
  56. HIPASS,
  57. GAUSSIAN_BLUR,
  58. GAUSSIAN_BLUR2,
  59. INVERT_BLUR,
  60. CARTOON,
  61. EMBOSS,
  62. SHARPEN,
  63. MELT,
  64. SOBEL_GX,
  65. SOBEL_GY,
  66. BLUR_3X3,
  67. };
  68. /// 5x5 Filter struct parameters
  69. struct S_FILTER
  70. {
  71. signed char kernel[5][5];
  72. unsigned int div;
  73. unsigned char offset;
  74. };
  75. /**
  76. * Manage an 8-bit channel image.
  77. */
  78. class IMAGE
  79. {
  80. public:
  81. /**
  82. * Construct a IMAGE based on image size.
  83. *
  84. * @param aXsize x size
  85. * @param aYsize y size
  86. */
  87. IMAGE( unsigned int aXsize, unsigned int aYsize );
  88. /**
  89. * Construct a IMAGE based from an existing image.
  90. *
  91. * It will make a copy the \a aSrcImage.
  92. *
  93. * @param aSrcImage
  94. */
  95. IMAGE( const IMAGE& aSrcImage );
  96. ~IMAGE();
  97. /**
  98. * Set a value in a pixel position, position is clamped in accordance with the
  99. * current clamp settings.
  100. *
  101. * @param aX x position
  102. * @param aY y position
  103. * @param aValue value to set the pixel
  104. */
  105. void Setpixel( int aX, int aY, unsigned char aValue );
  106. /**
  107. * Get the pixel value from pixel position, position is clamped in accord with the
  108. * current clamp settings.
  109. *
  110. * @param aX x position
  111. * @param aY y position
  112. * @return unsigned char - pixel value
  113. */
  114. unsigned char Getpixel( int aX, int aY ) const;
  115. /**
  116. * Draw a horizontal line.
  117. *
  118. * @param aXStart x start position
  119. * @param aXEnd x end position
  120. * @param aY y position
  121. * @param aValue value to add
  122. */
  123. void Hline( int aXStart, int aXEnd, int aY, unsigned char aValue );
  124. void CircleFilled( int aCx, int aCy, int aRadius, unsigned char aValue );
  125. /**
  126. * Perform a copy operation based on \a aOperation type.
  127. *
  128. * The available image operations.
  129. * - IMAGE_OP::RAW this <- aImgA
  130. * - IMAGE_OP::ADD this <- CLAMP(aImgA + aImgB)
  131. * - IMAGE_OP::SUB this <- CLAMP(aImgA - aImgB)
  132. * - IMAGE_OP::DIF this <- abs(aImgA - aImgB)
  133. * - IMAGE_OP::MUL this <- aImgA * aImgB
  134. * - IMAGE_OP::AND this <- aImgA & aImgB
  135. * - IMAGE_OP::OR this <- aImgA | aImgB
  136. * - IMAGE_OP::XOR this <- aImgA ^ aImgB
  137. * - IMAGE_OP::BLEND50 this <- (aImgA + aImgB) / 2
  138. * - IMAGE_OP::MIN this <- (aImgA < aImgB) ? aImgA : aImgB
  139. * - IMAGE_OP::MAX this <- (aImgA > aImgB) ? aImgA : aImgB
  140. *
  141. * @param aImgA an image input.
  142. * @param aImgB an image input.
  143. * @param aOperation operation to perform
  144. */
  145. void CopyFull( const IMAGE* aImgA, const IMAGE* aImgB, IMAGE_OP aOperation );
  146. /**
  147. * Invert the values of this image <- (255 - this)
  148. */
  149. void Invert();
  150. /**
  151. * Apply a filter to the input image and store it in the image class.
  152. *
  153. * @param aInImg input image
  154. * @param aFilterType filter type to apply
  155. */
  156. void EfxFilter( IMAGE* aInImg, IMAGE_FILTER aFilterType );
  157. /**
  158. * Apply a filter to the input image and store it in the image class.
  159. * skip the circle center defined by radius
  160. *
  161. * @param aInImg input image
  162. * @param aFilterType filter type to apply
  163. * @param aRadius center circle that the effect will not be applied
  164. */
  165. void EfxFilter_SkipCenter( IMAGE* aInImg, IMAGE_FILTER aFilterType, unsigned int aRadius );
  166. /**
  167. * Save image buffer to a PNG file into the working folder.
  168. *
  169. * Each RGB channel will have the 8bit-channel from the image.
  170. *
  171. * @param aFileName file name (without extension)
  172. */
  173. void SaveAsPNG( const wxString& aFileName ) const;
  174. /**
  175. * Set the current channel from a float normalized (0.0 - 1.0) buffer.
  176. *
  177. * this <- CLAMP(NormalizedFloat * 255)
  178. *
  179. * @param aNormalizedFloatArray a float array with the same size of the image
  180. */
  181. void SetPixelsFromNormalizedFloat( const float* aNormalizedFloatArray );
  182. /**
  183. * Get the image buffer pointer.
  184. *
  185. * @return unsigned char* the pointer of the buffer 8bit channel.
  186. */
  187. unsigned char* GetBuffer() const;
  188. unsigned int GetWidth() const { return m_width; }
  189. unsigned int GetHeight() const { return m_height; }
  190. private:
  191. /**
  192. * Calculate the coordinates points in accord with the current clamping settings.
  193. *
  194. * @param aXo X coordinate to be converted (output).
  195. * @param aXo Y coordinate to be converted (output).
  196. * @return bool - true if the coordinates are inside the image, false otherwise.
  197. */
  198. bool wrapCoords( int* aXo, int* aYo ) const;
  199. void plot8CircleLines( int aCx, int aCy, int aX, int aY, unsigned char aValue );
  200. unsigned char* m_pixels; ///< buffer to store the image 8bit-channel
  201. unsigned int m_width; ///< width of the image
  202. unsigned int m_height; ///< height of the image
  203. unsigned int m_wxh; ///< width * height precalc value
  204. IMAGE_WRAP m_wraping; ///< current wrapping type
  205. };
  206. #endif // IMAGE_H