如何模糊.pgm文件?

时间:2015-08-31 12:06:52

标签: c linux windows blur pgm

我编写了这段代码,它应该模糊.pgm文件。在Linux上完美运行,但它在Windows上产生了错误的结果。该程序应该像这样运行:“filter.exe enb.pgm enb_filtered.pgm qs 3”,其中第四个参数可以是qs / cnt / ins,具体取决于用户要使用的排序算法,而第五个参数则是一个奇数,并给出模糊窗口的宽度(至少应该到21)。第一个参数是我们的.exe,第二个是初始图像,第三个是最终图像。在Linux上,结果是预期的结果,而在Windows上,enb.filtered.pgm文件全部为黑色且尺寸错误。伙计们,能帮助我吗?

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <time.h>

#define HI(num) (((num) & 0x0000FF00) >> 8)
#define LO(num) ((num) & 0x000000FF)

typedef struct _PGMData {
    int row;
    int col;
    int max_gray;
    int **matrix;
} PGMData;

void quick_sort (int *a, int n) {
    int i, j, p, t;
    if (n < 2)
        return;
    p = a[n / 2];
    for (i = 0, j = n - 1;; i++, j--) {
        while (a[i] < p)
            i++;
        while (p < a[j])
            j--;
        if (i >= j)
            break;
        t = a[i];
        a[i] = a[j];
        a[j] = t;
    }
    quick_sort(a, i);
    quick_sort(a + i, n - i);
}

void insertion_sort (int *a, int n) {
    int i, j, t;
    for (i = 1; i < n; i++) {
        t = a[i];
        for (j = i; j > 0 && t < a[j - 1]; j--) {
            a[j] = a[j - 1];
        }
        a[j] = t;
    }
}

void counting_sort(int *array, int n)
{
    int i, j, k, min, max, *count;

    min = max = array[0];
    for(i=1; i < n; i++) {
        if ( array[i] < min ) {
          min = array[i];
        }
        else if ( array[i] > max ) {
            max = array[i];
        }
    }

    count = (int *)calloc(max - min + 1, sizeof(int));
    for(i = 0, k = 0; i < n; i++) {
        count[array[i] - min]++;
    }
    for(i = min; i <= max; i++) {
        for(j = 0; j < count[i - min]; j++) {
            array[k++] = i;
        }
    }
    free(count);
}

int **allocate_dynamic_matrix(int row, int col)
{
    int **ret_val;
    int i;

    ret_val = (int **)malloc(sizeof(int *) * row);
    if (ret_val == NULL) {
        perror("memory allocation failure");
        exit(EXIT_FAILURE);
    }

    for (i = 0; i < row; ++i) {
        ret_val[i] = (int *)malloc(sizeof(int) * col);
        if (ret_val[i] == NULL) {
            perror("memory allocation failure");
            exit(EXIT_FAILURE);
        }
    }

    return ret_val;
}

void deallocate_dynamic_matrix(int **matrix, int row)
{
    int i;

    for (i = 0; i < row; ++i)
        free(matrix[i]);
    free(matrix);
}

void SkipComments(FILE *fp)
{
    int ch;
    char line[100];

    while ((ch = fgetc(fp)) != EOF && isspace(ch))
        ;
    if (ch == '#') {
        fgets(line, sizeof(line), fp);
        SkipComments(fp);
    } else
        fseek(fp, -1, SEEK_CUR);
}

PGMData* readPGM(FILE *pgmFile, PGMData *data)
{
    char version[3];
    int i, j;
    int lo, hi;

    fgets(version, sizeof(version), pgmFile);
    if (strcmp(version, "P5")) {
        fprintf(stderr, "Wrong file type!\n");
        exit(EXIT_FAILURE);
    }

    SkipComments(pgmFile);
    fscanf(pgmFile, "%d", &(data->col));
    SkipComments(pgmFile);
    fscanf(pgmFile, "%d", &(data->row));
    SkipComments(pgmFile);
    fscanf(pgmFile, "%d", &(data->max_gray));
    fgetc(pgmFile);

    data->matrix = allocate_dynamic_matrix(data->row, data->col);

    if (data->max_gray > 255)
        for (i = 0; i < data->row; ++i)
            for (j = 0; j < data->col; ++j) {
                hi = fgetc(pgmFile);
                lo = fgetc(pgmFile);
                data->matrix[i][j] = (hi << 8) + lo;
            }
    else
        for (i = 0; i < data->row; ++i)
            for (j = 0; j < data->col; ++j) {
                lo = fgetc(pgmFile);
                data->matrix[i][j] = lo;
            }

    fclose(pgmFile);
    return data;

}
 /*and for writing*/

void writePGM(const char *filename, const PGMData *data)
{
    FILE *pgmFile;
    int i, j;
    int hi, lo;

    pgmFile = fopen(filename, "wb");
    if (pgmFile == NULL) {
        perror("cannot open file to write");
        exit(EXIT_FAILURE);
    }

    fprintf(pgmFile, "P5 ");
    fprintf(pgmFile, "%d %d ", data->col, data->row);
    fprintf(pgmFile, "%d ", data->max_gray);

    if (data->max_gray > 255) {
        for (i = 0; i < data->row; ++i) {
            for (j = 0; j < data->col; ++j) {
                hi = HI(data->matrix[i][j]);
                lo = LO(data->matrix[i][j]);
                fputc(hi, pgmFile);
                fputc(lo, pgmFile);
            }

        }
    } else {
        for (i = 0; i < data->row; ++i)
            for (j = 0; j < data->col; ++j) {
                lo = LO(data->matrix[i][j]);
                fputc(lo, pgmFile);
            }
    }

    fclose(pgmFile);
    deallocate_dynamic_matrix(data->matrix, data->row);
}

