4.2 Формат графических файлов – PNG

Формат PNG предназначен для хранения и передачи растровых изображений. Он позволяет хранить изображения, битовая глубина которых достигает 16 (в шкале серого цвета) или 48 (в truecolor-изображениях) битов на пиксель, а также 16 битов альфа-данных. Этот формат обеспечивает также поэтапное отображение данных изображения, хранение информации о прозрачности, а также осуществляет кодирование текстовой информации. В нем используется метод сжатия данных без потерь.

PNG — новый формат, ориентированный на специалистов в области компьютерной графики. Он разработан как альтернатива формату GIF (Graphics Interchange Format), использование которого разработчиками электронных публикаций и графических изображений сопряжено с предварительной оплатой предстоящей реализации изображений в этом формате (лицензирование). Лицензии должны приобретаться и на распространение программ, которые читают или записывают файлы в формате GIF.

Мобильный и несложный для реализации формат PNG по основным функциональным возможностям превосходит формат GIF. PNG должен распространяться бесплатно, что позволит избежать бремени лицензионных платежей и патентных споров с разработчиками формата.

PNG и GIF89a обладают общими признаками:

- Форматы организованы в виде потока данных.

- Обеспечивается сжатие данных изображения без потерь.

- Поддерживается хранение индексированных изображений, содержащих до 256 цветов.

- Обеспечивается поэтапное отображение с чересстрочной разверткой.

- Поддерживается прозрачность основного цвета.

- Имеется возможность хранить общедоступные и частные пользовательские данные.

- Оба формата независимы от аппаратных средств и операционной системы.

Вместе с тем, формат PNG наделен более широкими функциональными возможностями по сравнению с форматом GIF, например:

- Не обремененный юридическими проблемами метод сжатия данных.

- Более высокая скорость поэтапного отображения с чересстрочной разверткой.

- Расширенные возможности хранения пользовательских данных.

- Хранение truecolor-изображений глубиной до 48 битов на пиксель.

-  Хранение изображений в шкале серого цвета глубиной до 16 битов на пиксель.

- Полный альфа-канал.

-  Гамма-индикатор.

-  CRC-метод выявления разрушения потока данных.

-  Стандартный инструментарий для реализации программ чтения и записи PNG.

-  Стандартный набор эталонных изображений для тестирования программ чтения PNG.

Вместе с тем, формат PNG v1.0 пока не обладает:

- Возможностью записи нескольких изображений, как GIF.

- Отсутствует возможность хранения анимационных последовательностей.

В отличие от большинства графических форматов, PNG разработан специальным комитетом ISO. В его состав вошли специалисты по реализации подобных проектов и, в частности, знакомых с форматом GIF.

Формат PNG предусматривает введение дополнительных функциональных возможностей, что не нарушает его функциональности и не требует доработки уже существующих и работающих с ним программ.

Организация файла PNG

Файл (или поток данных) в формате PNG состоит из 8-байтовой идентификационной подписи и не менее чем трех порций данных. Порция — это независимый блок данных, структура которого определена в спецификации формата. Порции имеют собственный идентификатор, соответствующий внутреннему формату данных, и читаются последовательно от начала до конца файла (потока данных).

Концепция блоков данных, или порций, используется и в других форматах, наиболее известными среди которых являются GIF, IFF и RIFF. Данные в файлах таких форматов обычно читаются последовательно, а их фрагменты не нужно искать по смещениям от начала файла. Подобные форматы хорошо подходят для совместного использования с сетевыми протоколами и протоколами передачи данных и воспринимаются как файловые (хотя точнее было бы рассматривать записанную в таких форматах информацию как поток данных, перенаправленный в файл).

В PNG определены четыре стандартные порции, называемые критическими порциями, которые должны поддерживаться всеми программами чтения и записи формата PNG.

Порция заголовка (IHDR). Содержит основную информацию о данных изображения и должна быть первой. В потоке данных PNG возможна только одна порция заголовка.

Порция палитры (PLTE). Служит для хранения данные цветовой таблицы, связанные с данными изображения. Эта порция присутствует в файле только в том случае, когда данные изображения используют цветовую палитру, и располагается перед порцией данных изображения.

