Формат графический файлов GRP

Здесь я сначала размещу копипаст с какого-то английского ресурса, а затем сделаю перевод.

Делаю что бы не потерялось в сети это чудо)

UPD Нашел неточности, узнал значение неизвестных байтов

The GRP-file-format - used by Blizzard Inc. for StarCraft(TM)
-------------------------------------------------------------

Небольшие замечания
----------

Все написанное ниже основано на опыте при программировании CV-tool.
Я не даю никаких гарантий об этом документе, 
мой софт использует эту спецификацию 
Используйте данное описание на свой страх и риск.
Изменения возможны только при согласовании этого 
с автором - http://www.cs.tu-berlin.de/~mickyk/2XS.html.
Здесь вы так же найдете классы для C++.

Спасибо за внимание,

      TeLAMoN of 2XS in 1998.
      (mickyk@cs.tu-berlin.de)

The Blizzard GRP-Format
-----------------------

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

Как это работает:

Заголовок:
~~~~~~~
Смещение:
       +---------------+
 0x0000| L  frameCount | одно СЛОВО(WORD (2Bytes, первый байт младший)) для
       | H             | количества кадров
       +---------------+
 0x0002| L  X-Dim      | одно слово(WORD) для размера по оси X
       | H             | для всего изображения
       +---------------+
 0x0004| L  Y-Dim      | одно слово(WORD) для размера по оси X
       | H             | для всего изображения
       +---------------+

Заголовок кадра(??FrameTab):
~~~~~~~~~
Смещение:
       +---------------+
 0x0006| xOffset       | один байт для смещения по оси X
       +---------------+
 0x0007| yOffset       | один байт для смещения по оси Y
       +---------------+
 0x0008| xLen          | один байт для ширины по оси X
       | yLen          | один байт для ширины по оси Y
       +---------------+
 0x000a| L             | одно двойное слово (DOUBLEWORD (младший первый))
       |               | для положения в файле данных кадра
       |               | <pFrameData>
       | H             |
       +---------------+
       ...

       Эти блоки повторяются столько раз, сколько всего кадров (frameCount)
Данные кадра:
~~~~~~~~~~
Смещение:
             +---------------+
<pFrameData> | L Смещение    | одно слово (WORD) для смещения, где мы найдем
             | H первой линии| первую строку   <oL1> (что бы получить ширину
             +---------------+ этого кадра необходимо посчитать <oL1>/2 + 1)
             | L Смещение    |
             | H второй...   |
             +---------------+
             ...
             Эти блоки повторяются до тех пор пока не будет достигнута 
первая строка. Т.е. до <pFrameData>+<oL1>
Данные строки:
~~~~~~~~~
Смещение:
                  +---------------+
<pFrameData>+<oL1>| BYTE 1        | Поток данных, закодированных определенным образом
                  +---------------+ (см. ниже)
                  | BYTE 2        |
                  ...
                  | BYTE <oL2>-1  |
                  +---------------+
                  +---------------+
<pFrameData>+<oL2>| BYTE 1        | Поток данных
                  +---------------+
                  | BYTE 2        |
                  ...
                  | BYTE <oL3>-1  |
                  +---------------+
                   ... Повторяется для всех сток...

Хорошо, как теперь с этими кадрами работать? Что ж, давайте начнем:

Для начала скажу, что мы начнем в нижнем правом углу кадра.
Тогда строка записана справа на лево. И не забудьте про смещения xOffset и yOffset.

on_Top:

Если прочитанный байт >=0x80:

   -вычесть 0x80 из этого байта и вычесть результат из
    current_X_position.

    Пример: мы прочитали 0x85. Вычтем 0x80 и тогда мы получим 0x05. Если наше
    current_X_position = 0x43, то новое значение будет 0x43-0x05 = 0x3e.
    Как это выглядит в нашем фреймбефере: ( ^ - текущее положение current_X_position)

    до:        [... 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 20 10 1f ...]
                                                              ^
    после:     [... 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 20 10 1f ...]
                                               ^

иначе
Если прочитанный байт >0x40:
   -вычтем 0x40 и запомним результат как LOOP
   -прочитаем следующий байт и положим этот байт LOOP-раз в наш фрейм-буффер      

    Пример: Мы прочитали 0x43. Тогда LOOP будет равно 0x03.
    Следующий байт пусть будет 0x62.
    Тогда наш фреймбуффер будет выглядеть так:

    до:        [... 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 20 10 1f ...]
                                                   ^
    после:     [... 00 00 00 00 00 00 00 62 62 62 00 00 00 00 00 20 10 1f ...]
                                       ^  

иначе
Если прочитанный байт <0x40:
   -положим этот байт в LOOP
   -Скопируем LOOP байтов в фреймбуффер     

    Пример: Пусть grp выглядит так: ... 06 14 2a 34 3a a1 f1 ... а LOOP пусть будет 0x06,
    тогда наш фреймбуффер будет таким:

    до:       [... 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 20 10 1f ...]
                                                ^
    после:    [... 00 f1 a1 3a 34 2a 14 62 62 62 00 00 00 00 00 20 10 1f ...]
                    ^

Теперь читаем следующий байт (пока не достигнем конца строки) и возвращаемся обратно к "on_Top:".
Конец определяете по переменной yLen для текущего фрейма.

Трекбек

Ссылка для трекбека:
http://stepa.name/archives/43/trackback

Комментарии

Хех

Post a comment