Поскольку я мазохист, я пытаюсь написать что-то на C, чтобы декодировать 8-битный файл PNG (это учебная вещь, я не пытаюсь изобретать libpng ...)
IДошло до того, что материал в моем дефлированном, нефильтрованном буфере данных безошибочно напоминает исходное изображение (см. ниже), но он все еще довольно ошибочен, и я почти уверен, что с моей реализацией * что-то искажается1003 * алгоритмы фильтрации .Большинство из них довольно просты, но есть одна важная вещь, которую я не понимаю в документах : не очень хорошо разбираться в математике или когда-либо проходить курс компьютерной науки:
Используется арифметика без знака по модулю 256, так что и входы, и выходы помещаются в байты.
Что это значит ?
Если кто-то может сказать мнечто я был бы очень благодарен!
Для справки (и я извиняюсь за дерьмовый C) моя неряшливая реализация алгоритмов фильтрации, описанных в документах , выглядит как :
unsigned char paeth_predictor (unsigned char a, unsigned char b, unsigned char c) {
// a = left, b = above, c = upper left
char p = a + b - c; // initial estimate
char pa = abs(p - a); // distances to a, b, c
char pb = abs(p - b);
char pc = abs(p - c);
// return nearest of a,b,c,
// breaking ties in order a,b,c.
if (pa <= pb && pa <= pc) return a;
else if (pb <= pc) return b;
else return c;
}
void unfilter_sub(char* out, char* in, int bpp, int row, int rowlen) {
for (int i = 0; i < rowlen; i++)
out[i] = in[i] + (i < bpp ? 0 : out[i-bpp]);
}
void unfilter_up(char* out, char* in, int bpp, int row, int rowlen) {
for (int i = 0; i < rowlen; i++)
out[i] = in[i] + (row == 0 ? 0 : out[i-rowlen]);
}
void unfilter_paeth(char* out, char* in, int bpp, int row, int rowlen) {
char a, b, c;
for (int i = 0; i < rowlen; i++) {
a = i < bpp ? 0 : out[i - bpp];
b = row < 1 ? 0 : out[i - rowlen];
c = i < bpp ? 0 : (row == 0 ? 0 : out[i - rowlen - bpp]);
out[i] = in[i] + paeth_predictor(a, b, c);
}
}
И изображения, которые я вижу:
Источник
Источник http://img220.imageshack.us/img220/8111/testdn.png
Выход
Выход http://img862.imageshack.us/img862/2963/helloworld.png