int main ( int argc, char *argv[] )
{
    PGMData *initialImage, *finalImage;
    int **initialMatrix=NULL, **finalMatrix=NULL;
    int n=atoi(argv[4]);
    int i, j, k, l, counter;
    int *buffer=NULL;
    //Time count
    clock_t start, end;
    double cpu_time_used;

    start = clock();
    if ( argc != 5 ) /* argc should be 5 for correct execution */
    {
        /* We print argv[0] assuming it is the program name */
        printf( "usage: %s filename", argv[0] );
    }
    else
    {
        // We assume argv[1] is a filename to open
        FILE *file = fopen( argv[1], "r" );

        /* fopen returns 0, the NULL pointer, on failure */
        if ( !file )
        {
            printf( "Could not open file\n" );
        }
        else
        {   initialImage = (PGMData *)malloc(1 * sizeof(PGMData));
            initialImage = readPGM (file, initialImage);
            initialMatrix = (int **)malloc(initialImage->row * sizeof(int*));
            for(i = 0; i < initialImage->row; i++) {
                initialMatrix[i] = (int *)malloc(initialImage->col * sizeof(int));
            }
            finalMatrix = (int **)malloc(initialImage->row * sizeof(int*));
            for(i = 0; i < initialImage->row; i++) {
                finalMatrix[i] = (int *)malloc(initialImage->col * sizeof(int));
            }
            if (initialMatrix == NULL || finalMatrix == NULL) {
                puts ("Unable to allocate memory for matrix");
            }
            for (i = 0; i < initialImage->row; i++){
                for (j = 0; j < initialImage->col; j++){
                    initialMatrix[i][j] = initialImage->matrix[i][j];
                }
            }
            buffer = (int *) malloc(n * n * sizeof (int));
            if (buffer == NULL) {
                puts ("Unable to allocate memory for buffer");
            }
            for (i = 0; i < initialImage->row; i++){
                for (j = 0; j < initialImage->col; j++){
                    counter = 0;
                    for (k = -(n/2); k <= n/2; k++){
                        for (l = -(n/2); l <= n/2; l++){
    /*top left corner*/     if (i-k <= 0 && j-l <= 0) {
                                buffer[counter]=initialMatrix[0][0];
                            }
    /*left side*/       else if (i-k <= 0 && j-l >= 0 && j-l <= initialImage->col-1) {
                                buffer[counter]=initialMatrix[0][j-l];
                            }
    /*top side*/       else if (j-l <= 0 && i-k >= 0 && i-k <= initialImage->row-1) {
                                buffer[counter]=initialMatrix[i-k][0];
                            }
    /*bottom left corner*/     else if (j-l <= 0 && i-k >= initialImage->row-1) {
                                buffer[counter]=initialMatrix[initialImage->row-1][0];
                            }
    /*top right corner*/    else if (i-k <= 0 && j-l >= initialImage->col-1) {
                                buffer[counter]=initialMatrix[0][initialImage->col-1];
                            }
    /*bottom side*/       else if (i-k >= initialImage->row-1 && j-l >= 0 && j-l <=initialImage->col-1) {
                                buffer[counter]=initialMatrix[initialImage->row-1][j-l];
                            }
    /*right side*/  else if (j-l >= initialImage->col-1 && i-k >= 0 && i-k <=initialImage->row-1) {
                                buffer[counter]=initialMatrix[i-k][initialImage->col-1];
                            }
    /*bottom right corner*/   else if (j-l >= initialImage->col-1 && i-k >= initialImage->row-1) {
                                buffer[counter]=initialMatrix[initialImage->row-1][initialImage->col-1];
                            }
    /*rest*/              else {
                                buffer[counter]=initialMatrix[i-k][j-l];
                            }
                            counter++;
                        }
                    }
                    if(!strcmp(argv[3], "ins")) {
                        insertion_sort (buffer, n*n);
                    }
                    else if(!strcmp(argv[3], "qs")) {
                        quick_sort (buffer, n*n);
                    }
                    else if(!strcmp(argv[3], "cnt")) {
                        counting_sort (buffer, n*n);
                    }
                    else {
                        puts ("Unknown sorting algorithm");
                    }
                    finalMatrix[i][j] = buffer [n * n/2];
                }
            }
            finalImage = (PGMData *)malloc(1 * sizeof(PGMData));
            finalImage->col=initialImage->col;
            finalImage->row=initialImage->row;
            finalImage->max_gray = initialImage->max_gray;
            finalImage->matrix = finalMatrix;
            writePGM (argv[2], finalImage);
            deallocate_dynamic_matrix(initialMatrix, initialImage->row);
            deallocate_dynamic_matrix(initialImage->matrix, initialImage->row);
            free(buffer);
            free(initialImage);
            free(finalImage);
        }
    }
    end = clock();
    cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
    printf ("Execution time: %f seconds\n", cpu_time_used);
}

0 个答案:

没有答案