IMG архив — различия между версиями

Материал из GTAModding.ru
Перейти к: навигация, поиск
Строка 71: Строка 71:
 
  end;
 
  end;
  
procedure TForm1.Button2Click(Sender: TObject); //Процедура извлечения файлов
+
procedure TForm1.Button2Click(Sender: TObject); //Процедура извлечения файлов
var
+
var
  Size, Offset : Integer;
+
  Size, Offset : Integer;
  DestFile : TFileStream;  // Сюда будем загружать файл для сохранения
+
  DestFile : TFileStream;  // Сюда будем загружать файл для сохранения
begin
+
begin
  if CFileList.SelCount > 0 then  // Если что-либо выделено в списке файлов  
+
  if CFileList.SelCount > 0 then  // Если что-либо выделено в списке файлов  
  begin
+
    SaveDialog1.FileName := CFileList.Selected.Caption;
+
    if SaveDialog1.Execute then
+
 
     begin
 
     begin
      DestFile := TFileStream.Create(SaveDialog1.FileName, fmCreate);  // Создаём файл
+
    SaveDialog1.FileName := CFileList.Selected.Caption;
      DestFile.Seek(0, 0);  // Смещаемся в начало файла.
+
    if SaveDialog1.Execute then
      Size := StrToInt(CFileList.Selected.SubItems.Strings[0]);// Узнаём размер выделенного файла
+
    begin
      Offset := StrToInt(CFileList.Selected.SubItems.Strings[1]);// Узнаём смещение выделенного файла
+
      DestFile := TFileStream.Create(SaveDialog1.FileName, fmCreate);  // Создаём файл
      Stream.Seek(Offset, 0);  // Смещаемся к смещению (то есть, к началу) файла в архиве
+
      DestFile.Seek(0, 0);  // Смещаемся в начало файла.
      DestFile.CopyFrom(Stream, Size);  // Копируем количество байт, равным размеру файла в архиве
+
      Size := StrToInt(CFileList.Selected.SubItems.Strings[0]);// Узнаём размер выделенного файла
      DestFile.Free;  // Закрываем файл
+
      Offset := StrToInt(CFileList.Selected.SubItems.Strings[1]);// Узнаём смещение выделенного файла
    end;
+
      Stream.Seek(Offset, 0);  // Смещаемся к смещению (то есть, к началу) файла в архиве
  end;
+
      DestFile.CopyFrom(Stream, Size);  // Копируем количество байт, равным размеру файла в архиве
end;
+
      DestFile.Free;  // Закрываем файл
 +
    end;
 +
  end;
 +
end;
  
 
===Версия 3 - GTA IV===
 
===Версия 3 - GTA IV===

Версия 12:37, 17 января 2009

В IMG архивах GTA в основном хранятся игровые модели, текстуры, транспортные и пешеходные пути, анимации, а так же внешние скрипты. IMG архив имеет расширение .img. Эти архивы разделяются на версии и имеют схожий между собой формат (за исключением версии, используемой GTA IV).

Содержание

Структура

Версия 1 - GTA III & VC

Архивы первой версии, используемые в GTA III и Vice City, разделены на два файла: директория содержимого архива (.dir) и сам архив, содержащий файлы (.img).

Директория содержит список файлов, их имена, смещение и размер. Значения смещения и размера файлов должны быть умножены на 2048. Файлы расположены в блоках по 2 КБ. Это означает, что даже если файл имеет размер менее 2-х КБ (например, 218 байт), то в архиве он будет занимать 2 КБ. Файлы (обычно) не имеют сортировку, не сжаты и располагаются "друг за другом" (никакой древовидной иерархии).

Чтобы найти общее количество элементов (файлов) в .img архиве, необходимо разделить размер .dir файла на 32.

Файл директории не имеет заголовка, просто массив элементов по 32 байта на каждый:

Элемент (повторяется n-раз, где n - общее количество элементов):

 4 байта  - DWORD	- смещение файла (в блоках) в .img архиве, относительно его начала
 4 байта  - DWORD 	- размер файла (в блоках) в .img архиве
