Формат ani-файлов на ZX
(программы JpeGif Laboratory (GFXcon),
Little Viewer, Ani Editor)
Sam Style
+00 "GIF animation" : сигнатура
+13 =0
+14 размер по X в знакоместах (1-32)
+15 размер по Y в пикселях (1-192)
+16... данные анимации (кадры)
Анимация представляет собой последова─
тельность кадров. Для каждого кадра в на─
чале следуют два байта:
+0 длительность кадра в 1/50 сек
+1 тип упаковки кадра
Если длительность=255 или тип упаковки
не распознан плейером,то мультик возвраща─
ется на самый первый кадр.
И конвертер, и бета редактора выбирают
наилучший метод упаковки из 9 имеющихся
(по методу сжатия изображения).
---- тип 0
Это неупакованый спрайт в линейном фор─
мате. Бывает, что кадр ни в какую ни одним
другим методом не жмется.
При наличии цвета строка атрибутов идёт
после каждых 8 строк изображения.
---- тип 1
Взят из статьи "Сжатие графической ин─
формации и что из этого можно получить" by
Vitamin/CAIG/2001.
Кадр разбивается на знакоместа (размер
по Y увеличивается до ближайшего кратного
8 числа).Рассмотрим упаковку такого знако─
места:
#55,#ff,#55,#ff,#ff,#ff,#50,#05
Начиная со второго байта делаем XOR'инг
с предыдущим:
#55,#aa,#aa,#aa,#00,#00,#af,#55
Создадим флаговый байт - отметим нуле─
вым битом байты,которые равны предыдущему,
и единичным битом, которые не равны. Для
1-го байта предыдущим считается 0. Только
биты в обратном порядке - правый бит отве─
чает за первый байт. Получим:
1,1,0,1,0,0,1,1 = #D3
Теперь выводим в поток сначала флаговый
байт,а потом - те байты XOR'инга,для кото─
рых установлен бит в флаговом байте:
#D3,#55,#AA,#00,#AF,#55
В итоге вместо 8 байт знакоместа полу─
чили 6 байт в упакованом формате.
Распаковка идёт по следующему алгорит─
му:
byte=0
xorbyte=0
flag=байт флагов
цикл 8
RR flag
if carry=1
then берем из потока новый xorbyte
byte=byte xor xorbyte
вывод byte на экран
кц
Количество упакованых блоков,естествен─
но,равно числу знакомест в кадре. Знакоме─
ста пакуются слева направо сверху вниз
(т.е. сначала ряд верхних, потом следующий
ряд, и так до низа).
---- тип 2
Очень похож на тип 1, но в байте флагов
сброшены биты, соответствующие нулям в
XOR'инге. Т.е. для примера из типа 1 флаги
будут:
1,1,0,0,1,1,1,1 = #CF
И в поток выдастся
#CF,#55,#AA,#AA,#AA,#AF,#55
Тут получилось что выигрыш минимален,но
это не значит, что он хуже типа 1.
Здесь распаковка такая:
byte=0
flag=байт флагов
цикл 8
RR flag
if carry=1
then byte=byte xor (байт из потока)
вывод byte на экран
кц
---- тип 3
Это тот же тип 1, но полученное знако─
место не выводится прямиком на экран,а на─
кладывается по XOR на соответствующее зна─
коместо предыдущего кадра.
---- тип 4
Аналогично: кадр упакован типом 2 и по
XOR накладывается на предыдущий.
Если кадр меняется не сильно,то в резу─
льтате его XOR'инга с предыдущим кадром
получается много пустых знакомест, которые
пакуются лучше всего, и в этом случае тип
3 и тип 4 на голову выше остальных типов
упаковки.
Теперь о новых типах:
---- типы 5-9
Это спрессованные типы 1-4.Вводится та─
кое понятие,как флаг 2-го уровня.Биты это─
го флага определяют состояние байтов фла─
гов для 8 следующих за ним знакомест. Если
бит=0, то флаг=0 (в этом случае в поток
пишется только цвет,да и то,если он есть),
а если=1, то флаг не нулевой,и блок идёт в
поток по полной программе (флаг, данные и,
может, цвет).
На примере:
Допустим, упакованый кадр (для широты
кругозора будет с неупакованным цветом)
начинается так...
DB %10010000
DB 1
DB 2
DB 3
DB 4
DB %00100001,#FF,#55,5
DB 6
DB 7
DB %10000000,#77,1
Первый байт - флаг 2-го уровня. Смотрим
за состоянием битов, начиная с нулевого
(правого):
0 - блок пустой (типы 5,6) или не меняется
(типы 7,8). Из данных блока в потоке
только цвет (=1)
0 - то же (цвет 2)
0 - то же (цвет 3)
0 - то же (цвет 4)
1 - АГА! Блок в поток выложен полностью.
Берём флаг блока (%00100001) и
соответственно типу распаковываем
блок. Цвет 5
0 - блок пустой. Цвет 6
0 - блок пустой. Цвет 7
1 - полный блок. (Флаг %10000000, данные
#77, цвет 1.)
Всё, разобрались с 8 блоками...
Дальше следует то же самое - флаг 2-го
уровня и всё, что к нему прилагается.
Конечно, общее число блоков в кадре не
обязательно кратно 8. В таких случаях
ненужные биты последнего флага 2-го уровня
не учитываются.
Что мы с этого получаем? Каждый нулевой
байт флагов стягивается в 1 бит флага 2-го
уровня,но при этом каждый ненулевой распу─
хает до 9 бит. Например, полностью пустой
кадр без цвета ужмётся в страшные 64 раза
(во-первых, пустые знакоместа жмутся в
нулевой флаговый байт, а во-вторых, каждый
нулевой флаговый байт жмётся в 1 бит флага
2-го уровня).
---- теперь про цвет
Информацию о наличии цвета и его упако─
вке (да,и это тоже есть!) передают старшие
биты типа кадра.
b7 = 0, если цветового потока нет (т.е. он
полностью идентичен потоку
предыдущего кадра)
= 1, если он есть
b6 = 0, если цвет не кодируется (т.е. за
каждым упакованым знакоместом идёт
1 байт цвета)
= 1, если кодируется (пропускаются
знакоместа с неизменяющимся цветом)
А теперь я сказать по бумажка...
При упаковке цвета введён ещё и контро─
льный байт для цвета. Весьма и очень похож
на флаг 2-го уровня - если в нем бит = 0,
то цвет знакоместа не поменялся по отноше─
нию к предыдущему кадру и в потоке отсутс─
твует. А если бит = 1, то вслед за знако─
местом идёт его цвет. Как и флаг 2-го уро─
вня,флаг цвета встречается каждые 8 знако─
мест. Если оба эти флага наличествуют (на─
пример, тип 5 с упакованым цветом: #С5),то
первым всегда идет флаг 2-го уровня, а за
ним - флаг цвета.
Полная схема потока кадра вроде как вы─
глядит так:
[длительность]
[тип] b0..5 - тип упаковки
b6 - цвет спрессован
b7 - цвет присутствует
[флаг 2 уровня] только для типов 5-9
(определяет наличие пар
[флаг][блок])
[флаг цвета] только для спрессованного
цвета (определяет наличие
компонента [цвет])
[флаг 1][блок 1][цвет 1]
[флаг 2][блок 2][цвет 2]
[флаг 3][блок 3][цвет 3]
[флаг 4][блок 4][цвет 4]
[флаг 5][блок 5][цвет 5]
[флаг 6][блок 6][цвет 6]
[флаг 7][блок 7][цвет 7]
[флаг 8][блок 8][цвет 8]
[флаг 2 уровня]
...
Ну, и как всегда,приоритет в выборе ти─
па упаковки (и изображения,и цвета) - раз─
мер...