STE-Industries: utilities testing
Bitmap.cpp
Go to the documentation of this file.
1 
14 # include "Graphic.h"
15 # include "Bitmap.h"
16 # include "FileException.h"
17 # include "IntegerException.h"
18 # include "FloatException.h"
19 # include "NameException.h"
20 # include "Interpolator.h"
21 # include "Thread.h"
22 
23 # include <stdio.h>
24 # include <string.h>
25 # include <math.h>
26 
27 constexpr unsigned int Step = 5;
28 
29 namespace GraphicSpace
30 {
31 
33 
34 const char Bitmap::HeaderName [HEADER_NAME_LENGTH] = { 'B', 'M' };
35 
36 const char* const Bitmap::OpenReadBinary = "rb";
37 
38 const char* const Bitmap::OpenWriteBinary = "wb";
39 
72 
75  CurrentGenerator,
76  register const RepulsionType* RepulsionPointer)
77  const noexcept
78  {
79  register unsigned int Best;
80  register uint_fast32_t Value;
81  register uint_fast32_t Maximum;
82  IndexType BestIndex [NUMBER_OF_NEIGHBOURS];
83 
84  assert(NumberOfNeighbours == 3 or NumberOfNeighbours == 5 or
85  NumberOfNeighbours == 8);
86  Best = 1;
87  Maximum = Neighbour [0].Attraction *
88  RepulsionPointer [Neighbour [0].Index].Repulsion;
89  BestIndex [0] = Neighbour [0].Index;
90  if ((Value = Neighbour [1].Attraction *
91  RepulsionPointer [Neighbour [1].Index].Repulsion) >= Maximum)
92  if (Value > Maximum)
93  {
94  Maximum = Value;
95  BestIndex [0] = Neighbour [1].Index;
96  }
97  else
98  {
99  BestIndex [1] = Neighbour [1].Index;
100  Best = 2;
101  }
102  if ((Value = Neighbour [2].Attraction *
103  RepulsionPointer [Neighbour [2].Index].Repulsion) >= Maximum)
104  if (Value > Maximum)
105  {
106  Maximum = Value;
107  BestIndex [0] = Neighbour [2].Index;
108  Best = 1;
109  }
110  else
111  BestIndex [Best++] = Neighbour [2].Index;
112  if (NumberOfNeighbours > 3)
113  {
114  if ((Value = Neighbour [3].Attraction *
115  RepulsionPointer [Neighbour [3].Index].Repulsion) >=
116  Maximum)
117  if (Value > Maximum)
118  {
119  Maximum = Value;
120  BestIndex [0] = Neighbour [3].Index;
121  Best = 1;
122  }
123  else
124  BestIndex [Best++] = Neighbour [3].Index;
125  if ((Value = Neighbour [4].Attraction *
126  RepulsionPointer [Neighbour [4].Index].Repulsion) >=
127  Maximum)
128  if (Value > Maximum)
129  {
130  Maximum = Value;
131  BestIndex [0] = Neighbour [4].Index;
132  Best = 1;
133  }
134  else
135  BestIndex [Best++] = Neighbour [4].Index;
136  if (NumberOfNeighbours > 5)
137  {
138  if ((Value = Neighbour [5].Attraction *
139  RepulsionPointer [Neighbour [5].Index].
140  Repulsion) >= Maximum)
141  if (Value > Maximum)
142  {
143  Maximum = Value;
144  BestIndex [0] = Neighbour [5].Index;
145  Best = 1;
146  }
147  else
148  BestIndex [Best++] =
149  Neighbour [5].Index;
150  if ((Value = Neighbour [6].Attraction *
151  RepulsionPointer [Neighbour [6].Index].
152  Repulsion) >= Maximum)
153  if (Value > Maximum)
154  {
155  Maximum = Value;
156  BestIndex [0] = Neighbour [6].Index;
157  Best = 1;
158  }
159  else
160  BestIndex [Best++] =
161  Neighbour [6].Index;
162  if ((Value = Neighbour [7].Attraction *
163  RepulsionPointer [Neighbour [7].Index].
164  Repulsion) >= Maximum)
165  if (Value > Maximum)
166  {
167  Maximum = Value;
168  BestIndex [0] = Neighbour [7].Index;
169  Best = 1;
170  }
171  else
172  BestIndex [Best++] =
173  Neighbour [7].Index;
174  }
175  }
176  if (Best == 1)
177  return BestIndex [0];
178  if (Maximum == 0)
179  return UINT_FAST32_MAX;
180  return BestIndex [CurrentGenerator.Generate(Best - 1)];
181  }
182 
215 
218  CurrentGenerator,
219  register const RepulsionType* RepulsionPointer)
220  const noexcept
221  {
222  unsigned int Index;
223  uint_fast32_t Probability [NUMBER_OF_NEIGHBOURS];
224 
225  assert(NumberOfNeighbours == 3 or NumberOfNeighbours == 5 or
226  NumberOfNeighbours == 8);
227  Probability [0] = Neighbour [0].Attraction *
228  RepulsionPointer [Neighbour [0].Index].Repulsion;
229  Probability [1] = Neighbour [1].Attraction *
230  RepulsionPointer [Neighbour [1].Index].Repulsion;
231  Probability [2] = Neighbour [2].Attraction *
232  RepulsionPointer [Neighbour [2].Index].Repulsion;
233  if (NumberOfNeighbours > 3)
234  {
235  Probability [3] = Neighbour [3].Attraction *
236  RepulsionPointer [Neighbour [3].Index].Repulsion;
237  Probability [4] = Neighbour [4].Attraction *
238  RepulsionPointer [Neighbour [4].Index].Repulsion;
239  if (NumberOfNeighbours > 5)
240  {
241  Probability [5] = Neighbour [5].Attraction *
242  RepulsionPointer [Neighbour [5].Index].
243  Repulsion;
244  Probability [6] = Neighbour [6].Attraction *
245  RepulsionPointer [Neighbour [6].Index].
246  Repulsion;
247  Probability [7] = Neighbour [7].Attraction *
248  RepulsionPointer [Neighbour [7].Index].
249  Repulsion;
250  }
251  }
252  if ((Index = CurrentGenerator.Select(Probability,
253  NumberOfNeighbours)) == UINT_MAX)
254  return UINT_LEAST32_MAX;
255  return Neighbour [Index].Index;
256  }
257 
297 
298 unsigned int Bitmap::ComputeTermite(register unsigned int MaximumValue,
299  register IndexType PixelIndex,
300  register const uint8_t* ColorPointer,
301  register unsigned int Steps,
302  register const PixelInformationType*
303  PixelInformationPointer,
304  register RepulsionType* RepulsionPointer,
305  register RandomGenerator& CurrentGenerator,
306  register PathFunction PathFinder) const noexcept
307  {
308  register unsigned int PathMaximum;
309 
310  PathMaximum = ColorPointer [PixelIndex];
311  assert(PathMaximum < MaximumValue);
312  RepulsionPointer [PixelIndex].Repulsion =
313  RepulsionTable [++RepulsionPointer [PixelIndex].Visitors];
314  for (; Steps > 0; --Steps)
315  {
316  if ((PixelIndex = (PixelInformationPointer [PixelIndex].*
317  PathFinder)(CurrentGenerator, RepulsionPointer)) >
318  BitmapSize)
319  break;
320  RepulsionPointer [PixelIndex].Repulsion =
321  RepulsionTable [++RepulsionPointer [PixelIndex].
322  Visitors];
323  if (ColorPointer [PixelIndex] > PathMaximum)
324  if ((PathMaximum = ColorPointer [PixelIndex]) ==
325  MaximumValue)
326  break;
327  }
328  return PathMaximum;
329  }
330 
376 
377 void Bitmap::CorrectStrip(register uint8_t* CorrectedColorPointer,
378  register const uint8_t* OriginalColorPointer,
379  register unsigned int StartRow, register unsigned int EndRow,
380  register unsigned int MaximumValue,
381  register const CorrectionParameters& Parameters,
382  register const PixelInformationType* PixelInformationPointer,
383  register PathFunction PathFinder,
384  register const uint_least32_t DivisionTable [UINT8_MAX + 1])
385  const noexcept
386  {
387  register unsigned int Index;
388  register IndexType PixelIndex;
389  register IndexType LastIndex;
390  register uint_fast32_t Sum;
391  register RepulsionType* RepulsionPointer;
392  RandomGenerator LocalGenerator(Generator);
393 
394  RepulsionPointer = new RepulsionType [BitmapSize];
395  LocalGenerator.ModifySeed(StartRow ^ EndRow);
396  for (; StartRow < EndRow; ++StartRow)
397  {
398  LastIndex = MakeIndex(StartRow, Width);
399  for (PixelIndex = MakeIndex(StartRow, 0);
400  PixelIndex < LastIndex; ++PixelIndex)
401  {
402  if (OriginalColorPointer [PixelIndex] == MaximumValue)
403  continue;
404  IgnoreValue(memcpy(RepulsionPointer,
406  BitmapSize * sizeof(RepulsionType)));
407  Sum = 0;
408  for (Index = 0; Index < Parameters.Termites; ++Index)
409  Sum += DivisionTable
410  [ComputeTermite(MaximumValue,
411  PixelIndex, OriginalColorPointer,
412  Parameters.Steps,
413  PixelInformationPointer,
414  RepulsionPointer, LocalGenerator,
415  PathFinder)];
416  CorrectedColorPointer [PixelIndex] =
417  static_cast<uint8_t>(RoundedDivide(Sum *
418  OriginalColorPointer [PixelIndex],
419  TERMITES_SUM_SCALE * Parameters.Termites));
420  }
421  }
422  delete [] RepulsionPointer;
423  }
424 
473 
474 void Bitmap::CorrectColor(register uint8_t* CorrectedColorPointer,
475  register const uint8_t* OriginalColorPointer,
476  register unsigned int MaximumValue,
477  register const CorrectionParameters& Parameters,
478  register const PixelInformationType* PixelInformationPointer,
479  register PathFunction PathFinder,
480  register const uint_least32_t DivisionTable [UINT8_MAX + 1])
481  noexcept
482  {
483  register unsigned int Index;
484  register unsigned int StartRow;
485  Thread CorrectorThread
487 
488  if (Parameters.Threads == 1)
489  CorrectStrip(CorrectedColorPointer, OriginalColorPointer,
490  0, Height, MaximumValue, Parameters,
491  PixelInformationPointer, PathFinder, DivisionTable);
492  else
493  {
496  if (DescriptorPointer == nullptr)
498  new CorrectionDescriptorType [Strips];
499  StartRow = 0;
501  CorrectedColorPointer;
503  OriginalColorPointer;
504  DescriptorPointer [0].MaximumValue = MaximumValue;
505  DescriptorPointer [0].ParametersPointer = &Parameters;
507  PixelInformationPointer;
508  DescriptorPointer [0].PathFinder = PathFinder;
509  DescriptorPointer [0].DivisionTablePointer = DivisionTable;
510  for (Index = 0; Index < Strips; ++Index)
511  {
512  DescriptorPointer [Index] = DescriptorPointer [0];
513  DescriptorPointer [Index].StartRow = StartRow;
514  if ((StartRow += STRIP_HEIGHT) > Height)
515  StartRow = Height;
516  DescriptorPointer [Index].EndRow = StartRow;
517  }
518 
519  // Divide the rows as equally as possible among the
520  // threads.
521  for (Index = 0; Index < Parameters.Threads; ++Index)
522  CorrectorThread [Index].Start(CorrectFunction, this);
523  for (Index = 0; Index < Parameters.Threads; ++Index)
524  CorrectorThread [Index].Join();
526  }
527  }
528 
540 //
542 
544  noexcept
545  {
547 
548  StripMutex.Lock();
549  if (Strips > 0)
550  {
551  Value = &DescriptorPointer [--Strips];
552  if (not Value->ParametersPointer->Quiet)
553  IgnoreValue(printf(STRIP_INDEX_FORMAT, Strips));
554  }
555  else
556  Value = nullptr;
557  StripMutex.Unlock();
558  return Value;
559  }
560 
572 
573 Bitmap::Bitmap(void) noexcept: Width(0), Height(0), BitmapSize(0),
574  BitsPerPixel(0), HorizontalResolution(0), VerticalResolution(0),
575  PixelPointer(), RepulsionTable(), InitialRepulsionPointer(),
576  Generator(), Strips(), StripMutex(), DescriptorPointer(nullptr)
577  {
578  register unsigned int Color;
579 
580  for (Color = 0; Color < NUMBER_OF_COLORS; ++Color)
581  PixelPointer [Color] = nullptr;
582  }
583 
597 
598 Bitmap::Bitmap(const Bitmap& thisBitmap) noexcept: Width(thisBitmap.Width),
599  Height(thisBitmap.Height), BitmapSize(thisBitmap.BitmapSize),
600  BitsPerPixel(thisBitmap.BitsPerPixel),
601  HorizontalResolution(thisBitmap.HorizontalResolution),
602  VerticalResolution(thisBitmap.VerticalResolution), PixelPointer(),
603  RepulsionTable(), InitialRepulsionPointer(),
604  Generator(thisBitmap.Generator), Strips(thisBitmap.Strips),
605  StripMutex(), DescriptorPointer(nullptr)
606  {
607  register unsigned int Color;
608 
609  AllocateImage();
610  if (BitmapSize != 0)
611  for (Color = 0; Color < NUMBER_OF_COLORS; ++Color)
612  memcpy(PixelPointer [Color],
613  thisBitmap.PixelPointer [Color], BitmapSize);
614  }
615 
629 
630 Bitmap::Bitmap(Bitmap&& thisBitmap) noexcept: Width(thisBitmap.Width),
631  Height(thisBitmap.Height), BitmapSize(thisBitmap.BitmapSize),
632  BitsPerPixel(thisBitmap.BitsPerPixel),
633  HorizontalResolution(thisBitmap.HorizontalResolution),
634  VerticalResolution(thisBitmap.VerticalResolution), PixelPointer(),
635  RepulsionTable(), InitialRepulsionPointer(),
636  Generator(thisBitmap.Generator), Strips(thisBitmap.Strips),
637  StripMutex(), DescriptorPointer(thisBitmap.DescriptorPointer)
638  {
639  register unsigned int Color;
640 
641  for (Color = 0; Color < NUMBER_OF_COLORS; ++Color)
642  {
643  PixelPointer [Color] = thisBitmap.PixelPointer [Color];
644  thisBitmap.PixelPointer [Color] = nullptr;
645  }
646  thisBitmap.DescriptorPointer = nullptr;
647  }
648 
660 
661 Bitmap::~Bitmap(void) noexcept
662  {
663  DestroyImage();
664  if (DescriptorPointer != nullptr)
665  delete [] DescriptorPointer;
666  }
667 
681 
682 Bitmap& Bitmap::operator = (const Bitmap& thisBitmap) noexcept
683  {
684  register unsigned int Color;
685 
686  Width = thisBitmap.Width;
687  Height = thisBitmap.Height;
688  BitmapSize = thisBitmap.BitmapSize;
689  BitsPerPixel = thisBitmap.BitsPerPixel;
690  HorizontalResolution = thisBitmap.HorizontalResolution;
691  VerticalResolution = thisBitmap.VerticalResolution;
692  Generator = thisBitmap.Generator;
693  DestroyImage();
694  AllocateImage();
695  if (BitmapSize != 0)
696  for (Color = 0; Color < NUMBER_OF_COLORS; ++Color)
697  memcpy(PixelPointer [Color],
698  thisBitmap.PixelPointer [Color], BitmapSize);
699  return *this;
700  }
701 
715 
716 Bitmap& Bitmap::operator = (Bitmap&& thisBitmap) noexcept
717  {
718  register unsigned int Color;
719 
720  Width = thisBitmap.Width;
721  Height = thisBitmap.Height;
722  BitmapSize = thisBitmap.BitmapSize;
723  BitsPerPixel = thisBitmap.BitsPerPixel;
724  HorizontalResolution = thisBitmap.HorizontalResolution;
725  VerticalResolution = thisBitmap.VerticalResolution;
726  Generator = thisBitmap.Generator;
727  DestroyImage();
728  for (Color = 0; Color < NUMBER_OF_COLORS; ++Color)
729  {
730  PixelPointer [Color] = thisBitmap.PixelPointer [Color];
731  thisBitmap.PixelPointer [Color] = nullptr;
732  }
733  return *this;
734  }
735 
823 
824 void Bitmap::ReadFile(const char* Path) noexcept(false)
825  {
826  register unsigned int Color;
827  register uint_fast32_t Value;
828  register uint_fast32_t Row;
829  register uint_fast32_t Column;
830  register IndexType Index;
831  register FILE* InputFile;
832  int_fast32_t FileSize;
833  uint8_t Buffer [DIB_HEADER_SIZE];
834 
835  if ((InputFile = fopen(Path, OpenReadBinary)) == nullptr)
837  if (fseek(InputFile, 0, SEEK_END) < 0)
839  if ((FileSize = ftell(InputFile)) < 0)
841  if (fseek(InputFile, 0, SEEK_SET) < 0)
843  if (fread(Buffer, 1, HEADER_SIZE, InputFile) != HEADER_SIZE)
845  if (static_cast<uint_fast32_t>(FileSize) !=
846  LoadInteger(Buffer + OFFSET_OF_FILE_SIZE, LONG_DATA_SIZE))
848  static_cast<uint_fast32_t>(FileSize));
849  if (memcmp(Buffer, HeaderName, HEADER_NAME_LENGTH) != 0)
850  throw NameException(Buffer);
851  if ((Value = LoadInteger(Buffer + OFFSET_OF_BITMAP_OFFSET,
852  LONG_DATA_SIZE)) != HEADER_SIZE + DIB_HEADER_SIZE)
854  INVALID_BITMAP_OFFSET, Value);
855  if (fread(Buffer, 1, DIB_HEADER_SIZE, InputFile) != DIB_HEADER_SIZE)
857  switch (Value = LoadInteger(Buffer, LONG_DATA_SIZE))
858  {
859  case DIB_HEADER_SIZE:
860  break;
861  default:
863  INVALID_DIB_HEADER_SIZE, Value);
864  }
865  Width = LoadInteger(Buffer + OFFSET_OF_WIDTH, LONG_DATA_SIZE);
866  if (Width == 0 or Width > MAXIMUM_WIDTH)
868  INVALID_IMAGE_WIDTH, Width);
869  Height = LoadInteger(Buffer + OFFSET_OF_HEIGHT, LONG_DATA_SIZE);
870  if (Height == 0 or Height > MAXIMUM_WIDTH)
872  INVALID_IMAGE_HEIGHT, Height);
873  BitmapSize = Width * Height;
874  if (BitmapSize > Bitmap::MAXIMUM_BITMAP_SIZE)
876  BitmapSize);
877  if ((Value = LoadInteger(Buffer + OFFSET_OF_COLOR_PLANES,
878  SHORT_DATA_SIZE)) != NUMBER_OF_COLOR_PLANES)
880  INVALID_COLOR_PLANES, Value);
881  if ((BitsPerPixel = static_cast<uint16_t>(LoadInteger(Buffer +
882  OFFSET_OF_BITS_PER_PIXEL, SHORT_DATA_SIZE))) !=
883  NUMBER_OF_COLORS * CHAR_BIT)
885  INVALID_BITS_PER_PIXEL, BitsPerPixel);
886  if ((Index = LoadInteger(Buffer + OFFSET_OF_COMPRESSION,
887  LONG_DATA_SIZE)) != VALID_COMPRESSION)
889  INVALID_COMPRESSION, Index);
890  if ((Value = LoadInteger(Buffer + OFFSET_OF_IMAGE_SIZE,
891  LONG_DATA_SIZE)) != ComputeLineSize() * Height)
892  if (Index != 0 or Value != 0)
894  INVALID_IMAGE_SIZE, Value);
895  HorizontalResolution = LoadInteger(Buffer +
896  OFFSET_OF_HORIZONTAL_RESOLUTION, LONG_DATA_SIZE);
897  VerticalResolution = LoadInteger(Buffer + OFFSET_OF_VERTICAL_RESOLUTION,
898  LONG_DATA_SIZE);
899  if ((Value = LoadInteger(Buffer + OFFSET_OF_NUMBER_OF_COLORS,
900  LONG_DATA_SIZE)) != 0)
902  INVALID_NUMBER_OF_COLORS, Value);
903  if ((Value = LoadInteger(Buffer + OFFSET_OF_NUMBER_OF_IMPORTANT_COLORS,
904  LONG_DATA_SIZE)) != 0)
907  DestroyImage();
908  AllocateImage();
909  Value = ComputeLineSize();
910  Index = 0;
911  for (Row = 0; Row < Height; ++Row)
912  {
913  for (Column = 0; Column < Width; ++Column)
914  {
915  if (fread(Buffer, 1, NUMBER_OF_COLORS, InputFile) !=
916  NUMBER_OF_COLORS)
918  FILE_READ_ERROR, Path);
919  for (Color = 0; Color < NUMBER_OF_COLORS; ++Color)
920  PixelPointer [Color] [Index] = Buffer [Color];
921  ++Index;
922  }
923  if (Column * NUMBER_OF_COLORS < Value)
924  if (fread(Buffer, 1, Value - Column * NUMBER_OF_COLORS,
925  InputFile) != Value - Column * NUMBER_OF_COLORS)
927  FILE_READ_ERROR, Path);
928  }
929  if (fclose(InputFile) != 0)
931  }
932 
972 
973 void Bitmap::WriteFile(const char* Path) noexcept(false)
974  {
975  register unsigned int Color;
976  register uint_fast32_t Length;
977  register uint_fast32_t Row;
978  register uint_fast32_t Column;
979  register IndexType Index;
980  register FILE* OutputFile;
981  uint8_t Buffer [DIB_HEADER_SIZE];
982 
983  if ((OutputFile = fopen(Path, OpenWriteBinary)) == nullptr)
985  IgnoreValue(memset(Buffer, 0, HEADER_SIZE));
986  IgnoreValue(memcpy(Buffer, HeaderName, HEADER_NAME_LENGTH));
987  Length = ComputeLineSize();
988  StoreInteger(Buffer + OFFSET_OF_FILE_SIZE, HEADER_SIZE +
989  DIB_HEADER_SIZE + Length * Height, LONG_DATA_SIZE);
990  StoreInteger(Buffer + OFFSET_OF_BITMAP_OFFSET,
991  HEADER_SIZE + DIB_HEADER_SIZE, LONG_DATA_SIZE);
992  if (fwrite(Buffer, 1, HEADER_SIZE, OutputFile) != HEADER_SIZE)
994  IgnoreValue(memset(Buffer, 0, DIB_HEADER_SIZE));
995  StoreInteger(Buffer, DIB_HEADER_SIZE, LONG_DATA_SIZE);
996  StoreInteger(Buffer + OFFSET_OF_WIDTH, Width, LONG_DATA_SIZE);
997  StoreInteger(Buffer + OFFSET_OF_HEIGHT, Height, LONG_DATA_SIZE);
998  StoreInteger(Buffer + OFFSET_OF_COLOR_PLANES, NUMBER_OF_COLOR_PLANES,
999  SHORT_DATA_SIZE);
1000  StoreInteger(Buffer + OFFSET_OF_BITS_PER_PIXEL, BitsPerPixel,
1001  SHORT_DATA_SIZE);
1002  StoreInteger(Buffer + OFFSET_OF_COMPRESSION, VALID_COMPRESSION,
1003  LONG_DATA_SIZE);
1004  StoreInteger(Buffer + OFFSET_OF_HORIZONTAL_RESOLUTION,
1005  HorizontalResolution, LONG_DATA_SIZE);
1006  StoreInteger(Buffer + OFFSET_OF_VERTICAL_RESOLUTION, VerticalResolution,
1007  LONG_DATA_SIZE);
1008  if (fwrite(Buffer, 1, DIB_HEADER_SIZE, OutputFile) != DIB_HEADER_SIZE)
1010  Index = 0;
1011  assert(Length >= Width * NUMBER_OF_COLORS);
1012  Length -= Width * NUMBER_OF_COLORS;
1013  for (Row = 0; Row < Height; ++Row)
1014  {
1015  for (Column = 0; Column < Width; ++Column)
1016  {
1017  for (Color = 0; Color < NUMBER_OF_COLORS; ++Color)
1018  Buffer [Color] = PixelPointer [Color] [Index];
1019  if (fwrite(Buffer, 1, NUMBER_OF_COLORS, OutputFile) !=
1020  NUMBER_OF_COLORS)
1022  FILE_WRITE_ERROR, Path);
1023  ++Index;
1024  }
1025  if (Length > 0)
1026  {
1027  IgnoreValue(memset(Buffer, 0, Length));
1028  if (fwrite(Buffer, 1, Length, OutputFile) != Length)
1030  FILE_WRITE_ERROR, Path);
1031  }
1032  }
1033  if (fclose(OutputFile) != 0)
1035  }
1036 
1075 
1076 Bitmap Bitmap::Correct(register const CorrectionParameters& Parameters)
1077  noexcept(false)
1078  {
1079  register unsigned int FirstValue;
1080  register unsigned int SecondValue;
1081  register IndexType Index;
1082  register float Sqrt2;
1083  register PixelInformationType* PixelInformationPointer;
1084  register PathFunction PathFinder;
1085  register RepulsionType InitialRepulsion;
1086  Bitmap LocalBitmap(*this);
1087  uint_least32_t OrthogonalAttraction
1088  [UINT8_MAX + 1];
1089  uint_least32_t DiagonalAttraction
1090  [UINT8_MAX + 1];
1091  uint_least32_t DivisionTable [UINT8_MAX + 1];
1092 
1093  if (Parameters.Termites == 0 or Parameters.Termites >
1094  MAXIMUM_NUMBER_OF_TERMITES)
1096  INVALID_NUMBER_OF_TERMITES, Parameters.Termites);
1097  if (Parameters.Steps == 0 or Parameters.Steps > MAXIMUM_NUMBER_OF_STEPS)
1099  INVALID_NUMBER_OF_STEPS, Parameters.Steps);
1100  if (Parameters.RepulsionStep < 0.0 or Parameters.RepulsionStep > 1.0)
1102  Parameters.RepulsionStep);
1103  if (Parameters.Alpha < 0.0 or Parameters.Alpha > 1.0)
1105  Parameters.Alpha);
1106  if (Parameters.Beta < 0.0 or Parameters.Beta > 1.0)
1108  Parameters.Beta);
1109  PathFinder = Parameters.ChoiceKind == ChoiceType::RANDOM?
1110  &PixelInformationType::NextPixelRandom:
1111  &PixelInformationType::NextPixelMaximum;
1112  for (Index = 0; Index < NumberOfElements(RepulsionTable); ++Index)
1113  RepulsionTable [Index] = static_cast<unsigned short>
1114  (lrintf(powf(static_cast<float>(1) / (1 +
1115  static_cast<float>(Index) * Parameters.RepulsionStep),
1116  Parameters.Alpha) * REPULSION_SCALE));
1117  Sqrt2 = sqrtf(2);
1118  for (Index = 0; Index < NumberOfElements(OrthogonalAttraction); ++Index)
1119  {
1120  OrthogonalAttraction [Index] = static_cast<uint_least32_t>
1121  (lrintf(powf(static_cast<float>(1 + Index) / Sqrt2,
1122  Parameters.Beta) * ATTRACTION_SCALE));
1123  DiagonalAttraction [Index] = static_cast<uint_least32_t>
1124  (lrintf(powf((Sqrt2 + static_cast<float>(Index)) /
1125  Sqrt2, Parameters.Beta) * ATTRACTION_SCALE));
1126  }
1127  for (Index = 1; Index < NumberOfElements(DivisionTable); ++Index)
1128  DivisionTable [Index] = static_cast<uint_least32_t>
1129  (RoundedDivide(static_cast<uint_least32_t>(UINT8_MAX) *
1130  TERMITES_SUM_SCALE, Index));
1131  DivisionTable [0] = DivisionTable [1];
1132  PixelInformationPointer = new PixelInformationType [BitmapSize];
1133  InitialRepulsionPointer = new RepulsionType [BitmapSize];
1134  InitialRepulsion.Visitors = 0;
1135  InitialRepulsion.Repulsion = RepulsionTable [0];
1136  for (Index = 0; Index < BitmapSize; ++Index)
1137  InitialRepulsionPointer [Index] = InitialRepulsion;
1138  for (FirstValue = 0; FirstValue < Height; ++FirstValue)
1139  for (SecondValue = 0; SecondValue < Width; ++SecondValue)
1140  PixelInformationPointer [MakeIndex(FirstValue,
1141  SecondValue)].
1142  SetLinks(*this, FirstValue, SecondValue);
1143  for (FirstValue = 0; FirstValue < NUMBER_OF_COLORS; ++FirstValue)
1144  {
1145  SecondValue = Parameters.TruncatePath? 0: UINT8_MAX + 1;
1146  for (Index = 0; Index < BitmapSize; ++Index)
1147  {
1148  PixelInformationPointer [Index].
1149  SetAttraction(*this, PixelPointer [FirstValue],
1150  Index, OrthogonalAttraction,
1151  DiagonalAttraction);
1152  if (PixelPointer [FirstValue] [Index] > SecondValue)
1153  SecondValue = PixelPointer [FirstValue] [Index];
1154  }
1155  CorrectColor(LocalBitmap.PixelPointer [FirstValue],
1156  PixelPointer [FirstValue], SecondValue, Parameters,
1157  PixelInformationPointer, PathFinder, DivisionTable);
1158  }
1159  delete [] PixelInformationPointer;
1160  delete [] InitialRepulsionPointer;
1161  return LocalBitmap;
1162  }
1163 
1189 
1190 void* Bitmap::CorrectFunction(void* Argument) noexcept(false)
1191  {
1192  const CorrectionDescriptorType* DescriptorPointer;
1193  Bitmap* BitmapPointer;
1194 
1195 // DescriptorPointer =
1196 // static_cast<const CorrectionDescriptorType*>(Argument);
1197  BitmapPointer = static_cast<Bitmap*>(Argument);
1198  while ((DescriptorPointer = BitmapPointer->GetStripDescriptor()) !=
1199  nullptr)
1200  BitmapPointer->
1201  CorrectStrip(DescriptorPointer->CorrectedColorPointer,
1202  DescriptorPointer->OriginalColorPointer,
1203  DescriptorPointer->StartRow, DescriptorPointer->EndRow,
1204  DescriptorPointer->MaximumValue,
1205  *(DescriptorPointer->ParametersPointer),
1206  DescriptorPointer->PixelInformationPointer,
1207  DescriptorPointer->PathFinder,
1208  DescriptorPointer->DivisionTablePointer);
1209  return nullptr;
1210  }
1211 
1212 }
GraphicSpace::IntegerExceptionType::INVALID_NUMBER_OF_TERMITES
@ INVALID_NUMBER_OF_TERMITES
Invalid number of termites parameter.
GraphicSpace::BitmapInterpolator
Interpolator BitmapInterpolator(Step)
GraphicSpace::IntegerExceptionType::INVALID_FILE_SIZE
@ INVALID_FILE_SIZE
Invalid file size.
GraphicSpace::FloatExceptionType::INVALID_ALPHA
@ INVALID_ALPHA
Invalid exponent of the repulsion parameter.
GraphicSpace::Bitmap::PixelInformationType::NextPixelRandom
IndexType NextPixelRandom(RandomGenerator &CurrentGenerator, register const RepulsionType *RepulsionPointer) const noexcept
Definition: Bitmap.cpp:217
GraphicSpace::Bitmap::ComputeTermite
unsigned int ComputeTermite(register unsigned int MaximumValue, register IndexType PixelIndex, register const uint8_t *ColorPointer, register unsigned int Steps, register const PixelInformationType *PixelInformationPointer, register RepulsionType *RepulsionPointer, register RandomGenerator &CurrentGenerator, register PathFunction PathFinder) const noexcept
Definition: Bitmap.cpp:298
GraphicSpace::Bitmap::MakeIndex
IndexType MakeIndex(unsigned int Row, unsigned int Column) const noexcept
Definition: Bitmap.inl:210
GraphicSpace::Bitmap::PixelPointer
uint8_t * PixelPointer[NUMBER_OF_COLORS]
Definition: Bitmap.h:486
GraphicSpace::IntegerExceptionType::INVALID_IMAGE_SIZE
@ INVALID_IMAGE_SIZE
Invalid image size.
GraphicSpace::IntegerExceptionType::INVALID_NUMBER_OF_IMPORTANT_COLORS
@ INVALID_NUMBER_OF_IMPORTANT_COLORS
Invalid number of important colors.
GraphicSpace::FileExceptionType::FILE_READ_ERROR
@ FILE_READ_ERROR
GraphicSpace::IntegerExceptionType::INVALID_BITMAP_OFFSET
@ INVALID_BITMAP_OFFSET
Invalid bitmap offset.
GraphicSpace::Bitmap::CorrectFunction
static void * CorrectFunction(void *Argument) noexcept(false)
Definition: Bitmap.cpp:1190
GraphicSpace::FloatExceptionType::INVALID_BETA
@ INVALID_BETA
Invalid exponent of the attraction parameter.
Bitmap.h
NumberOfElements
#define NumberOfElements(Array)
Definition: Graphic.h:65
GraphicSpace::Bitmap::STRIP_HEIGHT
static constexpr unsigned int STRIP_HEIGHT
Definition: Bitmap.h:292
GraphicSpace::Bitmap::CorrectionParameters::Steps
unsigned int Steps
Definition: Bitmap.h:195
GraphicSpace::RandomGenerator
Definition: RandomGenerator.h:31
GraphicSpace::Bitmap::CorrectionDescriptorType::CorrectedColorPointer
uint8_t * CorrectedColorPointer
Definition: Bitmap.h:427
GraphicSpace::Bitmap::CorrectionDescriptorType::OriginalColorPointer
const uint8_t * OriginalColorPointer
Definition: Bitmap.h:431
GraphicSpace::IntegerExceptionType::INVALID_COLOR_PLANES
@ INVALID_COLOR_PLANES
Invalid number of color planes.
GraphicSpace::Bitmap::CorrectionDescriptorType::MaximumValue
unsigned int MaximumValue
Definition: Bitmap.h:435
Graphic.h
GraphicSpace::Bitmap::RepulsionType::Visitors
unsigned short Visitors
Definition: Bitmap.h:314
GraphicSpace::Bitmap::Correct
Bitmap Correct(register const CorrectionParameters &Parameters) noexcept(false)
Definition: Bitmap.cpp:1076
GraphicSpace::Bitmap::RepulsionType::Repulsion
unsigned short Repulsion
Definition: Bitmap.h:310
GraphicSpace::Bitmap::PixelInformationType::NextPixelMaximum
IndexType NextPixelMaximum(RandomGenerator &CurrentGenerator, register const RepulsionType *RepulsionPointer) const noexcept
Definition: Bitmap.cpp:74
GraphicSpace::IntegerException
Definition: IntegerException.h:92
GraphicSpace::IntegerExceptionType::INVALID_IMAGE_HEIGHT
@ INVALID_IMAGE_HEIGHT
Invalid height of the image.
GraphicSpace::IntegerExceptionType::INVALID_BITS_PER_PIXEL
@ INVALID_BITS_PER_PIXEL
Invalid number of bits per pixel.
Interpolator.h
GraphicSpace::FloatException
Definition: FloatException.h:56
GraphicSpace::Bitmap::CorrectionDescriptorType::PixelInformationPointer
const PixelInformationType * PixelInformationPointer
Definition: Bitmap.h:445
GraphicSpace::Bitmap::WriteFile
void WriteFile(const char *Path) noexcept(false)
Definition: Bitmap.cpp:973
GraphicSpace::IntegerExceptionType::INVALID_NUMBER_OF_STEPS
@ INVALID_NUMBER_OF_STEPS
Invalid number of steps parameter.
GraphicSpace::FloatExceptionType::INVALID_REPULSION_STEP
@ INVALID_REPULSION_STEP
Invalid repulsion step parameter.
GraphicSpace::FileExceptionType::FILE_WRITE_ERROR
@ FILE_WRITE_ERROR
NameException.h
GraphicSpace::FileExceptionType::FILE_SEEK_ERROR
@ FILE_SEEK_ERROR
GraphicSpace::Bitmap::RoundedDivide
static uint_fast32_t RoundedDivide(uint_fast32_t Dividend, uint_fast32_t Divisor) noexcept
Definition: Bitmap.inl:265
GraphicSpace::Bitmap::CorrectionDescriptorType::ParametersPointer
const CorrectionParameters * ParametersPointer
Definition: Bitmap.h:440
GraphicSpace::Interpolator
Definition: Interpolator.h:29
GraphicSpace::IntegerExceptionType
IntegerExceptionType
Definition: IntegerException.h:35
GraphicSpace::Bitmap::CorrectionDescriptorType::EndRow
unsigned int EndRow
Definition: Bitmap.h:422
GraphicSpace::Bitmap::MAXIMUM_NUMBER_OF_THREADS
static constexpr unsigned int MAXIMUM_NUMBER_OF_THREADS
Definition: Bitmap.h:140
GraphicSpace::Bitmap::ReadFile
void ReadFile(const char *Path) noexcept(false)
Definition: Bitmap.cpp:824
FileException.h
GraphicSpace::Bitmap::CorrectionParameters::Termites
unsigned int Termites
Definition: Bitmap.h:191
GraphicSpace::Bitmap::StripMutex
Mutex StripMutex
Definition: Bitmap.h:522
Thread.h
GraphicSpace::FileExceptionType::FILE_CLOSE_ERROR
@ FILE_CLOSE_ERROR
GraphicSpace::Mutex::Initialize
void Initialize(void) noexcept(false)
Definition: Mutex.cpp:67
GraphicSpace::Thread
Definition: Thread.h:28
GraphicSpace::Bitmap::operator=
Bitmap & operator=(const Bitmap &thisBitmap) noexcept
Definition: Bitmap.cpp:682
GraphicSpace::Bitmap::CorrectionDescriptorType::StartRow
unsigned int StartRow
Definition: Bitmap.h:418
GraphicSpace::Bitmap::BitmapSize
uint_fast32_t BitmapSize
Definition: Bitmap.h:470
GraphicSpace::FileExceptionType::FILE_OPEN_ERROR
@ FILE_OPEN_ERROR
GraphicSpace::Bitmap::DescriptorPointer
CorrectionDescriptorType * DescriptorPointer
Definition: Bitmap.h:526
GraphicSpace::IntegerExceptionType::INVALID_IMAGE_WIDTH
@ INVALID_IMAGE_WIDTH
Invalid width of the image.
GraphicSpace::Bitmap::CorrectStrip
void CorrectStrip(register uint8_t *CorrectedColorPointer, register const uint8_t *OriginalColorPointer, register unsigned int StartRow, register unsigned int EndRow, register unsigned int MaximumValue, register const CorrectionParameters &Parameters, register const PixelInformationType *PixelInformationPointer, register PathFunction PathFinder, register const uint_least32_t DivisionTable[UINT8_MAX+1]) const noexcept
Definition: Bitmap.cpp:377
GraphicSpace::Bitmap::CorrectionParameters
Definition: Bitmap.h:182
GraphicSpace::Bitmap::InitialRepulsionPointer
RepulsionType * InitialRepulsionPointer
Definition: Bitmap.h:506
GraphicSpace::RandomGenerator::ModifySeed
void ModifySeed(uint_fast32_t Value) noexcept
Definition: RandomGenerator.inl:128
GraphicSpace
Definition: Bitmap.cpp:29
GraphicSpace::Bitmap::CorrectionDescriptorType::PathFinder
PathFunction PathFinder
Definition: Bitmap.h:449
GraphicSpace::FileException
Definition: FileException.h:60
GraphicSpace::Bitmap::OpenReadBinary
static const char *const OpenReadBinary
Definition: Bitmap.h:534
GraphicSpace::IntegerExceptionType::INVALID_NUMBER_OF_COLORS
@ INVALID_NUMBER_OF_COLORS
Invalid number of colors.
GraphicSpace::Bitmap::CorrectionDescriptorType
Definition: Bitmap.h:413
FloatException.h
GraphicSpace::Bitmap::Bitmap
Bitmap(void) noexcept
Definition: Bitmap.cpp:573
GraphicSpace::Mutex::Finalize
void Finalize(void) noexcept(false)
Definition: Mutex.cpp:93
GraphicSpace::Bitmap::Strips
uint_fast32_t Strips
Definition: Bitmap.h:518
GraphicSpace::Bitmap::CorrectionParameters::Quiet
bool Quiet
Definition: Bitmap.h:226
GraphicSpace::Bitmap::CorrectionDescriptorType::DivisionTablePointer
const uint_least32_t * DivisionTablePointer
Definition: Bitmap.h:456
GraphicSpace::FileExceptionType
FileExceptionType
Definition: FileException.h:34
GraphicSpace::Bitmap::~Bitmap
~Bitmap(void) noexcept
Definition: Bitmap.cpp:661
IntegerException.h
GraphicSpace::Bitmap::GetStripDescriptor
const CorrectionDescriptorType * GetStripDescriptor(void) noexcept
Definition: Bitmap.cpp:543
GraphicSpace::Bitmap::IndexType
uint_fast32_t IndexType
Definition: Bitmap.h:155
GraphicSpace::IntegerExceptionType::BITMAP_TOO_LARGE
@ BITMAP_TOO_LARGE
Bitmap too large.
GraphicSpace::Bitmap::HeaderName
static const char HeaderName[HEADER_NAME_LENGTH]
Definition: Bitmap.h:530
Step
constexpr unsigned int Step
Definition: Bitmap.cpp:27
IgnoreValue
#define IgnoreValue(Expression)
Definition: Graphic.h:55
GraphicSpace::Bitmap
Definition: Bitmap.h:32
GraphicSpace::Bitmap::TERMITES_SUM_SCALE
static constexpr unsigned int TERMITES_SUM_SCALE
Definition: Bitmap.h:276
GraphicSpace::NameException
Definition: NameException.h:50
GraphicSpace::Bitmap::CorrectColor
void CorrectColor(register uint8_t *CorrectedColorPointer, register const uint8_t *OriginalColorPointer, register unsigned int MaximumValue, register const CorrectionParameters &Parameters, register const PixelInformationType *PixelInformationPointer, register PathFunction PathFinder, const uint_least32_t DivisionTable[UINT8_MAX+1]) noexcept
GraphicSpace::Bitmap::OpenWriteBinary
static const char *const OpenWriteBinary
Definition: Bitmap.h:538
GraphicSpace::Bitmap::Generator
RandomGenerator Generator
Definition: Bitmap.h:514
GraphicSpace::Bitmap::PixelInformationType
Definition: Bitmap.h:325
GraphicSpace::Bitmap::MAXIMUM_BITMAP_SIZE
static constexpr unsigned int MAXIMUM_BITMAP_SIZE
Definition: Bitmap.h:126
GraphicSpace::Bitmap::Width
uint_fast32_t Width
Definition: Bitmap.h:462
GraphicSpace::Bitmap::RepulsionType
Definition: Bitmap.h:301
GraphicSpace::IntegerExceptionType::INVALID_DIB_HEADER_SIZE
@ INVALID_DIB_HEADER_SIZE
Invalid DIB header size.
GraphicSpace::IntegerExceptionType::INVALID_COMPRESSION
@ INVALID_COMPRESSION
Invalid value for compression.
GraphicSpace::Bitmap::Height
uint_fast32_t Height
Definition: Bitmap.h:466