Порция данных изображения (IDAT). Содержит собственно данные изображения. В потоке данных может быть несколько таких порций, которые записываются последовательно одна за другой.

Завершающая порция (IEND). Располагаясь последней, эта порция маркирует конец PNG-файла или потока данных.

Порции IHDR, IDAT и IEND должны присутствовать в каждом потоке данных PNG.

Ниже на рис.6  приведена структура PNG-файлов двух основных типов: с цветовой палитрой (а) и без нее (б).

Подпись

Порция IHDR

Порция IDAT

Порция IEND

а)

Подпись

Порция IHDR

Порция PLTE

Порция IDAT

Порция IEND

б)

Рис. 6 Структура PNG-файлов

Необязательные порции, называемые вспомогательными, программы чтения PNG -файлов могут игнорировать, а программы записи — не записывать. Следует отметить, однако, что если программа чтения не поддерживает эти порции, то в некоторых случаях визуализация записанных в формате PNG изображений может оказаться некорректной. (Изображения воспроизводятся темными или, наоборот, светлыми. Возможны искажения изображения). Поэтому желательно, чтобы программы, использующие формат PNG, обеспечивали интерпретацию большинства стандартных вспомогательных порций (в частности, порции Image Gamma).

Критические и вспомогательные порции, определенные в спецификации PNG, имеют общее название — стандартные порции. Кроме того, существуют дополнительные порции, которые называются общедоступными порциями специального назначения. Они употребляются не столь широко, как стандартные, но все же встречаются в некоторых приложениях. Список общедоступных порций специального назначения время от времени пересматривается и расширяется. В приложениях иногда определяются и так называемые частные порции, которые предназначены для хранения данных, не подлежащих интерпретации другими приложениями.

Ниже в Таблице 1 перечислены стандартные и специальные порции, определенные в спецификации PNG версии 1.0 и в сопутствующей документации. Порции в этом списке следуют в том порядке, в котором они могут появляться в потоке данных PNG.

Таблица 1

Тип порции

Может ли быть несколько

Необязательная или нет

Расположение в файле

IHDR

Нет

Нет

Первая порция

cHRM

Нет

Да

Перед PLTE и IDAT

gAMA

Нет

Да

Перед PLTE и IDAT

sBIT

Нет

Да

Перед PLTE и IDAT

PLTE

Нет

Да

Перед IDAT

bKGD

Нет

Да

После PLTE, перед IDAT

hIST

Нет

Да

После PLTE, перед IDAT

tRNS

Нет

Да

После PLTE, перед IDAT

oFFs

Нет

Да

Перед IDAT

pHYs

Нет

Да

Перед IDAT

sCAL

Нет

Да

Перед IDAT

IDAT

Да

Нет

Одним блоком (без разрывов) с другими IDAT

tIME

Нет

Да

Любое

tEXt

Да

Да

Любое

zTXt

Да

Да

Любое

fRAc

Да

Да

Любое

gIFg

Да

Да

Любое

gIFt

Да

Да

Любое

gIFx

Да

Да

Любое

IEND

Нет

Нет

Последняя порция

Описание файла

Подпись в файле PNG занимает 8 байтов и содержит информацию о соответствии файла или потока данных спецификации PNG:

typedef struct _PngSignature

{

BYTE Signature[8]; /* Идентификатор (всегда 89504E470DOAlAOAh) */ } PNGSIGNATURE;

Подпись содержит значения 89h 50h 4Eh 47h ODh OAh lAh OAh ("PNG\r\n\n"). Эта последовательность выглядит как случайный порядок значений, но имеет важное практическое значение. Первый байт, 89h, представляет собой 8-битовое значение, указывающее на то, что файл содержит двоичные данные. Если по какой-либо причине (например, при пересылке по 7-битовому каналу передачи данных) 8-й бит из файла будет удален, то это значение изменится на 09h, и причина, по которой файл оказался искажен, станет очевидной.

Следующие за ним байты выполняют такие функции:

