Псевдокод: Как декодировать файл PNG из битов и байтов? - PullRequest
0 голосов
/ 01 июня 2018

Я пытался понять это путем обратного инжиниринга файла .png, который я создал в GIMP.Это 4х4 пикселей.Моя цель состоит в том, чтобы декодировать необработанные пиксели из файла с намерением изменить это для кодирования.

Вот полный шестнадцатеричный дамп файла:

89504E47 0D0A1A0A 0000000D 49484452 00000004 00000004  
08020000 00269309 29000000 3F494441 54081D01 3400CBFF  
01CC96B1 134FE120 C0CECDF1 5101FFA5 60000000 000000E0  
403201DF E59286DF 6D000000 00000004 EDB11F00 2E007A21  
93EDB11F 3063136F 4733525A 00000000 49454E44 AE426082  

Согласно spec , мы начинаем с подписи PNG, которая является первыми 8 байтами.

89504E47 0D0A1A0A

Затем мы имеем повторяющиеся структуры «чанков», этот файл содержит 3 «чанков», заголовок (IHDR), данные изображения (IDAT) изатем конец "кусок" (IEND).

Каждый фрагмент размещается в: первые 4 байта для длины данных фрагмента, следующие 4 байта для типа данных, затем n байтов для фактических данных и затем 4 байта для циклической избыточностипроверка (CRC) типа данных и фактических данных разделов.

После этого через ...

0000000D

Длина данных куска (13 байтов).

49484452

Тип чанка (IHDR).

00000004 00000004 08020000 00

Является ли данные чанка (ширина 4 байта, высота; глубина в 1 байт, тип цвета, метод сжатия, метод фильтра, метод чересстрочной развертки),

269309 29

Является ли CRC данных и типа (удалось получить код для обработки этого из здесь .

000000 3F

- длина данных следующего блока (63 байта).

494441 54

- этотип чанка (IDAT).

081D01 3400CBFF 01CC96B1 134FE120 C0CECDF1 5101FFA5 60000000 000000E0 403201DF E59286DF 6D000000 00000004 EDB11F00 2E007A21 9350 * 10 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 10: * *.и отфильтрованы).

Итак, мой реальный вопрос: как мне декодировать этот последний раздел в необработанные пиксели?

Согласно spec , я должен сначала распаковать данные (INFLATE?), А затем отфильтровать его (??), чтобы оставить строки развертки пикселей (моя цель).

Если бы это можно было объяснить в псевдокоде, это было бы удивительно! В противном случае я знаком сБыстро и менее с C ...

Ответы [ 3 ]

0 голосов
/ 01 июня 2018

Ваш вопрос слишком широк для псевдокода - или, по крайней мере, для действующего псевдокода - если мы перейдем на достаточно высокий уровень, вы уже знаете основы: 1. распаковка, 2. нефильтрование, 3. прибыль.

Поскольку вы заявляете в комментариях, что хотите сделать все самостоятельно, я предлагаю начать с реализации алгоритма декомпрессии по умолчанию, ZLIB CM = 8 «deflate», который хорошо описан в https://www.ietf.org/rfc/rfc1951.txt среди других.

0 голосов
/ 05 июня 2018

Эта книга объясняет процесс декодирования для программистов:

https://www.amazon.com/Compressed-Image-File-Formats-JPEG/dp/0201604434

Весь процесс сложен, чтобы вписаться в пространство SO-ответа.PNG использует два разных метода сжатия: LZ и кодирование Хаффмана.

0 голосов
/ 01 июня 2018

Я думаю, pngcheck значительно поможет вам:

pngcheck -vv result.png

Пример вывода

File: result.png (334985 bytes)
  chunk IHDR at offset 0x0000c, length 13
    600 x 450 image, 24-bit RGB, non-interlaced
  chunk IDAT at offset 0x00025, length 65536
    zlib: deflated, 32K window, default compression
    row filters (0 none, 1 sub, 2 up, 3 avg, 4 paeth):
      1 4 4 4 4 4 4 4 1 4 4 4 4 4 4 4 1 4 4 4 4 4 4 4 4
      1 4 4 1 4 1 4 1 4 4 4 4 4 4 1 1 1 1 1 1 1 1 1 1 1
      1 1 1 1 1 1 1 1 1 4 4 1 1 1 1 1 1 1 4 4 1 4 1 1 4
      4 4 4 4 4 1 4 4 4 4 4 4 4 1 4 4 4 4 4 4 4 (96 out of 450)
  chunk IDAT at offset 0x10031, length 65536
    row filters (0 none, 1 sub, 2 up, 3 avg, 4 paeth):
      1 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 1
      4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
      4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 1 4 4
      4 4 4 4 4 4 4 4 4 4 4 4 4 1 4 4 4 (188 out of 450)
  chunk IDAT at offset 0x2003d, length 65536
    row filters (0 none, 1 sub, 2 up, 3 avg, 4 paeth):
      4 4 4 4 4 4 4 4 4 4 4 4 1 4 4 4 4 4 4 4 4 4 4 4 4
      4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
      4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
      4 1 4 4 4 4 4 4 4 4 (273 out of 450)
  chunk IDAT at offset 0x30049, length 65536
    row filters (0 none, 1 sub, 2 up, 3 avg, 4 paeth):
      4 4 4 4 4 4 4 4 4 2 4 4 4 4 4 1 4 4 4 4 4 4 4 4 4
      4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
      4 4 4 4 4 4 4 4 4 4 4 4 4 1 4 4 4 4 4 4 4 1 4 4 4
      4 4 4 4 1 4 4 4 (356 out of 450)
  chunk IDAT at offset 0x40055, length 65536
    row filters (0 none, 1 sub, 2 up, 3 avg, 4 paeth):
      4 4 4 4 1 4 4 4 4 4 4 4 1 4 4 4 4 4 4 4 4 4 4 4 4
      4 4 4 1 4 4 4 4 4 4 4 1 1 1 4 4 1 4 4 1 1 1 4 4 4
      4 4 1 1 1 4 1 4 4 4 1 4 1 4 4 4 1 4 1 4 4 4 4 4 4
      4 1 1 4 1 4 4 1 4 1 (441 out of 450)
  chunk IDAT at offset 0x50061, length 7188
    row filters (0 none, 1 sub, 2 up, 3 avg, 4 paeth):
      4 1 1 4 4 4 4 1 4 (450 out of 450)
  chunk IEND at offset 0x51c81, length 0
No errors detected in result.png (8 chunks, 58.6% compression).
...