24 байта  - CHAR[24] 	- имя файла

Сам .img архив не имеет заголовка, просто файлы, как говорилось ранее, расположенные в блоках по 2 КБ.

Схема распределения файлов в IMG архиве

Версия 2 - GTA SA

Архивы второй версии, используемые в GTA San Andreas, содержат .dir и .img файлы в одном .img файле. Директория имеет такой же формат, как и в формате 1-ой версии, но располагается в начале .img файла. Файлы так же размещены в блоках по 2 КБ. Смещения файлов задаются от начала самого архива, а не от конца списка файлов.

Заголовок:

 4 байта	 - CHAR[4]	- сигнатура архива, всегда имеет значение "VER2"
 4 байта	 - DWORD	- общее количество элементов (файлов)

Элемент: (повторяется n-раз, где n - общее количество элементов):

 4 байта - DWORD     - смещение файла (в блоках) в архиве
 4 байта - DWORD     - размер файла (в блоках)
24 байта - CHAR[24]  - имя файла

Недостаток этого формата - это его расширяемость. Если вы добавите слишком много файлов, директория начнёт записываться поверх первых файлов в архиве, поэтому вам нужно будет записывать первые файлы в конец архива.

Пример программы на Delphi по работе с форматом

procedure TForm1.Button1Click(Sender: TObject); //Процедура открытия архива
var
  Size, Offset, FileNum, A : Integer;
  Name : PChar;
  FileName : String;
  ListItem : TListItem;
begin
  if OpenDialog1.Execute then
  begin
    CFileName.Text := OpenDialog1.FileName;
    Size := 0;
    Offset := 0;
    Name := PChar(AllocMem(24));                                 
    CFileList.Clear;
    FileName := OpenDialog1.FileName;
    Stream := TFileStream.Create(FileName, fmOpenRead);   // Открываем архив для чтения
    Stream.Seek(4, 0);   // Пропускаем первые 4 байта, так как они всегда равны "VER2"
    Stream.Read(FileNum, 4);   // Считываем количество файлов
    for A := 0 to FileNum - 1 do  // Цикл считывания всех файлов
    begin
      Stream.Read(Offset, 4);   // Считываем смещение файла
      Stream.Read(Size, 4);   // Считываем размер файла
      Stream.Read(Name^, 24);  // Считываем имя файла
      ListItem := CFileList.Items.Add;                  //
      ListItem.Caption := Name;                         // Добавляем файл со всеми 
      ListItem.SubItems.Add(IntToStr(Size * 2048));     // параметрами в список файлов
      ListItem.SubItems.Add(IntToStr(Offset * 2048));   // 
    end;
  end;
end;
procedure TForm1.Button2Click(Sender: TObject); //Процедура извлечения файлов
var
  Size, Offset : Integer;
  DestFile : TFileStream;  // Сюда будем загружать файл для сохранения
begin
  if CFileList.SelCount > 0 then   // Если что-либо выделено в списке файлов 
   begin
    SaveDialog1.FileName := CFileList.Selected.Caption;
    if SaveDialog1.Execute then
    begin
      DestFile := TFileStream.Create(SaveDialog1.FileName, fmCreate);   // Создаём файл
      DestFile.Seek(0, 0);   // Смещаемся в начало файла.
      Size := StrToInt(CFileList.Selected.SubItems.Strings[0]);// Узнаём размер выделенного файла
      Offset := StrToInt(CFileList.Selected.SubItems.Strings[1]);// Узнаём смещение выделенного файла
      Stream.Seek(Offset, 0);  // Смещаемся к смещению (то есть, к началу) файла в архиве
      DestFile.CopyFrom(Stream, Size);  // Копируем количество байт, равным размеру файла в архиве
      DestFile.Free;   // Закрываем файл
    end;
  end;
end;

Версия 3 - GTA IV

Данная версия архива имеет более сложную структуру. Эта статья не завершена