- Позволяют визуально идентифицировать поток данных PNG (байты 2—4 содержат символы "PNG");

-  Помогают выявить факт пересылки файла по изменению управляющей последовательности новая строка ("\г\п" заменяется на "\г", "\п" или "\п\г");

-  Останавливают распечатку потока данных PNG в операционной системе MS-DOS;

- Позволяют выявить проблемы преобразования символов возврата каретки и перевода строки (последовательности новая строка) при пересылке файлов.

За подписью следуют три или более порции данных PNG. Все порции имеют одинаковый базовый формат и могут содержать блоки данных переменной длины:

typedef struct PngChunk

(

DWORD DataLength; /* Размер поля Data в байтах */

DWORD Type; /* Код, идентифицирующий тип порции */

BYTE Data[]; /* Блок данных, хранящийся в этой порции */

DWORD Crc; /* Значение 32-битовой контрольной суммы для полей Type и Data */ } PNGCHUNK;

Значение поля DataLength соответствует количеству байтов, записанных в поле Data. Диапазон значений этого поля — от 0 до 231-1.

Значение поля Type — это 4-байтовый код типа данных, хранящихся в порции. Каждый байт этого поля может содержать ASCII-код прописной или строчной буквы (AZ, az). Например, порция IHDR идентифицируется записанным в поле Type значением 69484452h (iHDR). Однако программы чтения файлов PNG должны трактовать коды типа порции как 32-битовые буквальные значения, а не как символьные строки. Как известно пользователю удобнее читать коды типа в текстовой форме.

В поле Data хранятся данные порции. Если данных в порции нет, то это поле имеет нулевую длину.

Поле Сrс содержит значение 32-битовой контрольной суммы (CRC-32), вычисленное для полей Type и Data, и используется для проверки достоверности данных порции. В формате PNG применяется алгоритм CRC, определенный стандартами ISO 3309 и ITU-T V.42.

Размер порции зависит от размера хранящихся в ней данных и может изменяться в пределах от 12 байтов (если данных нет) до (231—1)4-12 байтов (максимально возможный объем данных). Порции всегда выравниваются по границам байтов, поэтому заполнитель не требуется.

Критические порции

Ниже приведены стандартные порции, которые должны поддерживаться всеми программами чтения и записи файлов PNG.

Порция заголовка.  Порция заголовка содержит информацию о данных изображения, записанных в файле PNG. Эта порция, следуя первой в потоке данных, располагается непосредственно за подписью. Ее длина равна 13 байтам, а формат приведен ниже:

typedef struct _IHDRChunk

{

DWORD Width; /* Ширина изображения в пикселях */

DWORD Height; /* Высота изображения в пикселях */

BYTE BitDepth; /* Количество битов на пиксель или выборку */

BYTE ColorType; /* Индикатор интерпретации цвета */

BYTE Compression; /* Индикатор типа сжатия */

BYTE Filter; /* Индикатор типа фильтра */

BYTE Interlace; /* Тип используемой схемы чередования */ ) IHDRCHUNK;

Поля Width и Height указывают ширину и высоту растрового изображения в пикселях. Каждое из этих полей должно содержать значение в диапазоне от 1 до 231-1.

Поле BitDepth определяет количество битов на пиксель (для индексированных цветных изображений) или на выборку (для изображений в шкале серого цвета и truecolor-изображений). В случае индексированных цветных изображениях BitDepth может принимать значения 1, 2, 4 или 8, а в случае изображений в шкале серого цвета — 1, 2, 4, 8 или 16. Для truecolor-изображений (с альфа-данными или без них) и изображений в шкале серого цвета с альфа-данными поддерживаются только два значения — 8 и 16.

Поле ColorType указывает, как интерпретируются данные изображения. Допустимыми значениями являются 0 (в градациях серого), 2 (truecolor), 3 (индексированное цветное), 4 (в градациях серого с альфа-данными) и 6 (truecolor с альфа-данными).

Поле Compression содержит индикатор типа сжатия данных изображения. В настоящее время единственным допустимым значением этого поля является 0, что соответствует методу сжатия Deflate

