Skip to main content

Описание бинарного формата MSK

Date: 2018.08 | Version: 0.1 | Авторы: Александр Евдокимов#

Глоссарий

integer - тип данных, целое положительное число.

string - тип данных, строка.

Ссылки

Шаблон формата MSK для 010 Editor. Открыть

Оглавление#

1. Введение

2. Общая структура формата

3. Секции

3.1 Заголовок файла

3.2 Пиксельные данные

3.2.1 8 битная маска

3.2.1.1 Палитра

3.2.1.2 Таблица индексов

3.2.2 16 битная маска

1. Введение#

Этот документ описывает структуру формата файла MSK, используемого в игре Дальнобойщики Путь к Победе и Дальнобойщики 2 (Версия 8). Формат MSK содержит 8 битные изображения с палитрой или 16 битные изображения в формате RGB. Изображение хранится в сжатом виде (вариант RLE кодирования).

Все переменные, перечисленные в таблицах, показаны в порядке их следования в файле.

2. Общая структура формата#

Формат MSK разделен на 2 основные секции (см Табл. 1).

Таблица 1. Общая Структура#

СекцияСсылки
1Заголовок файлаСм. Таблица
2Пиксельные данныеСм. Таблица

3. Секции#

3.1 Заголовок файла#

Файл начинается с сигнатуры длиной 4 байта в виде строки См. Таблица 2. Далее следуют размеры изображения.

Таблица 2. Структура заголовка файла#

Тип данныхОписаниеЗначение
1stringСигнатура файла (4 байта)См. Таблица 3
2integerШирина изображения (2 байта)
3integerВысота изображения (2 байта)

Таблица 3. Идентификаторы#

ТипОписание
1"MSKR"
2"MS16""16 битное изображение RGB565
3"MSK8"8 битное изображение, Черно-белая маска
4"MASK"8 битное изображение, 8 битная маска

3.2. Пиксельные данные#

3.2.1 8 битная маска#

Таблица 4. Общая Структура#

СекцияСсылки
1ПалитраСм. 3.2.1.1 Палитра
2Таблица индексовСм. 3.2.1.2 Таблица индексов пикселей)

3.2.1.1 Палитра#

Стандартная 8 битная палитра на 256 цветов по три байта на цвет в формате RGB. Подробнее

3.2.1.2 Таблица индексов пикселей#

Стандартная таблица индексов пикселей, где каждый байт хранит индекс цвета в палитре 0..255, сжатая методом RLE кодирования.

3.2.2 16 битная маска#

Изображение в формате RGB по два байта на 1 пиксель. Формат сжатия аналогичен для 8 битного изображения с учетом того, что необходимо выделять по два байта на 1 пиксель изображения при распаковке. В конце файла расположена секция PFRM, содержащая RGB маски.

Таблица 6. Общая Структура#

СекцияСсылки
0Пустые данные (768 байт)
1Пиксельные данные
2Секция с масками RGB (PFRM)

Таблица 6. Cекция PFRM#

ТипОписание
1stringИндификатор PFRM (4 байта)
2integerРазмер секции (4 байта)
3Маска для красного цвета (4 байта)
4Маска для зеленого цвета (4 байта)
5Маска для синего цвета (4 байта)

Описание метода сжатия#

8-битное изображение#

Кодируется только таблица индексов, палитра остается в неизменном виде. Принцип кодирования:

  • Данные записываются в файле двумя группами: байты без сжатия и сжатые;

  • Первая группа со значениями меньше 128 применяется для данных без сжатия. Здесь сначала будет идти один первый байт, имеющий значение 0..127, а затем последовательность байтов данных в количестве указанном в первом байте. При распаковке нужно скопировать эти данные без изменения.

  • Вторая группа со значениями больше 128 используется для обозначения последовательности черных пикселей (RLE сжатие);

    В один "сжатый" байт можно уместить не больше 127 пикселей исходного изображения. Например, если значение байта в msk файле будет равно 254, это будет означать, что в исходном изображении была последовательность из 254 - 128 = 126 байт, и при распаковке файла вы должны записать 126 байт со значением 0.

  • Изображение кодируется построчно;

    Для примера рассмотрим вариант, когда верхняя часть исходного несжатого изображения состоит только из черного цвета и имеет ширину 200 пикселей.Тогда при сжатии мы получим два байта: 1 байт имеет значение 255 и хранит первые 127 черных пикселей, второй байт хранит оставшиеся 73 (200 - 127) и имеет значение 201.

16-битное изображение#

Аналогично с учетом того, что в 16 битных изображениях сжимаются пиксели. Необходимо учитывать, что на 1 пиксель распакованного изображения требуется 2 байта.

Как распаковать (упрощенно):#

  1. Прочитать первый байт.
  2. Если он больше 128, то записать байты со значением 0.
  3. Если он меньше 128, то скопировать данные идущие после.
  4. Вернуться к пункту 1.