#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <pthread.h>
#include <semaphore.h>
typedef struct Parameters {
int s,t,number;
}Parameters;
static sem_t *masSemathore;
void* run(void* arg);
unsigned char* image;
unsigned char* new_image;
int main(void)
{
int n, width, height, i, res;
FILE *fin, *fout;
if (((fin = fopen("4.1.02.bmp", "r")) == NULL) || ((fout = fopen("new.bmp", "w")) == NULL))
{
return -1;
}
void* data = (void*)& width;
fseek(fin, 18, SEEK_SET);
n = fread(data, 4, 1, fin);
printf("Width: %d\n", width);
data = (void*)& height;
fseek(fin, 22, SEEK_SET);
n = fread(data, 4, 1, fin);
printf("Height: %d\n", height);
unsigned char* bmp = (unsigned char*) malloc (sizeof(char)*54);//�����
image = (unsigned char*) malloc (sizeof(char)*3*width*height);//������ �����
new_image = (unsigned char*) malloc (sizeof(char)*3*width*height);//����� �����
fseek(fin, 0, SEEK_SET);
n = fread(bmp, 54, 1, fin);
n = fread(image, 3*width*height, 1, fin);
//*(unsigned int*)&bmp[2] = 54 + 3*w*h; //��������� int � char
printf("Введите число нитей: ");
unsigned int p; //Число нитей
scanf("%d", &p);
bool badP = false; //Флаг, который означается целится нацело или нет
unsigned int g = height*width / p; //Количество пикселей на нить
if (3*height*width % p != 0)
badP = true; //Устанавливаем флаг
masSemathore = (sem_t*)malloc(p*sizeof(sem_t));
sem_init(&masSemathore[0], 0, 1);
for (i = 1; i < p; i++)
sem_init(&masSemathore[i], 0, 0);
pthread_t *thread;
thread = (pthread_t*)malloc(p*sizeof(pthread_t));
Parameters *masParameters;
masParameters = (Parameters*)malloc(p*sizeof(Parameters));
for (int i = 0; i < p-1; i++) { //Каждая отрабатывает кусок изображения от s до t длиной g
masParameters[i].s = 3*g*i;
masParameters[i].t = 3*g*(i+1);
masParameters[i].number = i;
}
masParameters[p-1].s = 3*g*(p-1);
masParameters[p-1].t = 3*height*width - masParameters[p-1].s;
masParameters[p-1].number = p-1;
for (i = 0; i < p; i++) {
res = pthread_create(&thread[i], NULL, &run, &masParameters[i]);
if (res != 0) {
printf("Cannot create thread %d", i+1);
exit(1);
}
}
for (i = 0; i < p; i++)
pthread_join(thread[i], NULL);
for (i = 0; i < p; i++)
sem_destroy(&masSemathore[i]);
free(masSemathore);
free(masParameters);
int sum = 0,j;
for (int i = 0; i < 256; i++) {
for (int j = 0; j < 3*width*height; j += 3) {
if (new_image[j] == i) {
sum++;
}
}
printf("%d=%d\n",i,sum);
sum = 0;
}
fwrite(bmp, 54, 1, fout);
fwrite(new_image, 3*width*height, 1, fout);
fclose(fin);
fclose(fout);
return 0;
}
void *run(void *arg) {
Parameters param = *((Parameters *) arg);
int s = param.s, t = param.t, number = param.number; //возвращаем параметры к нормальному типу, а не void
sem_wait(&masSemathore[number]);//Ждем пока дойдет очереть до этой нити
for (int i = s; i < t; i += 3) {
int k =(image[i]+image[i+1]+image[i+2])/3;
new_image[i] = k;
new_image[i+1] = k;
new_image[i+2] = k;
if (i % 10000 == 0) {
printf("k=%d,image[%d]=%d\n",k,i,image[i]);
}
}
sem_post(&masSemathore[number]);//Останавниваем нить, отдаем процессор другой нити
return NULL;
}