Формат 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 уровня] ... Ну, и как всегда,приоритет в выборе ти─ па упаковки (и изображения,и цвета) - раз─ мер...