KiCad PCB EDA Suite
IMAGE Class Reference

Manage an 8-bit channel image. More...

#include <image.h>

Public Member Functions

 IMAGE (unsigned int aXsize, unsigned int aYsize)
 Construct a IMAGE based on image size. More...
 
 IMAGE (const IMAGE &aSrcImage)
 Construct a IMAGE based from an existing image. More...
 
 ~IMAGE ()
 
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. More...
 
unsigned char Getpixel (int aX, int aY) const
 Get the pixel value from pixel position, position is clamped in accord with the current clamp settings. More...
 
void Hline (int aXStart, int aXEnd, int aY, unsigned char aValue)
 Draw a horizontal line. More...
 
void CircleFilled (int aCx, int aCy, int aRadius, unsigned char aValue)
 
void CopyFull (const IMAGE *aImgA, const IMAGE *aImgB, IMAGE_OP aOperation)
 Perform a copy operation based on aOperation type. More...
 
void Invert ()
 Invert the values of this image <- (255 - this) More...
 
void EfxFilter (IMAGE *aInImg, IMAGE_FILTER aFilterType)
 Apply a filter to the input image and store it in the image class. More...
 
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. More...
 
void SaveAsPNG (const wxString &aFileName) const
 Save image buffer to a PNG file into the working folder. More...
 
void SetPixelsFromNormalizedFloat (const float *aNormalizedFloatArray)
 Set the current channel from a float normalized (0.0 - 1.0) buffer. More...
 
unsigned char * GetBuffer () const
 Get the image buffer pointer. More...
 
unsigned int GetWidth () const
 
unsigned int GetHeight () const
 

Private Member Functions

bool wrapCoords (int *aXo, int *aYo) const
 Calculate the coordinates points in accord with the current clamping settings. More...
 
void plot8CircleLines (int aCx, int aCy, int aX, int aY, unsigned char aValue)
 

Private Attributes

unsigned char * m_pixels
 buffer to store the image 8bit-channel More...
 
unsigned int m_width
 width of the image More...
 
unsigned int m_height
 height of the image More...
 
unsigned int m_wxh
 width * height precalc value More...
 
IMAGE_WRAP m_wraping
 current wrapping type More...
 

Detailed Description

Manage an 8-bit channel image.

Definition at line 89 of file image.h.

Constructor & Destructor Documentation

◆ IMAGE() [1/2]

IMAGE::IMAGE ( unsigned int  aXsize,
unsigned int  aYsize 
)

Construct a IMAGE based on image size.

Parameters
aXsizex size
aYsizey size

Definition at line 45 of file image.cpp.

46{
47 m_wxh = aXsize * aYsize;
48 m_pixels = new unsigned char[m_wxh];
49 memset( m_pixels, 0, m_wxh );
50 m_width = aXsize;
51 m_height = aYsize;
53}
IMAGE_WRAP m_wraping
current wrapping type
Definition: image.h:232
unsigned int m_width
width of the image
Definition: image.h:229
unsigned int m_height
height of the image
Definition: image.h:230
unsigned char * m_pixels
buffer to store the image 8bit-channel
Definition: image.h:228
unsigned int m_wxh
width * height precalc value
Definition: image.h:231
@ CLAMP
Coords are clamped to image size.

References CLAMP, m_height, m_pixels, m_width, m_wraping, and m_wxh.

◆ IMAGE() [2/2]

IMAGE::IMAGE ( const IMAGE aSrcImage)

Construct a IMAGE based from an existing image.

It will make a copy the aSrcImage.

Parameters
aSrcImage

Definition at line 56 of file image.cpp.

57{
58 m_wxh = aSrcImage.GetWidth() * aSrcImage.GetHeight();
59 m_pixels = new unsigned char[m_wxh];
60 memcpy( m_pixels, aSrcImage.GetBuffer(), m_wxh );
61 m_width = aSrcImage.GetWidth();
62 m_height = aSrcImage.GetHeight();
64}
unsigned char * GetBuffer() const
Get the image buffer pointer.
Definition: image.cpp:73
unsigned int GetHeight() const
Definition: image.h:214
unsigned int GetWidth() const
Definition: image.h:213

References CLAMP, GetBuffer(), GetHeight(), GetWidth(), m_height, m_pixels, m_width, m_wraping, and m_wxh.

◆ ~IMAGE()

IMAGE::~IMAGE ( )

Definition at line 67 of file image.cpp.

68{
69 delete[] m_pixels;
70}

References m_pixels.

Member Function Documentation

◆ CircleFilled()

