Skip to content
Snippets Groups Projects
traitementPGM.c 13.8 KiB
Newer Older
Og's avatar
Og committed
#include "traitementPGM.h"

// Recupére un nombre dans une chaine de caractere avec un séparateur et suprime le nombre trouver de la chaine de caractére
int stringToInt(char *buf, char crt)
{
    int result = 0;
    int i;
    //printf("buf =%s", buf);

    for (i = 0; buf[i] != crt && buf[i] != '\n'; i++)
    {
        result = result * 10 + (buf[i] - '0');
    }
    i++;
    int j;
    for (j = 0; buf[j] != '\n'; j++)
    {

        buf[j] = buf[j + i];
    }
    buf[j + 1] = '\n';

    return result;
}

error_code pgm_read_from_file(pgm *p, char *filename)
{
    FILE *fp = fopen(filename, "r");
    int buf_size = 32;
    char buffer[buf_size];
    int x, y, max;

    // Test si le fichier filname existe
    if (NULL == fp)
    {
        fprintf(stderr, "Can't open output file %s!\n", filename); // affiche dans le canal d'erreur
Og's avatar
Og committed
        return uninitialized;
Og's avatar
Og committed
    }

    // Test si l'image est bien en format PGM "P5"
    fgets(buffer, buf_size, fp);
    //printf("%s", buffer);
    if (buffer[0] != 'P' && buffer[1] != '5')
    {
        fprintf(stderr, "File isn't in PGM format %s!\n", buffer); // affiche dans le canal d'erreur
Og's avatar
Og committed
        return out_of_bounds;
Og's avatar
Og committed
    }

    // Recupère la taille de l'image
    fgets(buffer, buf_size, fp);
    x = stringToInt(buffer, ' ');
    y = stringToInt(buffer, ' ');
    // printf("String :%s X:%d Y:%d\n", buffer,x,y);

    // Recupère l'intensité max des pixels de l'image
    fgets(buffer, buf_size, fp);
    max = stringToInt(buffer, '\0');
    // printf("max :%d\n", max);

    // Initialise les descriptife de l'image pgm
    p->max = max;
    p->pixels.pM = NULL;

    // Créer une liste contenant le fichier pgm
    __u_char *filechar = malloc(y * x * sizeof(__int32_t));
    __int32_t *fileint = malloc(y * x * sizeof(__int32_t));
    __int16_t *fileint16 = malloc(y * x * sizeof(__int32_t));
    //fread(filechar, sizeof(__u_char), y * x, fp);

    fread(fileint16, sizeof(__int16_t), y * x, fp);

    // Cast les valleurs char en int32 compris par la matrix
    for (int i = 0; i < y * x; i++)
    {
        fileint[i] = (__int32_t)fileint16[i];
        //printf("%d ",fileint[i]);
    }

    // Créer une matrix contenant les données du pgm
Og's avatar
Og committed
    if (matrix_init_from_array(&p->pixels, y, x, fileint) != ok)
Og's avatar
Og committed
    {
        fprintf(stderr, "The matrix isn't allocated %s!\n", buffer); // affiche dans le canal d'erreur
Og's avatar
Og committed
        return memory_error;
Og's avatar
Og committed
    }

    // Libébere l'espace non utils
    free(fileint);
    free(filechar);
    free(fileint16);
    fclose(fp);
Og's avatar
Og committed
    return ok;
Og's avatar
Og committed
}

