Листинг программы «Раскрашивание карты»
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include #include #include #include #include #include #include #pragma warning(disable: 5045)
#pragma warning(disable: 4820)
#define Right 1
#define Left 2
#define Top 3
#define Down 4
#define White 1500
#define ByteOnPixel 3
#define DataTimeSize 10
#define SecondsInMinute 60
#define Black 0
#define ConstBMP 0x4D42
#define NumberOfArguments 5
FILE* Log;
enum Errors {
OpenFileError,
MemoryAllocationError,
InputFileBmpError,
ToManyAreas
};
void Help(void) {
printf("\t---------------------------------------Добро пожаловать в программу!---------------------------------\n"
"\t| Программа поддерживает обработку следующих ключей: |\n"
"\t| 1. -h/--help - Ключ для вывода справки. |\n"
"\t| 2. -i/--input - Ключ для передачи пути к входному файлу. |\n"
"\t| 3. -o/--output - Ключ для передачи пути к выходному файлу. |\n"
"\t| Для запуска программы требуется ввести ключи -i и -o. |\n"
"\t------------------------------------------------------------------------------------------------------\n");
}
typedef struct {
int bfSize; // Общий размер файла в байтах (4 байта)
int bfOffBits; // Начальная позиция данных растрового изображения относительно растрового изображения (4 байта)
int biSize; // Количество байтов, занимаемых этой структурой (4 байта)
int biWidth; // Ширина растрового изображения в пикселях (4 байта)
int biHeight; // Высота растрового изображения в пикселях (4 байта)
int biCompression; // Тип сжатия растрового изображения должен быть 0 (без сжатия), 1 (BI_RLE8 Тип сжатия) или одно из 2 (тип сжатия BI_RLE4)) (4 байта)
int biSizeImage; // Размер растрового изображения в байтах (4 байта)
int biXPelsPerMeter; // Разрешение растрового изображения по горизонтали, количество пикселей на метр (4 байта)
int biYPelsPerMeter; // Вертикальное разрешение растрового изображения, пикселей на метр (4 байта)
int biClrUsed; // Количество цветов в таблице цветов, фактически используемых растровым изображением (4 байта)
int biClrImportant; // Количество важных цветов в процессе отображения растрового изображения (4 байта)
short bfType; // Код формата (2 байта)
short bfReserved1; // Зарезервированное слово растрового файла, должно быть 0 (2 байта)
short bfReserved2; // Зарезервированное слово растрового файла, должно быть 0 (2 байта)
short biPlanes; // Уровень целевого устройства должен быть 1 (2 байта)
short biBitCount; // Количество битов, необходимых для каждого пикселя, должно быть 1 (два цвета), // 4 (16 цветов), 8 (256 цветов), 24 (истинный цвет) или 32 (улучшенный истинный цвет) (2 байта)
}Header;
struct Queue {
int Position;
struct Queue* Next;
};
void PrintError(int Error) {
char Date[DataTimeSize] = { 0 }, Time[DataTimeSize] = { 0 };
_strdate(Date); //Текущая дата
_strtime(Time); //Текущее время
if (Error == OpenFileError)
fprintf(Log, "%s %s - ERROR - Ошибка при открытии файла\n", Date, Time);
if (Error == MemoryAllocationError)
fprintf(Log, "%s %s - ERROR - Ошибка при выделении памяти\n", Date, Time);
if (Error == InputFileBmpError)
fprintf(Log, "%s %s - ERROR - Входной файл не ялвется BMP файлом\n", Date, Time);
if (Error == ToManyAreas)
fprintf(Log, "%s %s - ERROR - Слишком много областей\n", Date, Time);
}
void* Check_NULL(void* Ptr) {
if (Ptr == NULL) {
PrintError(MemoryAllocationError);
exit(EXIT_FAILURE);
}
return Ptr;
}
void Enqueue(struct Queue** Head, struct Queue** Tail, int Number) {
struct Queue* New = NULL;
New = (struct Queue*)Check_NULL(malloc(sizeof(struct Queue)));
if (New != NULL) {
memset(New, 0x00, sizeof(struct Queue));
New->Position = Number;
New->Next = NULL;
if (*Head == NULL) {
*Head = New;
}
else {
(*Tail)->Next = New;
}
*Tail = New;
}
else {
PrintError(MemoryAllocationError);
exit(EXIT_FAILURE);
}
}
int Dequeue(struct Queue** Head, struct Queue** Tail, int Areas) {
int Number = 0;
struct Queue* Temp = NULL;
if (*Head == NULL) {
return Areas+1;
/*PrintError(MemoryAllocationError);
exit(EXIT_FAILURE);*/
}
Temp = *Head;
Number = (*Head)->Position;
*Head = (*Head)->Next;
if (*Head == NULL) {
(*Tail) = NULL;
}
free(Temp);
return Number;
}
//Функция, которая заполняют структуру, содержащую информацию о заголовке файла bmp
ColorTop = DetermineColor(Output, (ftell(Output) + (FileHeader->biWidth * ByteOnPixel) * (Count - 1) + FlagWidth * (Count - 1) - ByteOnPixel * Count));
ColorDown = DetermineColor(Output, (ftell(Output) - (FileHeader->biWidth * ByteOnPixel) * (Count - 1) - FlagWidth * (Count - 1) - ByteOnPixel * Count)); //Черная граница справа
if (i + Count - 1 <= FileHeader->biHeight - 1 && i - Count + 1 >= 0 && ColorDown == Black && ColorTop == Black) {
Count++;
continue;
}
if (i + Count - 1 > FileHeader->biHeight - 1 && i - Count + 1 >= 0 && ColorTop == Black) {
Count++;
continue;
}
if (i + Count - 1 <= FileHeader->biHeight - 1 && i - Count + 1 < 0 && ColorDown == Black) {
Count++;
continue;
}
if (i + Count - 1 <= FileHeader->biHeight - 1 && i - Count + 1 >= 0 && (ColorDown != Black || ColorTop != Black))return Black;
if (i + Count - 1 <= FileHeader->biHeight - 1 && i - Count + 1 < 0 && ColorDown != Black) return Black;
if (i + Count - 1 > FileHeader->biHeight - 1 && i - Count + 1 > 0 && ColorTop != Black) return Black;
return Black;
}
if (j - Count < 0) return Black;
Color = DetermineColor(Output, (ftell(Output) - ByteOnPixel * Count));
if (j - Count >= 0 && Color != Black)return Color; //Нашли цвет
return Black;
}
int GoRight(FILE* Output, Header* FileHeader, int Area, int* Position, FILE* Table, int FlagWidth, int Areas) {
int i = Position[0], j = Position[1], Result = 0;
char One = '1';
unsigned char Color[3] = { 0 };
while (1) {
if (i == (FileHeader->biHeight - 1) || DetermineColor(Output, (ftell(Output) - (FileHeader->biWidth * 3) - FlagWidth)) == Black) {
if (j < FileHeader->biWidth && Area < 255 && DetermineColor(Output, ftell(Output)) < Areas) {
int Count = Areas + Area;
if (Count <= 255) {
Color[0] = 0; Color[1] = 0; Color[2] = (unsigned char)(Count);
}
if (Count > 255 && Count <= 510) {
Color[0] = 0; Color[1] = (unsigned char)(Count - 255); Color[2] = 255;
}
if (Count > 510 && Count <= 765) {
Color[0] = (unsigned char)(Count - 510); Color[1] = 255; Color[2] = 255;
}
ChangeColor(Output, Color);
fseek(Output, -3, SEEK_CUR);
}
Result = BottomBorder(Output, FileHeader, i, j, FlagWidth, Areas);
if (Result > Areas)Result -= Areas;
if (Area > Areas)Area -= Areas;
if (Result != Black) {
if (Result > Areas)Result -= Areas;
if (Area > Areas)Area -= Areas;
fseek(Table, (Area - 1) * Areas + (Result - 1), SEEK_SET);
fprintf(Table, "%c", One);
}
}
else {
Position[0] = i + 1;
Position[1] = j;
fseek(Output, -FileHeader->biWidth * 3 - FlagWidth, SEEK_CUR);
return Down;
}
if (((j < FileHeader->biWidth - 1 && DetermineColor(Output, ftell(Output) + 3) == Black)) || (j == FileHeader->biWidth - 1)) {
Result = BottomRight(Output, FileHeader, i, j, FlagWidth, Areas);
if (Result > Areas)Result -= Areas;
if (Area > Areas)Area -= Areas;
if (Result != Black) {
if (Result > Areas)Result -= Areas;
if (Area > Areas)Area -= Areas;
fseek(Table, (Area - 1) * Areas + (Result - 1), SEEK_SET);
fprintf(Table, "%c", One);
}
if (i > 0 && j < FileHeader->biWidth - 1 && DetermineColor(Output, (ftell(Output) + (FileHeader->biWidth * 3) + FlagWidth)) != Black && DetermineColor(Output, (ftell(Output) + (FileHeader->biWidth * 3) + FlagWidth) + 3) != Black) {
Position[0] = i - 1;
Position[1] = j + 1;
fseek(Output, +FileHeader->biWidth * 3 + FlagWidth + 3, SEEK_CUR);
return Right;
}
Position[0] = i;
Position[1] = j;
return Top;
}
else {
j++;
fseek(Output, +3, SEEK_CUR);
}
}
}
int GoTop(FILE* Output, Header* FileHeader, int Area, int* Position, FILE* Table, int FlagWidth, int Areas) {
int i = Position[0], j = Position[1], Result = 0;
char One = '1';
unsigned char Color[ByteOnPixel] = { 0 };
while (1) {
if (j == FileHeader->biWidth - 1 || DetermineColor(Output, (ftell(Output) + ByteOnPixel)) == Black) {
if (i >= 0 && Area < 255 && DetermineColor(Output, ftell(Output)) < Areas) {
int Count = Areas + Area;
if (Count <= 255) {
Color[0] = 0; Color[1] = 0; Color[2] = (unsigned char)(Count);
}
if (Count>255 && Count <= 510) {
Color[0] = 0; Color[1] = (unsigned char)(Count - 255); Color[2] = 255;
}
if (Count > 510 && Count <= 765) {
Color[0] = (unsigned char)(Count - 510); Color[1] = 255; Color[2] = 255;
}
ChangeColor(Output, Color);
fseek(Output, -ByteOnPixel, SEEK_CUR);
}
Result = BottomRight(Output, FileHeader, i, j, FlagWidth, Areas);
if (Result > Areas)Result -= Areas;
if (Area > Areas)Area -= Areas;
if (Result != Black) {
if (Result > Areas)Result -= Areas;
if (Area > Areas)Area -= Areas;
fseek(Table, (Area - 1) * Areas + (Result - 1), SEEK_SET);
fprintf(Table, "%c", One);
}
}
else {
Position[0] = i;
Position[1] = j + 1;
fseek(Output, +ByteOnPixel, SEEK_CUR);
return Right;
}
if ((i > 0 && DetermineColor(Output, (ftell(Output) + (FileHeader->biWidth * ByteOnPixel) + FlagWidth)) == Black) || i == 0) {
Result = BottomTop(Output, FileHeader, i, j, FlagWidth, Areas);
if (Result > Areas)Result -= Areas;
if (Area > Areas)Area -= Areas;
if (Result != Black) {
if (Result > Areas)Result -= Areas;
if (Area > Areas)Area -= Areas;
fseek(Table, (Area - 1) * Areas + (Result - 1), SEEK_SET);
fprintf(Table, "%c", One);
}
if (i > 0 && j > 0 && DetermineColor(Output, (ftell(Output) - ByteOnPixel)) != Black && DetermineColor(Output, (ftell(Output) + (FileHeader->biWidth * ByteOnPixel) + FlagWidth - ByteOnPixel)) != Black) {
Position[0] = i - 1;
Position[1] = j - 1;
fseek(Output, +FileHeader->biWidth * ByteOnPixel + FlagWidth - ByteOnPixel, SEEK_CUR);
return Top;
}
Position[0] = i;
Position[1] = j;
return Left;
}
else {
i--;
fseek(Output, +FileHeader->biWidth * ByteOnPixel + FlagWidth, SEEK_CUR);
}
}
}
int GoLeft(FILE* Output, Header* FileHeader, int Area, int* Position, FILE* Table, int FlagWidth, int Areas) {
int i = Position[0], j = Position[1], Result = 0;
char One = '1';
unsigned char Color[ByteOnPixel] = { 0 };
while (1) {
if (i == 0 || DetermineColor(Output, (ftell(Output) + (FileHeader->biWidth * ByteOnPixel) + FlagWidth)) == Black) {
if (j >= 0 && DetermineColor(Output, ftell(Output)) < Areas) {
int Count = Areas + Area;
if (Count <= 255) {
Color[0] = 0; Color[1] = 0; Color[2] = (unsigned char)(Count);
}
if (Count > 255 && Count <= 510) {
Color[0] = 0; Color[1] = (unsigned char)(Count - 255); Color[2] = 255;
}
if (Count > 510&& Count <= 765) {
Color[0] = (unsigned char)(Count - 510); Color[1] = 255; Color[2] = 255;
}
ChangeColor(Output, Color);
fseek(Output, -ByteOnPixel, SEEK_CUR);
}
Result = BottomTop(Output, FileHeader, i, j, FlagWidth, Areas);
if (Result > Areas)Result -= Areas;
if (Area > Areas)Area -= Areas;
if (Result != Black) {
if (Result > Areas)Result -= Areas;
if (Area > Areas)Area -= Areas;
fseek(Table, (Area - 1) * Areas + (Result - 1), SEEK_SET);
fprintf(Table, "%c", One);
}
}
else {
Position[0] = i - 1;
Position[1] = j;
fseek(Output, +(FileHeader->biWidth * ByteOnPixel) + FlagWidth, SEEK_CUR);
return Top;
}
if ((j > 0 && DetermineColor(Output, (ftell(Output) - ByteOnPixel)) == Black) || j == 0) {
Result = BottomLeft(Output, FileHeader, i, j, FlagWidth, Areas);
if (Result > Areas)Result -= Areas;
if (Area > Areas)Area -= Areas;
if (Result != Black) {
if (Result > Areas)Result -= Areas;
if (Area > Areas)Area -= Areas;
fseek(Table, (Area - 1) * Areas + (Result - 1), SEEK_SET);
fprintf(Table, "%c", One);
}
if (i < FileHeader->biHeight - 1 && j>0 && DetermineColor(Output, (ftell(Output) - (FileHeader->biWidth * ByteOnPixel) - FlagWidth)) != Black && DetermineColor(Output, (ftell(Output) - (FileHeader->biWidth * ByteOnPixel) - FlagWidth) - ByteOnPixel) != Black) {
Position[0] = i + 1;
Position[1] = j - 1;
fseek(Output, -(FileHeader->biWidth * ByteOnPixel) - FlagWidth - ByteOnPixel, SEEK_CUR);
return Left;
}
Position[0] = i;
Position[1] = j;
return Down;
}
else {
j--;
fseek(Output, -ByteOnPixel, SEEK_CUR);
}
}
}
int GoDown(FILE* Output, Header* FileHeader, int Area, int* Position, FILE* Table, int FlagWidth, int Areas) {
int i = Position[0], j = Position[1], Result = 0;
unsigned char Color[ByteOnPixel] = { 0 };
char One = '1';
while (1) {
if (j == 0 || DetermineColor(Output, (ftell(Output) - ByteOnPixel)) == Black) {
if (i < FileHeader->biHeight && Area < 255 && DetermineColor(Output, ftell(Output)) < Areas) {
int Count = Areas + Area;
if (Count <= 255) {
Color[0] = 0; Color[1] = 0; Color[2] = (unsigned char)(Count);
}
if (Count > 255 && Count <= 510) {
Color[0] = 0; Color[1] = (unsigned char)(Count - 255); Color[2] = 255;
}
if (Count > 510&& Count <= 765) {
Color[0] = (unsigned char)(Count - 510); Color[1] = 255; Color[2] = 255;
}
ChangeColor(Output, Color);
fseek(Output, -ByteOnPixel, SEEK_CUR);
}
Result = BottomLeft(Output, FileHeader, i, j, FlagWidth, Areas);
if (Result != Black) {
if (Result > Areas)Result -= Areas;
if (Area > Areas)Area -= Areas;
fseek(Table, (Area-1) * Areas + (Result - 1), SEEK_SET);
fprintf(Table, "%c", One);
}
}
else {
Position[0] = i;
Position[1] = j - 1;
fseek(Output, -ByteOnPixel, SEEK_CUR);
return Left;
}
if ((i < FileHeader->biHeight - 1 && DetermineColor(Output, (ftell(Output) - (FileHeader->biWidth * ByteOnPixel) - FlagWidth)) == Black) || i == FileHeader->biHeight - 1) {
Result = BottomBorder(Output, FileHeader, i, j, FlagWidth, Areas);
if (Result > Areas)Result -= Areas;
if (Area > Areas)Area -= Areas;
if (Result != Black) {
if (Result > Areas)Result -= Areas;
if (Area > Areas)Area -= Areas;
fseek(Table, (Area - 1) * Areas + (Result - 1), SEEK_SET);
fprintf(Table, "%c", One);
}
if (i < FileHeader->biHeight - 1 && j < FileHeader->biWidth - 1 && DetermineColor(Output, (ftell(Output) + ByteOnPixel)) != Black && DetermineColor(Output, (ftell(Output) - (FileHeader->biWidth * ByteOnPixel) - FlagWidth + ByteOnPixel)) != Black) {
Position[0] = i + 1;
Position[1] = j + 1;
fseek(Output, -(FileHeader->biWidth * ByteOnPixel) - FlagWidth + ByteOnPixel, SEEK_CUR);
return Down;
}
Position[0] = i;
Position[1] = j;
return Right;
}
else {
i++;
fseek(Output, -(FileHeader->biWidth * ByteOnPixel) - FlagWidth, SEEK_CUR);
}
}
}
//Функция, определяющая какие области являются соседями
void Outline(int Areas, FILE* Output, Header* FileHeader, FILE* Table) {
float Counter = 35.0;
long Step = FileHeader->bfSize / 3000;
int Position[2] = { 0 }, Count = 1, PositionI = 0, PositionJ = 0, ColorArea = 0, Action = Right, PrevColor = 0, Flag = 0;
int FlagWidth = Width(FileHeader);
fseek(Output, FileHeader->bfOffBits, SEEK_SET);
for (int i = FileHeader->biHeight - 1; i >= 0; i--) {
for (int j = 0; j < FileHeader->biWidth; j++) {
if (ftell(Output) % Step == 0) {
Counter += (float)0.01;
printf("\rПрогресс: %.2f%%", Counter);
}
ColorArea = DetermineColor(Output, ftell(Output));
if (Count < Areas && ColorArea == Count) {
Position[0] = i, Position[1] = j;
PositionI = Position[0], PositionJ = Position[1];
Action = Right;
Flag = 1;
while (1) {
if (Action == Right)Action = GoRight(Output, FileHeader, ColorArea, Position, Table, FlagWidth, Areas);
if (Position[0] == PositionI && Position[1] == PositionJ)break;
if (Action == Top)Action = GoTop(Output, FileHeader, ColorArea, Position, Table, FlagWidth, Areas);
if (Position[0] == PositionI && Position[1] == PositionJ)break;
if (Action == Left)Action = GoLeft(Output, FileHeader, ColorArea, Position, Table, FlagWidth, Areas);
if (Position[0] == PositionI && Position[1] == PositionJ)break;
if (Action == Down)Action = GoDown(Output, FileHeader, ColorArea, Position, Table, FlagWidth, Areas);
if (Position[0] == PositionI && Position[1] == PositionJ)break;
}
Count++;
PrevColor = DetermineColor(Output, ftell(Output));
}
/*if (j != 0 && Flag == 0 && ((ColorArea == Black && (PrevColor > 0 && PrevColor < Areas)) || ((ColorArea < Areas && ColorArea>0) && PrevColor == Black))) {
Action = Left;
if (ColorArea == Black) {
ColorArea = PrevColor;
PrevColor = Black;
j--;
fseek(Output, -ByteOnPixel, SEEK_CUR);
}
Position[0] = i, Position[1] = j;
PositionI = Position[0], PositionJ = Position[1];
while (1) {
if (Action == Left)Action = GoLeft(Output, FileHeader, ColorArea, Position, Table, FlagWidth, Areas);
if (Position[0] == PositionI && Position[1] == PositionJ)break;
if (Action == Top)Action = GoTop(Output, FileHeader, ColorArea, Position, Table, FlagWidth, Areas);
if (Position[0] == PositionI && Position[1] == PositionJ)break;
if (Action == Right)Action = GoRight(Output, FileHeader, ColorArea, Position, Table, FlagWidth, Areas);
if (Position[0] == PositionI && Position[1] == PositionJ)break;
if (Action == Down)Action = GoDown(Output, FileHeader, ColorArea, Position, Table, FlagWidth, Areas);
if (Position[0] == PositionI && Position[1] == PositionJ)break;
}
fseek(Output, +ByteOnPixel, SEEK_CUR);
j++;
Flag = 1;
}*/
if (Flag == 0) PrevColor = DetermineColor(Output, ftell(Output));
Flag = 0;
fseek(Output, ByteOnPixel, SEEK_CUR);
if (j == FileHeader->biWidth - 1) fseek(Output, FlagWidth, SEEK_CUR);
}
}
}
//Функция, определяющая количество областей и раскрашивающая эти области в цвета с номером области
int FindNumberOfAreas(FILE* Output, Header* FileHeader, int FlagWidth) {
float Counter = 10.0;
long Step = FileHeader->bfSize / 2500;
int FlagColor = 0, Position = 0, Count = 1;
unsigned char Color[ByteOnPixel];
memset(Color, 0, sizeof(Color));
fseek(Output, FileHeader->bfOffBits, SEEK_SET);
for (int i = FileHeader->biHeight - 1; i >= 0; i--) {
for (int j = 0; j < FileHeader->biWidth; j++) {
if (ftell(Output) % Step == 0) {
Counter += (float)0.01;
printf("\rПрогресс: %.2f%%", Counter);
}
if (Count <= 255) {
Color[0] = 0; Color[1] = 0; Color[2] = (unsigned char)Count;
}
if (Count > 255 && Count <= 383) {
Color[0] = 0; Color[1] = (unsigned char)(Count - 255); Color[2] = 255;
}
if (Count > 383) {
PrintError(ToManyAreas);
exit(EXIT_FAILURE);
}
Position = ftell(Output);
FlagColor = DetermineColor(Output, ftell(Output));
if (FlagColor == White) {
Colorize(Output, FileHeader, Color, White, FlagWidth, i, j);
Count++;
}
fseek(Output, Position + ByteOnPixel, SEEK_SET);
if (j == FileHeader->biWidth - 1) fseek(Output, FlagWidth, SEEK_CUR);
}
}
return (Count - 1);
}
void PaintingAreas(short* AreaColor, FILE* Output, Header* FileHeader, int FlagWidth) {
int Position = 0, FlagColor = 0, Count = 0;
float Counter = 75.0;
long Step = FileHeader->bfSize / 2500;
unsigned char Color[ByteOnPixel];
memset(Color, 0, sizeof(Color));
for (int i = FileHeader->biHeight - 1; i >= 0; i--) {
for (int j = 0; j < FileHeader->biWidth; j++) {
if (ftell(Output) % Step == 0) {
Counter += (float)0.01;
printf("\rПрогресс: %.2f%%", Counter);
}
if (AreaColor[Count] == 1) { Color[0] = 162; Color[1] = 249; Color[2] = 172; }
if (AreaColor[Count] == 2) { Color[0] = 233; Color[1] = 234; Color[2] = 176; }
if (AreaColor[Count] == 3) { Color[0] = 245; Color[1] = 163; Color[2] = 248; }
if (AreaColor[Count] == 4) { Color[0] = 249; Color[1] = 9; Color[2] = 38; }
if (AreaColor[Count] == 5) { Color[0] = 79; Color[1] = 236; Color[2] = 236; }
Position = ftell(Output);
FlagColor = DetermineColor(Output, ftell(Output));
if (FlagColor == Count + 1) {
Colorize(Output, FileHeader, Color, Count + 1, FlagWidth, i, j);
Count++;
}
fseek(Output, Position + ByteOnPixel, SEEK_SET);
if (j == FileHeader->biWidth - 1)fseek(Output, FlagWidth, SEEK_CUR);
}
}
Counter = 100.0;
printf("\rПрогресс: %.2f%%\n", Counter);
}
//Делает матрицу симметричной
void SymmertricMatrix(FILE* Table, int Areas) {
int Number = 0,Number1 = 0, Number2 = 0;
char Symbol = 0;
for (int i = 0; i < Areas; i++) {
for (int j = 0; j < Areas; j++) {
if (i == j) continue;
else {
fseek(Table, i * Areas + j, SEEK_SET);
Number1 = fgetc(Table)-'0';
fseek(Table, j * Areas + i, SEEK_SET);
Number2 = fgetc(Table)-'0';
Number = Number1 | Number2;
if (Number == 1)Symbol = '1';
else Symbol = '0';
fseek(Table, i * Areas + j, SEEK_SET);
fprintf(Table, "%c", Symbol);
fseek(Table, j * Areas + i, SEEK_SET);
fprintf(Table, "%c", Symbol);
}
}
}
}
//Функции, определяющие в какой цвет нужно закрасить эту область
short Define(FILE* Table, int Areas, short* AreaColor) {
int Count = 0;
float Counter = 65.0;
int Number = 0;
char Symbol = 0, One = '1';
char Number1 = 0, Number2 = 0;
float Step = (float)(1 / Areas);
short Color = 0;
struct Queue* Head = NULL, * Tail = NULL;
for (int i = 0; i < Areas; i++) {
for (int j = 0; j < Areas; j++) {
fseek(Table, i * Areas + j, SEEK_SET);
Symbol = (char)fgetc(Table);
if (Symbol == '0')
AreaColor[i]++;
}
}
for (int i = 0; i < Areas && Count < Areas; i++) {
for (int j = 0; j < Areas; j++) {
if (AreaColor[j] == i) {
Enqueue(&Head, &Tail, j);
Count++;
}
}
}
for (int i = 0; i < Areas; i++) {
AreaColor[i] = 0;
}
Count = 0;
for (int i = 0; i < Areas; i++) {
Counter += Step;
printf("\rПрогресс: %.2f%%", Counter);
Count = Dequeue(&Head, &Tail,Areas);
if (AreaColor[Count] != 0) continue;
Color++;
AreaColor[Count] = Color;
for (int k = 0; k < Areas; k++) { //Count-основная область
fseek(Table, Count * Areas + k, SEEK_SET);
Symbol = (char)fgetc(Table);
if (Symbol=='0') { //k область которая не сосед
if (AreaColor[k] == 0) { //Если эта область не раскрашена, то раскрашиваем ее в такой же цвет
AreaColor[k] = Color;
for (int c = 0; c < Areas; c++) {
fseek(Table, Count * Areas + c, SEEK_SET);
Number1 = (char)fgetc(Table) - '0';
fseek(Table, k * Areas + c, SEEK_SET);
Number2 = (char)fgetc(Table) - '0';
Number = Number1 | Number2;
if (Number == 1)Symbol = '1';
else Symbol = '0';
fseek(Table, Count * Areas + c, SEEK_SET);
fprintf(Table, "%c", Symbol);
fseek(Table, k * Areas + c, SEEK_SET);
fprintf(Table, "%c", One);
fseek(Table, c * Areas + k, SEEK_SET);
fprintf(Table, "%c", One);
}
}
}
}
}
return Color;
}
void DeleteBorders(FILE* Output, Header* FileHeader, int FlagWidth, int Areas) {
int FlagColor = 0;
unsigned char Color[ByteOnPixel] = { 0 };
fseek(Output, FileHeader->bfOffBits, SEEK_SET);
for (int i = FileHeader->biHeight - 1; i >= 0; i--) {
for (int j = 0; j < FileHeader->biWidth; j++) {
FlagColor = DetermineColor(Output, ftell(Output));
if (FlagColor > Areas) {
FlagColor = FlagColor - Areas;
if (FlagColor <= 255) {
Color[0] = 0; Color[1] = 0; Color[2] = (unsigned char)(FlagColor);
}
if (FlagColor > 255 && FlagColor <= 383) {
Color[0] = 0; Color[1] = (unsigned char)(FlagColor); Color[2] = 255;
}
/*if (FlagColor > 383) {
PrintError(ToManyAreas);
exit(EXIT_FAILURE);
}*/
ChangeColor(Output, Color);
fseek(Output, -ByteOnPixel, SEEK_CUR);
}
fseek(Output, ByteOnPixel, SEEK_CUR);
if (j == FileHeader->biWidth - 1) fseek(Output, FlagWidth, SEEK_CUR);
}
}
}
void PrintStart(void) {
char Date[DataTimeSize] = { 0 }, Time[DataTimeSize] = { 0 };
_strdate(Date); //Текущая дата
_strtime(Time); //Текущее время
fprintf(Log, "%s %s - INFO - Начало работы программы:\n", Date, Time);
}
void PrintResult(int TotalTime, int TimeOnColoring, int NumberOfColors, int Areas) {
char Date[DataTimeSize] = { 0 }, Time[DataTimeSize] = { 0 };
_strdate(Date); //Текущая дата
_strtime(Time); //Текущее время
if (TotalTime < SecondsInMinute) {
printf("Время работы всей программы: %d секунд.\n", TotalTime);
fprintf(Log, "%s %s - INFO - Время работы всей программы: %d секунд.\n", Date, Time, TotalTime);
}
else {
printf("Время работы всей программы: %d минут и %d секунд.\n", TotalTime / SecondsInMinute, TotalTime % SecondsInMinute);
fprintf(Log, "%s %s - INFO - Время работы всей программы: %d минут и %d секунд.\n", Date, Time, TotalTime / SecondsInMinute, TotalTime % SecondsInMinute);
}
if (TimeOnColoring < SecondsInMinute) {
printf("Время алгоритма раскрашивания: %d секунд.\n", TimeOnColoring);
fprintf(Log, "%s %s - INFO - Время алгоритма раскрашивания: %d секунд.\n", Date, Time, TimeOnColoring);
}
else {
printf("Время работы всей программы: %d минут и %d секунд.\n", TimeOnColoring / SecondsInMinute, TimeOnColoring % SecondsInMinute);
fprintf(Log, "%s %s - INFO - Время алгоритма раскрашивания: %d минут и %d секунд.\n", Date, Time, TimeOnColoring / SecondsInMinute, TimeOnColoring % SecondsInMinute);
}
printf("Количество цветов: %d\n", NumberOfColors);
fprintf(Log, "%s %s - INFO - Количество цветов: %d\n", Date, Time, NumberOfColors);
fprintf(Log, "\n");
printf("Количество областей: %d\n", Areas);
}
void PrintAreas(int Areas) {
char Date[DataTimeSize] = { 0 }, Time[DataTimeSize] = { 0 };
_strdate(Date); //Текущая дата
_strtime(Time); //Текущее время
fprintf(Log, "%s %s - INFO - Количество областей: %d\n", Date, Time, Areas);
}
void FillTable(FILE* Table, int Areas) {
char Zero = '0';
char One = '1';
for (int i = 0; i < Areas; i++) {
for (int j = 0; j < Areas; j++) {
if (i == j)fprintf(Table, "%c",One);
else fprintf(Table, "%c",Zero);
}
}
}
void Action(FILE* Input, FILE* Output) {
FILE* Table = fopen("Table.txt", "w+");
time_t TimeOnColoring = 0, TotalTime = clock();
Log = fopen("log.log", "a");
CheckFiles(Log);
PrintStart();
int Areas = 0, FlagWidth = 0, NumberOfColors = 0; //Количество областей
Header* FileHeader = (Header*)Check_NULL(malloc(sizeof(Header))); //Структура содержащая информацию из заголовка bmp файла
if (FileHeader == NULL) {
PrintError(MemoryAllocationError);
exit(EXIT_FAILURE);
}
memset(FileHeader, 0, sizeof(FileHeader));
Output = OpenFiles(FileHeader, Input, Output);
FlagWidth = Width(FileHeader); //Переменная, отвечающая за количество дополнительный байтов в конце ширины
Areas = FindNumberOfAreas(Output, FileHeader, FlagWidth);
FillTable(Table, Areas); //Файл содержит матрицй в линейном виде, в которой отмечены какие области являются соседями