void IMAGE::CircleFilled ( int  aCx,
int  aCy,
int  aRadius,
unsigned char  aValue 
)

Definition at line 173 of file image.cpp.

174{
175 int x = aRadius;
176 int y = 0;
177 int xChange = 1 - 2 * aRadius;
178 int yChange = 0;
179 int radiusError = 0;
180
181 while( x >= y )
182 {
183 plot8CircleLines( aCx, aCy, x, y, aValue );
184 y++;
185 radiusError += yChange;
186 yChange += 2;
187
188 if( ( 2 * radiusError + xChange ) > 0 )
189 {
190 x--;
191 radiusError += xChange;
192 xChange += 2;
193 }
194 }
195}
void plot8CircleLines(int aCx, int aCy, int aX, int aY, unsigned char aValue)
Definition: image.cpp:114

References plot8CircleLines().

Referenced by RENDER_3D_OPENGL::initializeOpenGL().

◆ CopyFull()

void IMAGE::CopyFull ( const IMAGE aImgA,
const IMAGE aImgB,
IMAGE_OP  aOperation 
)

Perform a copy operation based on aOperation type.

The available image operations.

Parameters
aImgAan image input.
aImgBan image input.
aOperationoperation to perform

Definition at line 205 of file image.cpp.

206{
207 int aV, bV;
208
209 if( aOperation == IMAGE_OP::RAW )
210 {
211 if( aImgA == nullptr )
212 return;
213 }
214 else
215 {
216 if( ( aImgA == nullptr ) || ( aImgB == nullptr ) )
217 return;
218 }
219
220 switch( aOperation )
221 {
222 case IMAGE_OP::RAW:
223 memcpy( m_pixels, aImgA->m_pixels, m_wxh );
224 break;
225
226 case IMAGE_OP::ADD:
227 for( unsigned int it = 0;it < m_wxh; it++ )
228 {
229 aV = aImgA->m_pixels[it];
230 bV = aImgB->m_pixels[it];
231
232 aV = (aV + bV);
233 aV = (aV > 255)?255:aV;
234
235 m_pixels[it] = aV;
236 }
237 break;
238
239 case IMAGE_OP::SUB:
240 for( unsigned int it = 0;it < m_wxh; it++ )
241 {
242 aV = aImgA->m_pixels[it];
243 bV = aImgB->m_pixels[it];
244
245 aV = (aV - bV);
246 aV = (aV < 0)?0:aV;
247
248 m_pixels[it] = aV;
249 }
250 break;
251
252 case IMAGE_OP::DIF:
253 for( unsigned int it = 0;it < m_wxh; it++ )
254 {
255 aV = aImgA->m_pixels[it];
256 bV = aImgB->m_pixels[it];
257
258 m_pixels[it] = abs( aV - bV );
259 }
260 break;
261
262 case IMAGE_OP::MUL:
263 for( unsigned int it = 0;it < m_wxh; it++ )
264 {
265 aV = aImgA->m_pixels[it];
266 bV = aImgB->m_pixels[it];
267
268 m_pixels[it] =
269 (unsigned char) ( ( ( (float) aV / 255.0f ) * ( (float) bV / 255.0f ) ) * 255 );
270 }
271 break;
272
273 case IMAGE_OP::AND:
274 for( unsigned int it = 0;it < m_wxh; it++ )
275 {
276 m_pixels[it] = aImgA->m_pixels[it] & aImgB->m_pixels[it];
277 }
278 break;
279
280 case IMAGE_OP::OR:
281 for( unsigned int it = 0;it < m_wxh; it++ )
282 {
283 m_pixels[it] = aImgA->m_pixels[it] | aImgB->m_pixels[it];
284 }
285 break;
286
287 case IMAGE_OP::XOR:
288 for( unsigned int it = 0;it < m_wxh; it++ )
289 {
290 m_pixels[it] = aImgA->m_pixels[it] ^ aImgB->m_pixels[it];
291 }
292 break;
293
295 for( unsigned int it = 0;it < m_wxh; it++ )
296 {
297 aV = aImgA->m_pixels[it];
298 bV = aImgB->m_pixels[it];
299
300 m_pixels[it] = (aV + bV) / 2;
301 }
302 break;
303
304 case IMAGE_OP::MIN:
305 for( unsigned int it = 0;it < m_wxh; it++ )
306 {
307 aV = aImgA->m_pixels[it];
308 bV = aImgB->m_pixels[it];
309
310 m_pixels[it] = (aV < bV)?aV:bV;
311 }
312 break;
313
314 case IMAGE_OP::MAX:
315 for( unsigned int it = 0;it < m_wxh; it++ )
316 {
317 aV = aImgA->m_pixels[it];
318 bV = aImgB->m_pixels[it];
319
320 m_pixels[it] = (aV > bV)?aV:bV;
321 }
322 break;
323
324 default:
325 break;
326 }
327}
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition: eda_angle.h:418

