TIM2

Материал из GTAModding.ru
Перейти к: навигация, поиск

TIM2 - растровый графичесий формат приставки Sony Playstation 2. C небольшими изменениями1 используется в PS2 TXD-файлах трилогии GTA, Bully, Manhunt и в других играх.

Содержание

Структура файла

В начале файла содержится заголовок размером 16 байт, имеющий следующую структуру:

 struct tim2_header {
   BYTE sign[4];
   WORD format_id;
   WORD pictures;
   BYTE padding[8];
 }
  • sign - 4 байта - всегда равно "TIM2"
  • format_id - 2 байта - равно 4 (??)
  • pictures - 2 байта - количество изображений в файле.
  • padding - 8 байт - зарезервированное место (байты могут быть нулями)

Далее идёт заголовок изображения, повторяющийся N раз (N=picures) вместе с палитрой и самим растром.

 struct tim2_imge_header {
   DWORD total_size;
   DWORD clut_size;
   DWORD image_size;
   WORD  header_size;
   WORD  clut_colors;
   BYTE  pict_format;
   BYTE  mipmaps;
   BYTE  clut_type; 
   BYTE  image_type;
   WORD  image_width;
   WORD  image_height;
   BYTE  unknown[24];
 };
  • total_size - 4 байта - общий размер (размер изображения, палитры и заголовка)
  • clut_size - 4 байта - размер палитры (равен количеству цветов, умноженному на 4)
  • image_size - 4 байта - размер изображения (размер растра, равен произведению длины, ширины и размеру пикселя в байтах)
  • header_size - 2 байта - размер заголовка (этой структуры). Важно отметить, что размер этой структуры колеблется в довольно больших пределах (поле unknown может больший или меньший размер). Возможно, при программировании, есть смысл не включать unknown в структуру, а считать его основываясь на значении поля header_size.
  • clut_colors - 2 байта - количество цветов в палитре
  • pict_format - 1 байт - неизвестно, обычно равно 0 (нулю).
  • mipmaps - 1 байт - количество мипмапов.
  • clut_type - 1 байт - неизвестно, обычно равно 3
  • image_type - 1 байт - тип изображения:
0 - NONE
1 - RGB16
2 - RGB24
3 - RGB32
4 - IDTEX4 - для 4-битных текстур
5 - IDTEX8 - для 8-битных текстур
  • image_width - 2 байта - ширина изображения в пикселях
  • image_height - 2 байта - высота изображения в пикселях

Далее идут данные растра, за ними - данные палитры.

Структура палитры

(Палитра идёт после растра, но вначале нужно объяснить структуру палитры) Если значение BPP равно 4 и 8 битам на пиксель, то используется палитра, хранящая в себе все эти цвета. Количество цветов, как ясно из школьной программы или дискретной математики равно bpp2, т.е. 16 для 4 бит и 256 для 8ми. Каждый цвет, в любом случае, представляет собой 4 байта в формате RGBA - Red (красный), Green(зелёный), Blue (синий), A(альфа). Сответсвенно, размр паритры равен colors·4 байт. Форматы, использующие менее 16 цветов не испоьзуются, а более 256 не имеют палитры вообще.

Структура растра

Растр сделан наподобие довольно известного формата BMP (Windows Bitmap).

  • Если текстура имеет глубину цвета 8бит, то растр представляет собой массив размером width x height типа BYTE, каждый байт которого содержит номер (индекс) цвета в палитре. НО для 8-битных текстур есть одина особенность - если разбить палитру на блоки по 32 цвета, то вторая и третья 8-ки цветов как бы поменяны местами (такое преобразование может понадобиться при создании BMP из TIM2):
  | 0 1 2 3 | 4 5 6 7 |  -->  | 0 2 1 3 | 4 6 5 7 | (каждая цифра -  блок из 8 цветов)
  • Если текстура 4-битная, то растр представляет собой массив размером width x height / 2 типа BYTE, в котором каждый байт задаёт два цвета, наподобие того, как в 8-битных цвет задаёт один байт. Палитра никаких особенностей не содержит.
  • Если текстура содержит 32 бита на пиксель, то она представляет собой массив цветов такой же струкуры, как и цвет палитры, т.е. width x height x 4. Точно также в формате RGBA.
  • Если текстура 16-битная, то растр хранится согласно полю в одном из форматов RGB (5-5-5, 5-6-5) или ARGB(1-5-5-5) или RGBA(4-4-4-4). В GTA обычно используется 1555.

Swizzling

В TXD-архивах GTA используется технология swizzling'а, которая, в общих чертах, позволяет выиграть в производительности игры за счёт нестандартного расположения пикселей. По своей сути swizzling - операция на блоке изображения размером 16x8. Если изображение меньше чем 16 по ширине, то ширина всё равно будет 16 (в сучае с 4-битными текстурами, это условие работает для 32 пикселей в ширину - по видимому, дело ещё и в размере строки в байтах). При этом swizzling применяется к большому изображению, а результат "обрезается" до нужных размеров. В зависимости от количества битов на пиксель (bpp) алгоритм подвергается некоторым вариациям (из-за способа хранения одного пикселя). Следует также отметить, что в GTA3 некоторые текстуры (4 и 8 бит) хранятся без swizzling'а.

Код unswizzling'а для 8-битных PS2 текстур выглядит так:

void unswizzle8( char* buf, int width, int height ) {
	char* swizzled = new char[width*height];
	memcpy(swizzled, buf, width*height);
 
	for (int y = 0; y < height; y++) {
		for (int x = 0; x < width; x++) {
			int block_location = (y & (~0xf)) * width + (x & (~0xf)) * 2;
			int swap_selector = (((y + 2) >> 2) & 0x1) * 4;
			int posY = (((y & (~3)) >> 1) + (y & 1)) & 0x7;
			int column_location = posY * width * 2 + ((x + swap_selector) & 0x7) * 4;
 
			int byte_num = ((y >> 1) & 1) + ((x >> 2) & 2);     // 0,1,2,3
 
			buf[(y * width) + x] = swizzled[block_location + column_location + byte_num];
		}
	}
	delete [] swizzled;
}

Преобразование в BMP

Логичный вопрос - преобразование одного растрового формата в другой (без потери качества). Итак,

  1. Палитру (для 4bpp и 8bpp) или же сам растр нужно преобразовать из RGBA в BGRA.
  2. Растр нужно отразить построчно сверху вниз.
  3. В 4-битных текстурах нужно поменять местами старшие и младшие 4 бита каждого байта растра.
  4. Далее собрать обший заголовок или воспользоваться готовыми функцияи Windows. (Информация по формату BMP есть здесь)

Обратите внимание, что

  • 8- и 4-битные BMP не поддерживают альфа-канал (маску).
  • Маску поддерживают 32-битные BMP, поэтому для отображения текстуры вместе с альфой именно в BMP можно воспользоваться им.

Примечания

^В TXD-файлах текстуры хранятся в с использованием swizzling'а. Исключение составляют только некоторые 4-битные текстуры.

Ссылки