Haiku OS

индекс
71,45

Почему векторные иконки Haiku такие компактные?

В Haiku векторные иконки такие компактные, как же так? Вы, наверное, ожидаете какой-нибудь хак, но секрет в том, что HVIF (Haiku Vector Icon Format) довольно прост. Самое главное, что этот формат оптимизирован для иконок. Как только вы соглашаетесь с этим простым предположением, сразу же приходят идеи различных способов оптимизации объёма данных.


Координаты


Например, пусть иконки имеют стандартное разрешение 64x64 пикселей. Было бы хорошо привязать координаты векторного пути к целым числам писклей. Также хорошо бы иметь возможность задавать координаты за границами иконок, поэтому определим диапазон от -32 до +95 пикселей, что уместится всего в 7 бит. Если же координаты не целые числа, или находятся за пределами диапазона [-32, 95], будем использовать 8-й бит, чтобы указать двухбайтную последовательность, которая расширяет диапазон до [-128, 192], а дополнительная точность будет использоваться для дробных значений координат.

Пути


Также полезно подумать и про оптимизацию общей формы векторных путей.
HVIF различает три основных типа: путь командами, путь прямыми линиями и путь только кривыми. Все пути кривыми могут представлять две другие формы путей, но они требуют хранения большого объёма данных, ведь шутка ли, на каждый сегмент требуется аж 6 координат. Если путь включает много прямых участков, или же много горизонтальных и вертикальных линий, будет лучше ассоциировать команды с сегментами, что значительно снижает количество требуемых координат на сегмент. Формат SVG определяет много больше, но ведь как можно обнаружить достаточно четырёх разных команд для путей, которые покрывают все нужды для иконок. Это горизонтальная линия, вертикальная линия, просто линия и кубическая кривая. Первым двум нужна только одна координата (X или Y), так как другая будет неизменной по отношению к предыдущей точке. Произвольная линия потребует 2 координаты, а кривая уже 6. Четыре закодированные команды для путей могут занять два бита, добавим изящество, запишем их отдельно от данных координат, таким образом один байт закодирует до четырех команд. Давайте теперь посчитаем какой объём данных займёт простой прямоугольник с целочисленными координатами:
  • 1 байт чтобы указать количество путей (4)
  • 1 байт для четырех команд пути (2 бита могут остаться неиспользованными, но там есть команда (линия) определяющая первую точку в любом случае)
  • 5 байт для координат (2 байта для первой точки, 3 байта для остальных)

В HVIF осуществляется анализ, какие именно команды использовать при кодировании, чтобы получить минимум данных. Например, если все кривые или все линии, то нет смысла в хранении секции команд.

Флаги


Большинство объектов иконок, кодируются с дополнительным зарезервированным байтом для «флагов», который определяет какие аспекты необходимо хранить в файле. Например, если фигура никогда не будет изменяться — нет смысла хранить матрицу преобразований. В этом случае «пустые метки» для неиспользованных параметров просто будет исключены.

Матрицы


Говоря о матрицах преобразований, следует иметь в виду, что они могут занимать довольно много места, если не предпринимать дополнительных мер.
HVIF использует нормальные аффинные матрицы для преобразований, которые, как правило, кодируются с помощью 6 double (48 байт) или float, если не задумываться о высокой  точности (24 байт). Для дополнительного сокращения затрат на хранение (так как для иконок точность не требуется), HVIF использует свой собственный формат с плавающей точкой, который использует только 3 байта на значение. Так  требуемый объём для матрицы сокращается до 18 байт.
Часто требуется лишь смещать фигуру, а не вращать, скашивать или масштабировать. В этом случае, имеет смысл хранить только смещение, используя тот же формат, что и для координат путей.

Стили


Существуют два вида стилей: просто цвет и градиент. Стиль секции может занимать значительное место, поэтому есть ряд шагов для снижения этого показателя. Цвет или градиент, которые не используют альфа-канал, не кодируется с альфа-каналом, и серый кодируется одним байтом. Какой тип кодирования для цветов используется также определяется байтом флагов любого заданного стиля. Существует также специальный формат для градиентов с двумя цветами, один в 0% и один на 100% смещении (очень распространенный тип градиента), где смещения цветов не кодируются.
Данные HVIF состоят из трех секций. Первая кодирует все стили, вторая все пути, а последняя все фигуры. Стили и пути глобальны в иконках Haiku, так что они могут быть использованы различными фигурами. Но должно быть не больше чем 256 стилей или 256 путей в общей сложности. Таким образом, фигуры могут ссылаться на них всего одним байтом, который представляет собой индекс стиля или пути в глобальном списке. Фигуры также могут иметь прикрепленные трансформации, например, трансформатор Stroke может преобразовать путь в обводку. Для хранения трансформаторов ничего особенного не изобреталось.
Как можно заметить, вряд ли есть смысл использовать HVIF для общей векторной графики. Этот формат подходит только для очень специальных задач. Но, как было сказано, для решения этих задач он может оказаться полезным, в конечном счете хотя бы с точки зрения отзывчивости рабочего окружения. Но это не произойдет само по себе. Если иконка разработана без знания того, как работает HVIF, то теряется заложенный в него потенциал. Например, если координаты векторного пути не являются целыми значениями, или если пути повторно не используются, где они могут быть, то иконка может занимать намного больше места, чем могла бы. Это особенно актуально, когда SVG иконка импортируется в Icon-O-Matic и просто сохраняется в HVIF как есть, что не есть хорошо. В некоторых работах еще предстоит удалить избыточную или ненужную информацию из иконок, но теперь, с информацией, которая только что была изложена, каждый сможет использовать приёмы оптимизации при создании иконок для Haiku.
+18
24 декабря 2009, 11:28
10