В поле Filter хранится индикатор способа фильтрации данных изображения перед сжатием. В настоящее время единственное допустимое значение этого поля — 0 (адаптивные методы фильтрации). Значение этого поля никак не сообщает о самом факте фильтрации; его может подтвердить только байт типа фильтра в начале каждой строки развертки. Фильтрация данных изображения перед их сжатием не обязательна.

Поле Interlace указывает алгоритм чередования, используемый для хранения данных изображения или, точнее, порядок передачи пиксельных данных. Для этого поля определены два значения: 0 (без чередования) и 1 (чередование по алгоритму Adam7).

Порция палитры. Порция палитры (PLTE) присутствует в потоках данных PNG, содержащих данные индексированных цветных изображений. При наличии палитры значение поля Color порции заголовка равно 3. Потоки данных PNG truecolor-изображений (в этом случае поле Color принимает значение 2 или 6) также могут содержать порцию палитры, которую программы отображения "не truecolor''-изображений будут использовать для квантования данных. В потоке данных PNG может присутствовать только одна порция палитры.

Порция палитры имеет длину от 3 до 768 байтов и следующий формат:

typedef struct _PLTEChunkEntry {

BYTE Red; /*Красная составляющая (0 = черный, 255 = максимум)*/

BYTE Green; /*3еленая составляющая (0 = черный, 255 = максимум)*/

BYTE Blue; /*Синяя составляющая (0 = черный, 255 = максимум)*/

} PLTECHUNKENTRY;

PLTECHUNKENTRY PLTEChunk[];

PLTEChunk — это массив, содержащий от 1 до 256 элементов PLTECHUNKENTRY. Каждый такой элемент состоит из трех полей: Red, Green и Blue, в которых хранятся значения красной, зеленой и синей составляющих для данного элемента палитры.

Порция данных изображения. Собственно данные изображения хранятся в порции IDAT, причем, в соответствии со спецификацией PNG, всегда в сжатом виде. Хранение в нескольких последовательных порциях IDAT облегчает буферизацию сжатых данных изображения. В потоке сжатых данных нет границ, поэтому порция IDAT может иметь размер от 0 до 231-1 байтов.

Завершающая порция изображения. Последней в потоке данных PNG всегда располагается завершающая порция изображения IEND. Никаких данных она не содержит.

Вспомогательные порции

В формате PNG v1.0 определены 10 вспомогательных порций, которые могут встречаться в потоке данных PNG. Некоторые из них содержат информацию, необходимую для правильной интерпретации данных изображения (например, порцию Image Gamma). Ниже приведено описание формата поля Data для некоторых из этих порций.

Порция Background Color. Порция Background Color задает цвет фона изображения. Следует отметить, что программы чтения файлов PNG часто игнорируют эту порцию и устанавливают цвет фона по своему выбору.

Формат данных порции цвета фона определяется форматом данных изображения (а точнее, значением поля ColorType порции IHDR). В индексированном цветном изображении (ColorType = 3) эта порция содержит 1 байт, который соответствует индексу цвета фона в палитре:

typedef struct _bKGDChunkEntry

{

BYTE Index; /* Индекс цвета фона в палитре */ } BKGDCHUNKENTRY;

Для данных в градациях серого (как с данными альфа-канала, так и без них; ColorType = 0 или 4) в этой порции хранится 2-байтовое значение, которое задает уровень яркости серого цвета фона:

typedef struct _bKGDChunkEntry

(

WORD Value; /* Значение уровня фона */ } BKGDCHUNKENTRY;

Для truecolor-изображений (как с данными альфа-канала, так и без них; ColorType = 2 или 6) в порции цвета фона хранятся три 2-байтовых значения, которые задают RGB-цвет фона:

typedef struct _bKGDChunkEntry

{

WORD Red; /* Выборка красной составляющей цвета фона */

WORD Green; /* Выборка зеленой составляющей цвета фона */

WORD Blue; /* Выборка синей составляющей цвета фона */ } BKGDCHUNKENTRY;

