Учитывая файл изображения и pixel_array_offset, как инициализировать фактические значения структуры пикселей? - PullRequest
0 голосов
/ 09 февраля 2019

Следуя этому требованию

Мне также нужно вернуть адрес первого "struct pixel *".Не уверен, правильно ли я его реализую.

struct pixel **read_pixel_array(FILE *image, int pixel_array_offset, int width, int height) {

    struct pixel **ptrs = malloc(height * sizeof(struct pixel));

    struct pixel *first_pixel;
    fseek(image, pixel_array_offset, SEEK_SET);

    for (int i=0, i<height, i++) {
        ptrs[i] = malloc(width * sizeof(struct pixel));
        for (int j=0, j<width, j++) {
            fread(ptrs[i][j]->blue, 1, 1, image);
            fread(ptrs[i][j]->green, 1, 1, image);
            fread(ptrs[i][j]->red, 1, 1, image);
        }

    }

    fseek(image, pixel_array_offset, SEEK_SET);
    fread(first_pixel, 3, 1, image);

    return &first_pixel;

}

1 Ответ

0 голосов
/ 09 февраля 2019

Вы хотите выяснить, как вы хотите хранить данные пикселей в оперативной памяти.В частности, вы хотите:

  • 1-мерный массив «указателей на 1-мерный массив пикселей» для каждой строки
  • 2-мерный массив пикселей
  • что-то еще

Ваш код выглядит так, как будто он пытается выполнить первый вариант (и выглядит так, будто он делает это неправильно - например, malloc(height * sizeof(struct pixel));, когда он должен быть malloc(height * sizeof(struct pixel *));. Однако ваш код также выглядит так, как будто онпытаясь сделать второй вариант (например, ptrs[i][j]->blue, а не row = ptrs[i]; и row[j]->blue).

Для первого варианта (одномерный массив указателей) это будет выглядеть так:

struct pixel **read_pixel_array(FILE *image, int pixel_array_offset, int width, int height) {

    struct pixel **ptrs;
    struct pixel *row;

    ptrs = malloc(height * sizeof(struct pixel *));
    if(ptrs == NULL) {
        // Failed to allocate memory for array of pointers
        return NULL;
    }

    fseek(image, pixel_array_offset, SEEK_SET);

    for (int i=0, i<height, i++) {
        row = malloc(width * sizeof(struct pixel));
        if(row == NULL) {
            // Failed to allocate memory for row. Need to free everything
            //   that was previously allocated to avoid memory leaks
            while(i > 0) {
                i--;
                free(ptrs[i]);
            }
            free(ptrs);
            return NULL;
        }
        ptrs[i] = row;
        for (int j=0, j<width, j++) {
            fread(row[j]->blue, 1, 1, image);
            fread(row[j]->green, 1, 1, image);
            fread(row[j]->red, 1, 1, image);
        }
    }
    return ptrs;
}

Сам я бы использовал второй вариант (один 2D-массив), потому что он проще и быстрее. Проблема в том, что C не знает размеры во время компиляции, поэтому вам нужно использовать чит-код и использовать реализованный 2D-массивкак массив 1D ". В этом случае это будет выглядеть так:

struct pixel *read_pixel_array(FILE *image, int pixel_array_offset, int width, int height) {
    struct pixel *myArray;

    myArray = malloc(height * width * sizeof(struct pixel));
    if(myArray == NULL) {
        // Failed to allocate memory
        return NULL;
    }

    fseek(image, pixel_array_offset, SEEK_SET);

    for (int i=0, i<height, i++) {
        for (int j=0, j<width, j++) {
            fread(myArray [i*width + j]->blue, 1, 1, image);
            fread(myArray [i*width + j]->green, 1, 1, image);
            fread(myArray [i*width + j]->red, 1, 1, image);
        }
    }
    return myArray;
}

ПРИМЕЧАНИЕ. Ни один из этих примеров не был проверен, и ни один из них не может считаться" правильным "без тестирования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...