Чтение данных пикселей файла PPM с использованием C - PullRequest
0 голосов
/ 18 марта 2012

Я пытаюсь прочитать данные пикселей из файла PPM.У меня есть функция для чтения заголовка, так что я знаю, что он указывает на начало данных пикселей.Я попытался использовать fgetc (файл), но если значение больше одной цифры, оно не будет работать.Я также попытался использовать массив и преобразовать массив в int или char, но у меня нет никакого способа узнать, сколько цифр у каждого значения.Я также не уверен, если значения разделены пробелами или нет.В основном мне нужен способ извлечь данные пикселей.(Я использую C.)

Мой код прямо сейчас:

char read_byte(FILE *ipt) {
    int c, i=0, sum=0;
    while (i<16) {
        c=fgetc(ipt);
        if((i%2)!=0 {
            if(c&1) {
                sum+=pow(2,i/2);
            }
        }
        i++;
    }
    return (char)sum;
}

РЕДАКТИРОВАТЬ: Сначала я думал, что файл был сохранен как значения ASCII, затем я понял, что он хранится какдвоичный файл.Прямо сейчас я думаю, что заставляю это действовать как гекс.Я не уверен, что это правильно.Я действительно застрял.

РЕДАКТИРОВАТЬ: немного изменил мой код

char read_byte(FILE *ipt) {
    int c, i=0, sum=0;
    while(i<8) {
        c = fgetc(ipt);
        c=c&1;
        sum+=c*pow(2,i);
        i++;
    }
    return sum;
}

Я печатаю сумму как% c

1 Ответ

1 голос
/ 18 марта 2012

Должны ли вы написать это для задания, или это для удовольствия, или вы могли бы использовать чужой код?

Существует решение с открытым исходным кодом.«Netpbm - это пакет графических программ и библиотека программирования.», Которая включает в себя программы для чтения PPM на http://netpbm.sourceforge.net/doc/

Редактировать: Вы получили или прочитали определение формата файла, например, http://netpbm.sourceforge.net/doc/ppm.html?

Похоже, что данные представляют собой либо последовательности трехбайтовых RGB-троек, либо последовательности двухбайтовых RGB-троек.

Программа может определить, какой формат используется из пункта 7 «Максимальное значение цвета (Maxval)».Там написано: «Если Maxval меньше 256, это 1 байт. В противном случае это 2 байта».

Таким образом, вы кодируете функцию, которая читает данные RGB одного байта / компонента, а затем кодируете другую, чтобы прочитать данные RGB двух байтов / компонента.

Программа может выбрать, какой вызов вызывать после прочтения значения Maxval.

Редактировать {

Согласно документу по этой ссылке, данные изображения в виде 'P6 'ppm является двоичным.

Таким образом, если MaxValue <256 и, следовательно, данные для каждого компонента цвета составляют один байт, то чтение трех байтов с тремя вызовами fgetc (fp) вернет двоичное значение одного пикселя RGB. </p>

Если программа прочитала заголовок, он имеет значения ширины и высоты для данных изображения.Таким образом, он может выделить массив для каждой строки (ширина по ширине пикселей RGB) и массив указателей на каждый выделенный массив строк пикселей.Затем считайте двоичные данные в каждую строку, и программе есть что-то простое для работы;2d массив.

} end edit

Мое чтение вашего вопроса показывает, что вы уже знаете, как читать однобайтовые данные, используя fgetc.

Редактировать - кажется, что это не имеет значения: вы можете прочитать двухбайтовые данные, дважды вызвав fgetc и сдвигая и разбивая данные, например (частично игнорируя проверку ошибок):

int a = fgetc(fp);
int b = fgetc(fp);
if (a >= 0 && b >= 0) { // then all is okay
    unsigned int twobyte = (a<<8) | b; // or (b<<8) | a; depending on byte order
// ...
...