комментарии (24)

+6
ingeniarius #
Для сравнения иконки в среднем занимаю 500-700 байт,
влезают в inode, и как результат считываются за раз вместе с атрибутами файла.
В BeOS растровые иконки занимали 1280 байт.
В Viste иконки могут занимать до 80 кило.
SVG иконки в ZETA сжатые достигают 2-10 кило.
НЛО прилетело и опубликовало эту надпись здесь
+4
ingeniarius #
HVIF двоичный формат, в то время как SVG символьный, что уже значительно определяет размер.
SVG к тому же не просто символьный (тот же например PS), но и XML :)
То есть очень избыточен.
Сказывается разная «заточенность» форматов.
SVG переносимый формат широкого назначения, HVIF формат разработан специально для иконок, со своими ограничениями.
0
combdn #
А вот такая иконка в макосе занимает 364 KB:

Там в файле еще 4 версии поменьше и альфаканалы для всех.
Вроде быстро все работает.

А если это все вектором описывать, то тормозить будет не от скорости загрузки файла, а от времени, которое процессор будет тратить на прорисовку каждой иконки.
0
ingeniarius #
А теперь представьте что иконка появляется мгновенно!
0
combdn #
Ну, так она так и делает.
0
ingeniarius #
В сравнении с HVIF этого быть не может по простой причине, опять придётся повторять, иконка умещается в inode, поэтому она загружается вместе с метаданными файла.
Как только показалось название файла, тут же показалось и иконка.
В других случаях это будет как дополнительная операция чтения файла:
1. нужно считать метаданные, узнать где иконка
2. найти и считать с диска иконку
0
combdn #
Может все так и есть, но я, как пользователь, никаких задержек не замечаю. Превью фильмов, картинок больших в иконках, да, подгружает, но обычные иконки уже сразу есть в новом окне.
0
ingeniarius #
Ну думаю в мак ос тоже придумывают всякого рода пути оптимизации, кеширование и прочее.
0
combdn #
Я про это и говорю. В Барсике вообще все программы заархивированы и записаны в одном и том же месте на диске. Если из под Леопарда зайти, то все программы по 0 байт будут.
0
ingeniarius #
Это как в одном месте?
0
ingeniarius #
Скажем так что даже для растра, за исключением bitmap, тоже надо подумать процессору чтобы его показать.
В HVIF применяются разного рода оптимизации, которые позволяют отрисовать вектр за один проход.
0
combdn #
Я вам говорю как рисователь иконок, если это (↑) оставить вектором, то на то, чтобы просчитать итоговое изображение уйдет больше процессорного времени. И я думаю, в хайковском формате невозможно сделать иконку такой сложности.

В макосе есть векторные иконки но они, как правило, на тулбарах программ находятся, черно-белые пиктограммы, например. Хранятся в формате PDF. Это, наверное, потому, что в макосе графическая система (Quartz) основана на PDF.
0
ingeniarius #
Может попробуете, как рисователь иконок, нарисовать подобную иконку в Icon-o-Matic (вот даже туториал есть video.google.com/videoplay?docid=-2008513940874112547#).
Будет очень интересно сравнить.
Саму haiku можно поставить или в виртуалке или с live flash/cd.
www.haiku-os.org/get-haiku
0
ingeniarius #
Немного фактов про HVIF:
www.haiku-os.org/news/2006-11-06/icon_facts
НЛО прилетело и опубликовало эту надпись здесь
0
ingeniarius #
Какого сравнения?
Прямоугольник:
HVIF — 7 байт
SVG — <rect x=«0» y=«0» width=«64» height=«64»/> — 42 байта
Разница уже в 6 раз :)
0
mdevils #
Пересите в пост подробные сравнения, пожалуйста.
0
ingeniarius #
Какие сравнения, откуда?
+2
spike_msu #
Ура, я перевел 100 000 иконок из SVG в HVIF и выиграл 3,5 мегабайта.
+3
mdevils #
0
immaculate #
Выше написано: влезают в inode, и как результат считываются за раз вместе с атрибутами файла. В этом основное преимущество, скорее всего.
+1
ingeniarius #
влезают в inode, и как результат считываются за раз вместе с атрибутами файла

И действительно зачем было экономить жалкие мегабайты? Пусть иконки по метру будут :)
+2
RISC #
Спасибо за перевод.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.