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

Материал из GTAModding.ru
Перейти к: навигация, поиск
(Версия 2 - GTA SA)
Строка 37: Строка 37:
  
 
Недостаток этого формата - это его расширяемость. Если вы добавите слишком много файлов, директория начнёт записываться ''поверх первых файлов в архиве'', поэтому вам нужно будет записывать первые файлы в конец архива.
 
Недостаток этого формата - это его расширяемость. Если вы добавите слишком много файлов, директория начнёт записываться ''поверх первых файлов в архиве'', поэтому вам нужно будет записывать первые файлы в конец архива.
 +
 +
====Пример программы на 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===
 
===Версия 3 - GTA IV===

Версия 12:36, 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

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