References std::abs(), ADD, AND, BLEND50, DIF, m_pixels, m_wxh, MAX, MIN, MUL, OR, RAW, SUB, and XOR.

◆ EfxFilter()

void IMAGE::EfxFilter ( IMAGE aInImg,
IMAGE_FILTER  aFilterType 
)

Apply a filter to the input image and store it in the image class.

Parameters
aInImginput image
aFilterTypefilter type to apply
Todo:
: This function can be optimized slipping it between the edges and do it without use the getpixel function. Optimization can be done to m_pixels[ix + iy * m_width] but keep in mind the parallel process of the algorithm
Todo:
This needs to write to a separate buffer.

Definition at line 474 of file image.cpp.

475{
476 S_FILTER filter = FILTERS[static_cast<int>( aFilterType )];
477
480
481 std::atomic<size_t> nextRow( 0 );
482 std::atomic<size_t> threadsFinished( 0 );
483
484 size_t parallelThreadCount = std::max<size_t>( std::thread::hardware_concurrency(), 2 );
485
486 for( size_t ii = 0; ii < parallelThreadCount; ++ii )
487 {
488 std::thread t = std::thread( [&]()
489 {
490 for( size_t iy = nextRow.fetch_add( 1 ); iy < m_height; iy = nextRow.fetch_add( 1 ) )
491 {
492 for( size_t ix = 0; ix < m_width; ix++ )
493 {
494 int v = 0;
495
496 for( size_t sy = 0; sy < 5; sy++ )
497 {
498 for( size_t sx = 0; sx < 5; sx++ )
499 {
500 int factor = filter.kernel[sx][sy];
501 unsigned char pixelv = aInImg->Getpixel( ix + sx - 2, iy + sy - 2 );
502
503 v += pixelv * factor;
504 }
505 }
506
507 v /= filter.div;
508 v += filter.offset;
509 CLAMP(v, 0, 255);
510
512 m_pixels[ix + iy * m_width] = v;
513 }
514 }
515
516 threadsFinished++;
517 } );
518
519 t.detach();
520 }
521
522 while( threadsFinished < parallelThreadCount )
523 std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) );
524}
static const S_FILTER FILTERS[]
Definition: image.cpp:334
5x5 Filter struct parameters
Definition: image.h:79

References CLAMP, filter, FILTERS, m_height, and m_wraping.

◆ EfxFilter_SkipCenter()

void IMAGE::EfxFilter_SkipCenter ( IMAGE aInImg,
IMAGE_FILTER  aFilterType,
unsigned int  aRadius 
)

Apply a filter to the input image and store it in the image class.

skip the circle center defined by radius

Parameters
aInImginput image
aFilterTypefilter type to apply
aRadiuscenter circle that the effect will not be applied

Definition at line 527 of file image.cpp.

528{
529 if( ( !aInImg ) || ( m_width != aInImg->m_width ) || ( m_height != aInImg->m_height ) )
530 return;
531
532 S_FILTER filter = FILTERS[static_cast<int>( aFilterType )];
533
534 aInImg->m_wraping = IMAGE_WRAP::ZERO;
535
536 const unsigned int radiusSquared = aRadius * aRadius;
537
538 const unsigned int xCenter = m_width / 2;
539 const unsigned int yCenter = m_height / 2;
540
541 for( size_t iy = 0; iy < m_height; iy++ )
542 {
543 int yc = iy - yCenter;
544
545 unsigned int ycsq = yc * yc;
546
547 for( size_t ix = 0; ix < m_width; ix++ )
548 {
549 int xc = ix - xCenter;
550
551 unsigned int xcsq = xc * xc;
552
553 if( ( xcsq + ycsq ) < radiusSquared )
554 {
555 const unsigned int offset = ix + iy * m_width;
556
557 m_pixels[offset] = aInImg->m_pixels[offset];
558
559 continue;
560 }
561
562 int v = 0;
563
564 for( size_t sy = 0; sy < 5; sy++ )
565 {
566 for( size_t sx = 0; sx < 5; sx++ )
567 {
568 int factor = filter.kernel[sx][sy];
569 unsigned char pixelv = aInImg->Getpixel( ix + sx - 2, iy + sy - 2 );
570
571 v += pixelv * factor;
572 }
573 }
574
575 v /= filter.div;
576 v += filter.offset;
577 CLAMP(v, 0, 255);
578
579 m_pixels[ix + iy * m_width] = v;
580 }
581 }
582}
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...
Definition: image.cpp:130
@ ZERO
Coords that wraps are not evaluated.

