Думаю, что каждый был в неловкой ситуации, когда вам задают "неправильный" вопрос из-за того, что задающий не в теме вопроса. В такой ситуации не поймешь, с чего начинать отвечать, поэтому я начну... с самого начала.
Вступление
Когда мы говорим Flash, то можем подразумевать совершенно разные вещи даже в рамках терминов web-технологии. Чтобы не было путаницы, я буду использовать:
- Flash – технология web-анимации в целом;
- Flash player – программа, библиотека ActiveX которая выполняет отображение flash;
- Standalone Flash player – приложение (exe-файл), отображающее flash;
- Flash IDE, Adobe Flash, Flash Professional – среда разработки, предоставляемая фирмой Adobe (ранее Macromedia);
- FLA – проектный файл (исходный) анимации для Flash IDE;
- Movie, мувик – цельная сущность web-анимации на этапе разработки;
- SWF – непосредственно конечный файл анимации.
И так, когда мы открываем web-страницу, на которой находится flash анимация, в упрощенном варианте происходит следующее: интернет-браузер в html разметке обнаруживает вставку flash-анимации, создает объект flash-плеера и указывает ему какой файл нужно отобразить. Flash-плеер выполняет загрузку swf, и, если это возможно, начинает его отображать. Благодаря такому принципу работы flash-плеер может отображать так называемые прелоадеры (preloaders), воспроизводить потоковый звук и видео (как, например, YouTube) без полной загрузки самого swf.
Структура SWF
Формат файла описан в документе SWF File format specification, который можно загрузить с сайта Adobe.com. Обычно документация опаздывает от выхода новых версий flash-плееров до полугода. На момент написания данного текста уже выпущен 10-ый flash-player, но файл спецификации не обновлен и содержит описание только 9-ой версии. Почти про все, что я здесь буду писать, можно найти спецификации, но в том то и дело, что "почти все" :)
Базовая структура SWF не зависит от версии, поэтому SWF всегда имеет структуру Header + Body. Body в свою очередь состоит из записей, которые в терминологии спецификации называют тэгами (tags).
Для описания структуры данных я буду использовать синтаксис Object Pascal.
Header
Заголовок содержит основную информацию о SWF и ее можно описать так:TSWFHeader = packed record
SIGN: array [0..2] of AnsiChar;
Version: byte;
FileSize: LongWord;
MovieRect: TRect;
FPS: word;
FramesCount: word;
end;
- Первым параметром идет сигнатура SIGN. Значение CWS указывает, что данный файл упакован ZLib-компрессией, а FWS - нет.
- Version – версия формата файла.
- FileSize – размер в байтах НЕСЖАТОГО файла.
- MovieRect – размер изображения на экране в твипсах (1px = 20twips). Учитывая эти единицы нужно отметить, что, фактически, SWF и графические объекты не могут быть больше, чем $ffff / 20 = 3276 px.
Я не встречал swf, в которых top-left значения больше или меньше 0, но задав эти значения в своих тестах убедился, что эти значения таки учитываются.
Стоит отметить, что указанный прямоугольник является «посадочным местом» которое отводится в браузерах. Если открыть swf в Standalone-плеере, то иногда можно увидеть "декорации за кадром". - FPS (frames per second) – значение в формате 8.8 fixed, т.е. для человеческого восприятия это значение Result := FPS shr 8 + (FPS and $FF) / ($FF+1);
- FramesCount – количество кадров. Как правило, минимум один кадр всегда есть, но можно делать swf и без кадров, если этот файл служит как библиотека для других swf.
Компрессия в SWF
Для уменьшения размера файла Macromedia применила два подхода.
Первый заключается в том, что для сохранения чисел используется побитовая упаковка. Выглядит это примерно так. Допустим, нам нужно сохранить размер прямоугольника, т.е. четыре числа типа integer. При простой записи это будет 4 * 4 байта = 16 байт. При записи в swf в первые 5 бит записывается число бит, необходимое для кодирования самого большого значения, а затем эти 4 значения в битовом представлении с указанной длиной бит. Например, нужно сохранить координаты (0, 0 - 100, 100) в переводе на твипсы (0, 0 - 2000, 2000). В битовом представлении число 2000 = 11111010000 (11 бит + 1 для знака). Выходит (5 + 4 * 12) / 8 = 7 байт, что меньше почти в двое.
Такой подход приводит к тому, что некоторые одинаковые тэги могут иметь разный размер. Это также относится и к Header.
Второй подход - это использование ZLib компрессии как в целом для всего swf, так и для отдельных тэгов.
Когда файл компрессированный, то первые три параметра Header-а (это 8 байт) не упакованы, а остальные упакованы и это объясняет, почему нельзя одним методом Read считать только заголовок swf.
4 комментария:
Header не записывается полностью как в структуре, которую я описал. Посмотрите код в примере delphiflash.com/library-info-from-swf.php
Случайно удалил Ваш пост
>>Создал пустой проект, скомпиллировал. Параметры: FP9, компрессию выключил, fps 30, размер 20х25, вес swf-файла 1340 байт. Просматриваю его winHex-ом. Там видим:
46 57 53 - соответствует fws
09 - собственно версия плеера
3c - соответствует 1340 (т.е. к-во байт)
05 00 00 50 - тут по идее должны быть размеры в твипсах, т.е. 0,0,400,500 Вот про это место у меня и вопрос. Что я не так смотрю, откуда не соответствие? Заранее спасибо.
С синтаксисом Delphi не знаком, сам флешер. Буду благодарен если подскажете, что есть TBitWidth, ReadNBits, Inc и конструкция типа Buffer^. С остальным можно и самому попробовать разобраться. Спасибо за отзыв.
Отправить комментарий