Получение фрагментов из байтов PNG в C

#arrays #c #image #file #binary

#массивы #c #изображение #файл #двоичный

Вопрос:

Я пытаюсь отделить фрагменты байтов png в C. Согласно Википедии, фрагменты png структурированы с 4 байтами, отображающими длину поступающих данных, 4 байтами, отображающими тип фрагмента, данные длины, описанные ранее, и 4-байтовый crc. Я новичок в C, но хорошо разбираюсь в Python. Так что, если некоторые из моих методов могут выглядеть немного странно или преувеличены, это потому, что я пытался сделать их похожими на вещи, которые я использовал в python. Пожалуйста, поправьте меня, как правильно что-то делать, если вы видите это!

На данный момент я создал структуру с членом int с именем length, двумя массивами символов без знака для type и crc и указателем символа без знака для данных (поскольку длина определяется позже). Мой текущий метод заключается в увеличении сегмента за сегментом в бесконечном цикле, пока я не дойду до конечного фрагмента, после чего я бы прервался. Когда я определяю значения текущего фрагмента, я перераспределяю пространство для временной переменной, чтобы освободить место для нового значения.

Я не знал, как я это сделаю, поскольку длины массивов должны определяться при инициализации, и я не мог найти количество фрагментов в байтах, поскольку его данные не являются известным значением. Итак, в том, что можно было бы назвать небрежным способом, я вроде как попытался заставить это работать как добавление к списку в python, но я не уверен, насколько хорошо это будет работать. Я убедился, что все ошибки компилятора были исправлены, и не ожидал, что это сработает с первого раза, но я ожидал, что это, по крайней мере, даст мне что-то. Тем не менее, это ничего мне не дало. И никакое количество операторов печати мне не помогло, оно никогда ничего не выводило. Я буквально не могу понять, что не так. Это, вероятно, несколько вещей, но я просто не могу понять, хоть убей. Вот мой код на данный момент:

 typedef struct Chunk Chunk;
struct Chunk {
    int length;
    unsigned char type[4];
    unsigned char *data;
    unsigned char crc[4];
};

Chunk* getChunksFromBytes(unsigned char* bytes)
{
    int next_seg = 8;
    int chunks = 0;
    long int size = 1;

    Chunk new_chunk;
    Chunk* file_chunks = (Chunk*) malloc(sizeof(Chunk));
    Chunk* temp = file_chunks;

    unsigned char end_chunk[4] = {'I', 'E', 'N', 'D'};

    while(1){
        new_chunk.length = bytes[next_seg 1] << 24 |
                           bytes[next_seg 2] << 16 |
                           bytes[next_seg 3] << 8 |
                           bytes[next_seg 4];

        new_chunk.type[0] = bytes[next_seg 5];
        new_chunk.type[1] = bytes[next_seg 6];
        new_chunk.type[2] = bytes[next_seg 7];
        new_chunk.type[3] = bytes[next_seg 8];

        if(new_chunk.type == end_chunk) break;

        unsigned char data[new_chunk.length];
        for(int i = 1; i <= new_chunk.length; i  ){
            data[i] = bytes[next_seg 8 i];
        }

        memcpy(new_chunk.data, data, sizeof(data));

        new_chunk.crc[0] = bytes[next_seg new_chunk.length 9];
        new_chunk.crc[1] = bytes[next_seg new_chunk.length 10];
        new_chunk.crc[2] = bytes[next_seg new_chunk.length 11];
        new_chunk.crc[3] = bytes[next_seg new_chunk.length 12];

        next_seg =new_chunk.length 12;
        size  = sizeof(new_chunk) 1;

        temp = realloc(temp, size);
        temp[chunks] = new_chunk;
        chunks  ;
    }

    return temp;
}
  

Комментарии:

1. Используйте malloc() динамическое выделение памяти. tutorialspoint.com/c_standard_library/c_function_malloc.htm

2. @paladin для какой части? вместо чего? вам нужно быть более конкретным.

3. С malloc() помощью вы можете создавать массивы во время выполнения. «Я не знал, как я это сделаю, поскольку длины массивов должны определяться при инициализации …» . Существует множество руководств по использованию malloc() , я предлагаю вам прочитать одно из них.

4. Кстати, если ваш PNG не такой большой, просто скопируйте весь файл в память и управляйте всем файлом, а не копируйте маленькие фрагменты. Используете ли вы Linux в качестве ОС? Если это так, прочитайте также об fmemopen() и open_memstream() .

5. Нет, я имел в виду, что байты, которые я прочитал из файла, разбиты на соответствующие фрагменты, а не то, что я загружаю их по частям. Например, фрагмент IDAT содержит информацию об изображении