Порция Primary Chromaticities and White Point. В порции Primary Chromaticities and White Point (основные цвета и белая точка) хранятся RGB-значения на базе цветового пространства 1931 CIE XYZ. Основные цвета задаются значениями координат х и у, умноженными на 100000.

typedef struct _cHRMChunkEntry

(

DWORD WhitePointX; /* х-значение белой точки */

DWORD WhitePointY; /* у-значение белой точки */

DWORD RedX; /* х-значение красной составляющей */

DWORD RedY; /* у-значение красной составляющей */

DWORD GreenX; /* х-значение зеленой составляющей */

DWORD GreenY; /* у-значение зеленой составляющей */

DWORD BlueX; /* х-значение синей составляющей */

DWORD BlueY; /* у-значение синей составляющей */ } CHRMCHUNKENTRY;

Порция Image Gamma. В порции Image Gamma (показатель гамма) хранится первоначальное значение показателя гамма относительно исходной сцены, умноженное на 100000. Отметим, что авторы PNG настоятельно рекомендуют реализовать эту порцию в декодерах.

typedef struct _gAMAChunkEntry

{

DWORD Gamma; /* Показатель гамма */ } GAMACHUNKENTRY;

Порция Image Histogram. В порции Image Histogram (гистограмма изображения) хранятся данные о приблизительной частоте использования каждого цвета палитры. Эта порция содержит массив 2-байтовых элементов, каждый из которых соответствует элементу палитры.

typedef struct _hISTChunkEntry

(

WORD Histogram[]; /* Данные гистограммы */ } HISTCHUNKENTRY;

Сжатие данных

Данные PNG-изображений всегда хранятся в сжатом виде. Для сжатия используется схема прогнозирования пиксельных значений с применением одного из вариантов метода Deflate. Алгоритм Deflate (создан Филом Кацем) используется в утилите архивации файлов pkzip. Этот метод сжатия без потерь обладает высокой скоростью кодирования/декодирования, хорошо документирован и распространяется бесплатно. Он поддерживается большинством платформ и операционных систем.

Deflate представляет собой разновидность метода сжатия LZW (запатентованного в 1981 году). В Deflate используется скользящее окно переменного размера и сортированные хеш-таблицы, позволяющие идентифицировать комбинации данных и сжимать их по алгоритму Хаффмена. В формате PNG применяется разновидность метода Deflate, в которой сортированные хеш-таблицы не используются, поэтому он не является субъектом патентных притязаний или лицензионных соглашений.

Перед сжатием данные изображения можно профильтровать. Фильтрация нормализует значения байтов в строке развертки, что повышает эффективность алгоритма сжатия Deflate и позволяет значительно уменьшить размер данных.

Все алгоритмы фильтрации применяются к байтам (а не к пикселям) строки развертки. При этом фильтруются и все данные альфа-канала, присутствующие в этой строке. Поскольку применять один алгоритм фильтрации ко всему изображению не всегда эффективно, каждая строка развертки фильтруется отдельно, причем к любой строке может применяться любой фильтр (а может и не применяться вообще).

С данными PNG-изображений обычно используются определенные типы прогнозирующих фильтров. Фильтрация данных осуществляется перед сжатием, а после распаковки выполняется обратная операция, в результате которой восстанавливаются исходные значения данных. Поэтому все фильтры, применяемые в PNG, полностью обратимы и обеспечивают фильтрацию без потерь.

Фильтр Sub фиксирует разность между значением байта текущего пикселя и значением этого же байта в предыдущем пикселе (так называемый прогнозирующий параметр), позволяя дифференцировать одни и те же выборки в пикселях с несколькими выборками. Этот же алгоритм прогнозирования применяется в формате TIFF

В фильтре Up хранится разность между значениями байта текущего пикселя и соответствующего байта пикселя предыдущей строки развертки. В фильтре Average хранится разность между значением текущего пикселя и средним значением пикселей, расположенных над текущим пикселем и слева от него.

Фильтр Path вычисляет значение с помощью линейной функции. В качестве предикатора используются ближайшее левое, верхнее или левое верхнее байтовые значения.

Hosted by uCoz