References CLAMP, filter, FILTERS, Getpixel(), m_height, m_pixels, m_width, m_wraping, and ZERO.

Referenced by RENDER_3D_OPENGL::initializeOpenGL().

◆ GetBuffer()

unsigned char * IMAGE::GetBuffer ( ) const

Get the image buffer pointer.

Returns
unsigned char* the pointer of the buffer 8bit channel.

Definition at line 73 of file image.cpp.

74{
75 return m_pixels;
76}

References m_pixels.

Referenced by IMAGE(), and OglLoadTexture().

◆ GetHeight()

unsigned int IMAGE::GetHeight ( ) const
inline

Definition at line 214 of file image.h.

214{ return m_height; }

References m_height.

Referenced by IMAGE(), RENDER_3D_OPENGL::initializeOpenGL(), and OglLoadTexture().

◆ Getpixel()

unsigned char IMAGE::Getpixel ( int  aX,
int  aY 
) const

Get the pixel value from pixel position, position is clamped in accord with the current clamp settings.

Parameters
aXx position
aYy position
Returns
unsigned char - pixel value

Definition at line 130 of file image.cpp.

131{
132 if( wrapCoords( &aX, &aY ) )
133 return m_pixels[aX + aY * m_width];
134 else
135 return 0;
136}
bool wrapCoords(int *aXo, int *aYo) const
Calculate the coordinates points in accord with the current clamping settings.
Definition: image.cpp:79

References m_pixels, m_width, and wrapCoords().

Referenced by EfxFilter_SkipCenter().

◆ GetWidth()

unsigned int IMAGE::GetWidth ( ) const
inline

Definition at line 213 of file image.h.

213{ return m_width; }

References m_width.

Referenced by IMAGE(), RENDER_3D_OPENGL::initializeOpenGL(), and OglLoadTexture().

◆ Hline()

void IMAGE::Hline ( int  aXStart,
int  aXEnd,
int  aY,
unsigned char  aValue 
)

Draw a horizontal line.

Parameters
aXStartx start position
aXEndx end position
aYy position
aValuevalue to add

Definition at line 139 of file image.cpp.

140{
141 if( ( aY < 0 ) || ( aY >= (int) m_height ) || ( ( aXStart < 0 ) && ( aXEnd < 0 ) )
142 || ( ( aXStart >= (int) m_width ) && ( aXEnd >= (int) m_width ) ) )
143 return;
144
145 if( aXStart > aXEnd )
146 {
147 int swap = aXStart;
148
149 aXStart = aXEnd;
150 aXEnd = swap;
151 }
152
153 // Clamp line
154 if( aXStart < 0 )
155 aXStart = 0;
156
157 if( aXEnd >= (int)m_width )
158 aXEnd = m_width - 1;
159
160 unsigned char* pixelPtr = &m_pixels[aXStart + aY * m_width];
161 unsigned char* pixelPtrEnd = pixelPtr + (unsigned int) ( ( aXEnd - aXStart ) + 1 );
162
163 while( pixelPtr < pixelPtrEnd )
164 {
165 *pixelPtr = aValue;
166 pixelPtr++;
167 }
168}

References m_height, m_pixels, m_width, and swap.

Referenced by plot8CircleLines().

◆ Invert()

void IMAGE::Invert ( )

Invert the values of this image <- (255 - this)

Definition at line 198 of file image.cpp.

199{
200 for( unsigned int it = 0; it < m_wxh; it++ )
201 m_pixels[it] = 255 - m_pixels[it];
202}

References m_pixels, and m_wxh.

◆ plot8CircleLines()

void IMAGE::plot8CircleLines ( int  aCx,
int  aCy,
int  aX,
int  aY,
unsigned char  aValue 
)
private

Definition at line 114 of file image.cpp.

115{
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 );
120}
void Hline(int aXStart, int aXEnd, int aY, unsigned char aValue)
Draw a horizontal line.
Definition: image.cpp:139

References Hline().

Referenced by CircleFilled().

◆ SaveAsPNG()

void IMAGE::SaveAsPNG ( const wxString &  aFileName) const

Save image buffer to a PNG file into the working folder.

Each RGB channel will have the 8bit-channel from the image.

Parameters
aFileNamefile name (without extension)

Definition at line 597 of file image.cpp.

