Я работаю над некоторым кодом, который создает простые файлы PNG на основе палитры без libpng. Выходной файл на этом этапе содержит только блоки IHDR, PLTE, IDAT (x3) и IEND. Единственное, что, возможно, немного отличается тем, что значения индекса пикселя в блоке IDAT не сжаты, то есть различные байты заголовка zlib/block следующие.Палитра базы PNG с IDAT, которая имеет BTYPE = 00 без сжатия, теперь с кодом Adler32
- CMF = 0x78.
- FLG = 0x9C (здесь также есть несколько других значений, но всегда с четностью 5).
- Заголовок блока байта = 0x01 (BFINAL = 1, BTYPE = 00).
Из того, что я вижу, код правильно строит файл, однако некоторые зрители изображений отказываются отображать изображение полностью, если вообще.
- MS Paint счастлив.
- GIMP счастлив.
- LibreOffice Draw счастлив.
- Ristretto >> Неустранимая ошибка чтения файла изображения PNG: недостаточно сжатых данных.
- ImageMagick >> определить: недостаточно данных изображения `20160317_PNG_064.png '@ error/png.c/MagickPNGErrorHandler/1645.
- Eye of Gnome >> недостаточно данных изображения.
Я положил файл через несколько разных инструментов, снова со смешанными результатами.
- optipng >> не хватает данные изображения.
- pngchunks не сообщает об ошибках.
- pngcheck не сообщает о каких-либо ошибках.
Вот hex view of the file 20160317_PNG_064.png
Картину он генерирует этот small 8x8 pixel image.
Так что я нахожусь в тупике относительно того, что попробовать дальше. Приветствуется всяческая помощь.
EDIT_000 Усугубляя проблему при расчете Adler32, здесь, по просьбе @Mark Adler, используется код, который я использую для вычисления значения Adler32 с тестовыми данными в основной функции. Кстати, это не фантазия, и я кодирую очень многословную.
#include <stdio.h>
#define DEBUG
static const unsigned long GC_ADLER32_BASE = 0xFFF1; // Largest prime smaller than 65536 is 65521.
unsigned long Adler32_Update
(
unsigned long Adler32,
unsigned char *Buffer,
unsigned int BufferLength
)
{
unsigned long ulW0;
unsigned long ulW1;
unsigned int uiW0;
#ifdef DEBUG
printf("\n");
printf(" Incoming Adler32 value.................0x%.8X\n", Adler32);
#endif
ulW0 = Adler32 & 0xFFFF;
ulW1 = (Adler32 >> 0x0010) & 0xFFFF;
#ifdef DEBUG
printf(" Inital sum values are..................0x%.8X, 0x%.8X\n", ulW0, ulW1);
#endif
for (uiW0 = 0x0000; uiW0 < BufferLength; uiW0 = uiW0 + 0x0001)
{
ulW0 = (ulW0 + Buffer[uiW0]) % GC_ADLER32_BASE;
ulW1 = (ulW1 + ulW0) % GC_ADLER32_BASE;
}
#ifdef DEBUG
printf(" Final sum values are...................0x%.8X, 0x%.8X\n", ulW0, ulW1);
#endif
Adler32 = (ulW1 << 0x0010) | ulW0;
#ifdef DEBUG
printf(" Outgoing Adler32 value.................0x%.8X\n", Adler32);
#endif
return (Adler32);
}
unsigned long Adler32_Get
(
unsigned char *Buffer,
unsigned int BufferLength
)
{
unsigned long Adler32;
Adler32 = 0x00000001L;
Adler32 = Adler32_Update(Adler32, Buffer, BufferLength);
return (Adler32);
}
int main
(
unsigned int argc,
unsigned char *arg[]
)
{
unsigned long Adler32;
unsigned char data[272] =
{
0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01,
0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01,
0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01,
0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x00,
0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02
};
Adler32 = Adler32_Get(data, sizeof(data));
printf("\n");
printf("The Adler32 value is ..........................0x%.8X\n", Adler32);
return(0x00);
}
Вы уверены, что ваш кусок 'data' представляет распакованные данные в том же образом? Изображение палитры 8x8 должно быть, если я правильно его вычислил, 8x8 = 64 байта. Каждая строка имеет перед ним фильтр-байт, который добавляет до 72 байт. Если я разделяю ваши данные вверх в строках, начинающихся с байта фильтра '0', я получаю 16 x 16 изображений (которые, плюс 16 строк фильтров, добавляет до 272 показано здесь). – usr2564301
(После тестирования) Yup. Если я загружаю исходные 72 байта в текущую процедуру Adler32, я получаю значение Outgoing Adler32 ................. 0x10080061' - * точно * что dr. Адлер рассчитал. Поэтому ваша рутина кажется правильной в конце концов, вы просто применяли ее к неправильному набору данных. – usr2564301