error_code pgm_write_to_file(pgm *p, char *filename)
{
    FILE *fp = fopen(filename, "w");

    // Test si le fichier filname existe
    if (NULL == fp)
    {
        fprintf(stderr, "Can't creat output file %s!\n", filename); // affiche dans le canal d'erreur
Og's avatar
Og committed
        return uninitialized;
Og's avatar
Og committed
    }

    fprintf(fp, "P5\n%d %d\n%d\n", p->pixels.n, p->pixels.m, p->max);

    // Créer une liste contenant le fichier pgm
    u_int16_t *filechar = malloc(p->pixels.n * p->pixels.m * sizeof(u_int16_t));
    for (int i = 0; i < p->pixels.m; i++)
    {
        for (int j = 0; j < p->pixels.n; j++)
        {
            filechar[i * p->pixels.n + j] = (u_int16_t)p->pixels.pM[j][i];
        }
    }
    fwrite(filechar, sizeof(u_int16_t), p->pixels.n * p->pixels.m, fp);

    free(filechar);
    fclose(fp);
Og's avatar
Og committed
    return ok;
Og's avatar
Og committed
}
/*
pgm_error pmg_negative(pgm *neg, const pgm *const orig)
{
    // Test si la matrix d 'origine existe
    if (orig->pixels.pM == NULL)
    {
        fprintf(stderr, "L'image d'origine n'est pas initialisée !\n");
        return failure;
    }
    // Initialise les descriptife de l'image pgm
    neg->max = orig->max;
    neg->pixels.pM = NULL;

    // Allocation d'espace pour l'image
    if (matrix_init(&neg->pixels, orig->pixels.m, orig->pixels.n) != OK)
    {
        return failure;
    }

    // Soutraire le negatif de chaque pixels
    for (int i = 0; i < orig->pixels.n; i++)
    {
        for (int j = 0; j < orig->pixels.m; j++)
        {
            neg->pixels.pM[i][j] = orig->max - orig->pixels.pM[i][j];
        }
    }

    return success;
}

pgm_error pmg_symmetry_hori(pgm *sym, const pgm *const orig)
{
    // Test si la matrix d 'origine existe
    if (orig->pixels.pM == NULL)
    {
        fprintf(stderr, "L'image d'origine n'est pas initialisée !\n");
        return failure;
    }
    // Initialise les descriptife de l'image pgm
    sym->max = orig->max;
    sym->pixels.pM = NULL;

    // Allocation d'espace pour l'image
    if (matrix_init(&sym->pixels, orig->pixels.m, orig->pixels.n) != OK)
    {
        return failure;
    }

    // Equivaut a la simetrie du pixel
    for (int i = 0; i < orig->pixels.n; i++)
    {
        for (int j = 0; j < orig->pixels.m; j++)
        {
            // pixels partan de gauche sont equivalant a seux partant de droite
            sym->pixels.pM[i][j] = orig->pixels.pM[orig->pixels.n - 1 - i][j]; 
        }
    }

    return success;
}

pgm_error pmg_symmetry_vert(pgm *sym, const pgm *const orig)
{
    // Test si la matrix d 'origine existe
    if (orig->pixels.pM == NULL)
    {
        fprintf(stderr, "L'image d'origine n'est pas initialisée !\n");
        return failure;
    }
    // Initialise les descriptife de l'image pgm
    sym->max = orig->max;
    sym->pixels.pM = NULL;

    // Allocation d'espace pour l'image
    if (matrix_init(&sym->pixels, orig->pixels.m, orig->pixels.n) != OK)
    {
        return failure;
    }

    // Equivaut a la simetrie du pixel
    for (int i = 0; i < orig->pixels.n; i++)
    {
        for (int j = 0; j < orig->pixels.m; j++)
        {
            // pixels partan du haut sont equivalant a seux partant de bas
            sym->pixels.pM[i][j] = orig->pixels.pM[i][orig->pixels.m - 1 - j]; 
        }
    }

    return success;
}

pgm_error pmg_symmetry_cent(pgm *sym, const pgm *const orig)
{
    // Test si la matrix d 'origine existe
    if (orig->pixels.pM == NULL)
    {
        fprintf(stderr, "L'image d'origine n'est pas initialisée !\n");
        return failure;
    }
    // Initialise les descriptife de l'image pgm
    sym->max = orig->max;
    sym->pixels.pM = NULL;

    // Allocation d'espace pour l'image
    if (matrix_init(&sym->pixels, orig->pixels.m, orig->pixels.n) != OK)
    {
        return failure;
    }

    // Equivaut a la simetrie du pixel
    for (int i = 0; i < orig->pixels.n; i++)
    {
        for (int j = 0; j < orig->pixels.m; j++)
        {
            // pixels partan de gauche sont equivalant a seux partant de droite
            // pixels partan du haut sont equivalant a seux partant de bas
            sym->pixels.pM[i][j] = orig->pixels.pM[orig->pixels.n - 1 - i][orig->pixels.m - 1 - j]; 
        }
    }

    return success;
}

pgm_error pmg_photomaton(pgm *photomaton, const pgm *const orig)
{
    // Test si la matrix d 'origine existe
    if (orig->pixels.pM == NULL)
    {
        fprintf(stderr, "L'image d'origine n'est pas initialisée !\n");
        return failure;
    }
    // Initialise les descriptife de l'image pgm
    photomaton->max = orig->max;
    photomaton->pixels.pM = NULL;

    // Allocation d'espace pour l'image
    if (matrix_init(&photomaton->pixels, orig->pixels.m, orig->pixels.n) != OK)
    {
        return failure;
    }

    int partn = orig->pixels.n / 2;
    int partm = orig->pixels.m / 2;
    bool divn = false;
    bool divm = false;
    int x =0;
    int y =0;

    // Pour chaque pixels de l'image permuter sure les differents quadrants
    for (int i = 0; i < orig->pixels.n; i++)
    {
        for (int j = 0; j < orig->pixels.m; j++)
        {
            if (!divm) // Alterner chaque ligne entre les cadrant du haut et seux du bas 
            {
                if (!divn) // Alterner chaque pixels sur cadrant haut gauche et haut droite
                {
                    photomaton->pixels.pM[y][x] = orig->pixels.pM[i][j];
                }
                else
                {
                    photomaton->pixels.pM[partn + y][x] = orig->pixels.pM[i][j];
                    x++;
                }
            }
            else
            {
                if (!divn)  // Alterner chaque pixels sur cadrant bas gauche et bas droite
                {
                    photomaton->pixels.pM[y][partm + x] = orig->pixels.pM[i][j];
                }
                else
                {
                    photomaton->pixels.pM[partn + y][partm + x] = orig->pixels.pM[i][j];
                    x++;
                }
            }
            divn = !divn;
            
        }
        divm = !divm;
        if(!divm)
        {
            y++;
        }
        x = 0;
    }
    return success;
}

pgm_error pmg_crop(pgm *crop, const pgm *const orig, int32_t x0, int32_t x1,int32_t y0, int32_t y1)
{
    // Test si la matrix d 'origine existe
    if (orig->pixels.pM == NULL)
    {
        fprintf(stderr, "L'image d'origine n'est pas initialisée !\n");
        return failure;
    }
    // Initialise les descriptife de l'image pgm
    crop->max = orig->max;
    crop->pixels.pM = NULL;

    // Allocation d'espace pour l'image
    if (matrix_extract_submatrix(&crop->pixels, orig->pixels, y0, y1, x0 ,x1) != OK)
    {
        return failure;
    }
    return success;
}
    
pgm_error pmg_conv(pgm *conv, const pgm *const orig, const matrix *const kernel)
{
    // Test si la matrix d 'origine existe
    if (orig->pixels.pM == NULL)
    {
        fprintf(stderr, "L'image d'origine n'est pas initialisée !\n");
        return failure;
    }
    // Initialise les descriptife de l'image pgm
    conv->max = orig->max;
    conv->pixels.pM = NULL;

    // Allocation d'espace pour l'image
    if (matrix_init(&conv->pixels, orig->pixels.m, orig->pixels.n) != OK)
    {
        return failure;
    }

    int tabRes[9];
    int sum=0;

    // Parcourire tout l'image[i][j]
    for (int i = 0; i < conv->pixels.n; i++)
    {
        for (int j = 0; j < conv->pixels.m; j++)
        {
            

            // Copier les pixels au alentoure du pixel [i][j]
            for (int t = 0; t < 9; t++)
            {
                // Délimiter les sortie de cadrant en affecteur une valeur 0 
                if(j==0 && t<3)
                {
                    tabRes[t] = 0;
                    continue;
                }
                if(i == 0 && t%3 == 0)
                {
                    tabRes[t] = 0;
                    continue;
                }
                if(j == conv->pixels.m -1 && t>5)
                {
                    tabRes[t] = 0;
                    continue;
                }
                if(i == conv->pixels.n -1 && ( t==2 || t==5 || t==8))
                {
                    tabRes[t] = 0;
                    continue;
                }
                tabRes[t] = orig->pixels.pM[i-1 + t%3 ][j-1 + t/3];
            }
            
            // Appliquer la matrix de convolution a notre selection de pixel et calculer la moyen des pixels
            sum=0;
            for (int t = 0; t < 9; t++)
            {
                sum = sum + (tabRes[t] * kernel->pM[t%3][t/3]);
            }
            sum = sum/9;
            // Caster la sum dans la valeur de nos pixels
            if(sum < 0){sum = 0;}
            if(sum >= conv->max){sum = conv->max -1;}

            // Apliquer la valeur du pixels
            conv->pixels.pM[i][j] = sum;
            

        }
        
    }
    
    return success;
}

pgm_error pmg_filtre(pgm *conv, const pgm *const orig, const matrix *const kernel)
{
    // Test si la matrix d 'origine existe
    if (orig->pixels.pM == NULL)
    {
        fprintf(stderr, "L'image d'origine n'est pas initialisée !\n");
        return failure;
    }
    // Initialise les descriptife de l'image pgm
    conv->max = orig->max;
    conv->pixels.pM = NULL;

    // Allocation d'espace pour l'image
    if (matrix_init(&conv->pixels, orig->pixels.m, orig->pixels.n) != OK)
    {
        return failure;
    }

    int tabRes[9];
    int sum=0;

    // Parcourire tout l'image[i][j]
    for (int i = 0; i < conv->pixels.n; i++)
    {
        for (int j = 0; j < conv->pixels.m; j++)
        {
            

            // Copier les pixels au alentoure du pixel [i][j]
            for (int t = 0; t < 9; t++)
            {
                if(j==0 && t<3)
                {
                    tabRes[t] = 0;
                    continue;
                }
                if(i == 0 && t%3 == 0)
                {
                    tabRes[t] = 0;
                    continue;
                }
                if(j == conv->pixels.m -1 && t>5)
                {
                    tabRes[t] = 0;
                    continue;
                }
                if(i == conv->pixels.n -1 && ( t==2 || t==5 || t==8))
                {
                    tabRes[t] = 0;
                    continue;
                }
                tabRes[t] = orig->pixels.pM[i-1 + t%3 ][j-1 + t/3];
            }
            
            // Appliquer la matrix de convolution a notre selection de pixel et calculer la moyen des pixels
            sum=0;
            for (int t = 0; t < 9; t++)
            {
                sum = sum + (tabRes[t] * kernel->pM[t%3][t/3]);
            }
            sum = sum/9; // faux la valeur de doit pas etre moyennée mais ajustée entre le min et max des pixesl
            // Caster la sum dans la valeur de nos pixels
            if(sum < 0){sum = 0;}
            if(sum >= conv->max){sum = conv->max -1;}

            // Apliquer la valeur du pixels
            conv->pixels.pM[i][j] = sum;
            

        }
        
    }
    
    return success;
}
*/
void PrintImagePGM(pgm img, char *filname)
{
    printf("Image sélectionnée '%s' de taille %dx%d lumMax:%d\n", filname, img.pixels.n, img.pixels.m, img.max);
    struct gfx_context_t *ImagePGM = initWindow(img.pixels.n, img.pixels.m, filname);
Og's avatar
Og committed
    dessineTab2D(ImagePGM, img.pixels.pM, img.pixels.n, img.pixels.m,img.max); //
Og's avatar
Og committed
    gfx_present(ImagePGM);
    waitSpacePress();
    gfx_destroy(ImagePGM);
}