598{
599 DBG_SaveBuffer( aFileName, m_pixels, m_width, m_height );
600}
void DBG_SaveBuffer(const wxString &aFileName, const unsigned char *aInBuffer, unsigned int aXSize, unsigned int aYSize)

References DBG_SaveBuffer(), m_height, m_pixels, and m_width.

◆ Setpixel()

void IMAGE::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.

Parameters
aXx position
aYy position
aValuevalue to set the pixel

Definition at line 123 of file image.cpp.

124{
125 if( wrapCoords( &aX, &aY ) )
126 m_pixels[aX + aY * m_width] = aValue;
127}

References m_pixels, m_width, and wrapCoords().

◆ SetPixelsFromNormalizedFloat()

void IMAGE::SetPixelsFromNormalizedFloat ( const float *  aNormalizedFloatArray)

Set the current channel from a float normalized (0.0 - 1.0) buffer.

this <- CLAMP(NormalizedFloat * 255)

Parameters
aNormalizedFloatArraya float array with the same size of the image

Definition at line 585 of file image.cpp.

586{
587 for( unsigned int i = 0; i < m_wxh; i++ )
588 {
589 int v = aNormalizedFloatArray[i] * 255;
590
591 CLAMP( v, 0, 255 );
592 m_pixels[i] = v;
593 }
594}

References CLAMP, m_pixels, and m_wxh.

◆ wrapCoords()

bool IMAGE::wrapCoords ( int *  aXo,
int *  aYo 
) const
private

Calculate the coordinates points in accord with the current clamping settings.

Parameters
aXoX coordinate to be converted (output).
aXoY coordinate to be converted (output).
Returns
bool - true if the coordinates are inside the image, false otherwise.

Definition at line 79 of file image.cpp.

80{
81 int x = *aXo;
82 int y = *aYo;
83
84 switch( m_wraping )
85 {
87 x = ( x < 0 ) ? 0 : x;
88 x = ( x >= (int) ( m_width - 1 ) ) ? ( m_width - 1 ) : x;
89 y = ( y < 0 ) ? 0 : y;
90 y = ( y >= (int) ( m_height - 1 ) ) ? ( m_height - 1 ) : y;
91 break;
92
94 x = ( x < 0 ) ? ( ( m_width - 1 ) + x ) : x;
95 x = ( x >= (int) ( m_width - 1 ) ) ? ( x - m_width ) : x;
96 y = ( y < 0 ) ? ( ( m_height - 1 ) + y ) : y;
97 y = ( y >= (int) ( m_height - 1 ) ) ? ( y - m_height ) : y;
98 break;
99
100 default:
101 break;
102 }
103
104 if( ( x < 0 ) || ( x >= (int) m_width ) || ( y < 0 ) || ( y >= (int) m_height ) )
105 return false;
106
107 *aXo = x;
108 *aYo = y;
109
110 return true;
111}
@ WRAP
Coords are wrapped around.

References CLAMP, m_height, m_width, m_wraping, and WRAP.

Referenced by Getpixel(), and Setpixel().

Member Data Documentation

◆ m_height

unsigned int IMAGE::m_height
private

height of the image

Definition at line 230 of file image.h.

Referenced by EfxFilter(), EfxFilter_SkipCenter(), GetHeight(), Hline(), IMAGE(), SaveAsPNG(), and wrapCoords().

◆ m_pixels

unsigned char* IMAGE::m_pixels
private

buffer to store the image 8bit-channel

Definition at line 228 of file image.h.

Referenced by CopyFull(), EfxFilter_SkipCenter(), GetBuffer(), Getpixel(), Hline(), IMAGE(), Invert(), SaveAsPNG(), Setpixel(), SetPixelsFromNormalizedFloat(), and ~IMAGE().

◆ m_width

unsigned int IMAGE::m_width
private

width of the image

Definition at line 229 of file image.h.

Referenced by EfxFilter_SkipCenter(), Getpixel(), GetWidth(), Hline(), IMAGE(), SaveAsPNG(), Setpixel(), and wrapCoords().

◆ m_wraping

IMAGE_WRAP IMAGE::m_wraping
private

current wrapping type

Definition at line 232 of file image.h.

Referenced by EfxFilter(), EfxFilter_SkipCenter(), IMAGE(), and wrapCoords().

◆ m_wxh

unsigned int IMAGE::m_wxh
private

width * height precalc value

Definition at line 231 of file image.h.

Referenced by CopyFull(), IMAGE(), Invert(), and SetPixelsFromNormalizedFloat().


The documentation for this class was generated from the following files: