TIM файлы – Формат хранения графики PSX

Автор SPOT, 10 мая 2015, 10:16

« назад - далее »

zetper

Цитата: TTEMMA от 01 сентября 2015, 08:31 

Цитата: zetper от 29 августа 2015, 15:39Опишите пожалуйста метод хранения графики в TIM2 если нужны примеры файлов здесь они есть rutracker.org/forum/viewtopic.php?t=4514120 
SPOT твои объяснения о хранению несжатой графики о очень просто и понятны,СПАСИБО ТЕБЕ БОЛЬШОЕ за них.
gtamodding.ru/wiki/TIM2
 
 
В статье с gtamodding описано всё языком профессионала,а хотелось бы видеть в простом виде как в этой статье, где всё разложено по полочка и наглядно.
 

SPOT

Цитата: zetper от 29 августа 2015, 15:39Опишите пожалуйста метод хранения графики в TIM2 если нужны примеры файлов здесь они есть
 
SPOT твои объяснения о хранению несжатой графики о очень просто и понятны,СПАСИБО ТЕБЕ БОЛЬШОЕ за них.
 
Сейчас напряг со свободным временем, как оно появится обязательно займусь разборкой и описанием TIM2.

TTEMMA

По быстрому накидал код для извлечения изображений из TIM в PNG:
 

Type
TBpp = (Bpp_4 = 8, Bpp_8 = 9, Bpp_16 = 2, Bpp_24 = 3);
TTim_Palette = packed record
Size   : LongWord;
VramX  : Word;
VramY  : Word;
Width  : Word;
Height : Word;
end;
TTim_Image = Packed Record
Size   : LongWord;
VramX  : Word;
VramY  : Word;
Width  : Word;
Height : Word;
end;
TTim = Packed Record
Bpp         : TBpp;
Tim_Palette : TTim_Palette;
Tim_Image   : TTim_Image;
const
ID : LongWord = $10;
end;

Procedure GetRGB555(Color : Word;var R,G,B:Byte);
begin
R := (Color and $1F) * 8;
G := ((Color shr 5) and $1F) * 8;
B := ((Color shr 10) and $1F) * 8;
end;

Function Create_HPalette(Stream:TStream;Count:Word):HPalette;
var
I:Integer;
_Pal:PLogPalette;
w:word;
begin
_Pal := 0;
GetMem(_pal, sizeof(TLogPalette) + sizeof(TPaletteEntry) * Count);
_Pal.palVersion := $300;
_Pal.palNumEntries := Count;
for I := 0 to Count-1 do
begin
Stream.Read(w,2);
GetRGB555(w,_Pal.palPalEntry[i].peRed,_Pal.palPalEntry[i].peGreen,_Pal.palPalEntry[i].peBlue);
_Pal.palPalEntry[i].peFlags := 0;
end;
Result := CreatePalette(_PAL^);
end;

Function Convert_Tim_To_PNG(TIM_Stream:TStream; Palette_Number: Byte):TPNGImage;
var
TIM         : TTIM;
L           : LongWord;
scanline    : pByteArray;
RGBScanline : pRgbLine;
_Palette    : HPalette;
B           : Byte;
w           : Word;
I,x,y       :Integer;
begin
TIM_Stream.Position := 0;
TIM_Stream.Read(l,4);

if l = TTim.ID then
begin
TIM_Stream.Read(TIM.Bpp,4);
case TIM.Bpp of
Bpp_4: begin
TIM_Stream.Read(TIM.Tim_Palette,SizeOF(TIM.Tim_Palette));
_Palette := 0;
for I := 1 to TIM.Tim_Palette.Height do
begin
if i = Palette_Number then
_Palette := Create_HPalette(TIM_Stream,16) else
TIM_Stream.Position := TIM_Stream.Position + $20;
end;
TIM_Stream.Read(TIM.Tim_Image,SizeOf(Tim.Tim_Image));
Tim.Tim_Image.Width := TIM.Tim_Image.Width * 4;
Result := TPngImage.Create;
Result.CreateBlank(COLOR_PALETTE,8,Tim.Tim_Image.Width,Tim.Tim_Image.Height);
Result.Palette := _Palette;
for y := 0 to TIM.Tim_Image.Height - 1 do
begin
scanline := Result.Scanline[y];
x:=0;
while x<Tim.Tim_Image.Width do
begin
TIM_Stream.Read(b,1);
scanline[x] := b and $F;
scanline[x+1] := b shr 4;
inc(x,2);
end;
end;
end;
Bpp_8: begin
TIM_Stream.Read(TIM.Tim_Palette,SizeOF(TIM.Tim_Palette));
_Palette := 0;
for I := 1 to TIM.Tim_Palette.Height do
begin
if i = Palette_Number then
_Palette := Create_HPalette(TIM_Stream,256) else
TIM_Stream.Position := TIM_Stream.Position + $200;
end;
TIM_Stream.Read(TIM.Tim_Image,SizeOf(Tim.Tim_Image));
Tim.Tim_Image.Width := TIM.Tim_Image.Width * 2;
Result := TPngImage.Create;
Result.CreateBlank(COLOR_PALETTE,8,Tim.Tim_Image.Width,Tim.Tim_Image.Height);
Result.Palette := _Palette;
for y := 0 to TIM.Tim_Image.Height - 1 do
begin
scanline := Result.Scanline[y];
for x := 0 to TIM.Tim_Image.Width - 1 do
TIM_Stream.Read(scanline[x],1);
end;
end;
Bpp_16: begin
TIM_Stream.Read(TIM.Tim_Image,SizeOf(Tim.Tim_Image));
Tim.Tim_Image.Width := TIM.Tim_Image.Width;
Result := TPngImage.Create;
Result.CreateBlank(COLOR_RGB,8,Tim.Tim_Image.Width,Tim.Tim_Image.Height);
for y := 0 to TIM.Tim_Image.Height - 1 do
begin
RGBScanline := Result.Scanline[y];
for x := 0 to TIM.Tim_Image.Width - 1 do
begin
TIM_Stream.Read(w,2);
GetRGB555(w,RGBScanline[x].rgbtRed,RGBScanline[x].rgbtGreen,RGBScanline[x].rgbtBlue);
end;
end;
end;
Bpp_24: begin
TIM_Stream.Read(TIM.Tim_Image,SizeOf(Tim.Tim_Image));
                 Tim.Tim_Image.Width := TIM.Tim_Image.Width * 2 div 3;
                 Result := TPngImage.Create;
                 Result.CreateBlank(COLOR_RGB,8,Tim.Tim_Image.Width,Tim.Tim_Image.Height);
                 for y := 0 to TIM.Tim_Image.Height - 1 do
                   begin
                     RGBScanline := Result.Scanline[y];
                     for x := 0 to TIM.Tim_Image.Width - 1 do
                        begin
                          TIM_Stream.Read(RGBScanline[x].rgbtRed,1);
                          TIM_Stream.Read(RGBScanline[x].rgbtGreen,1);
                          TIM_Stream.Read(RGBScanline[x].rgbtBlue,1);
                        end;
end;
end;
end;
end;
end;
Может кому пригодится ;)

Mefistotel


TTEMMA

Цитата: Mefistotel от 13 июня 2016, 23:17А обратная конверсия?)
Обратную я тоже написал, но она слегка "костыльная".
Её костыль в том, что если надо сохранить в 4bpp или 8bpp, то изображение(png) должно быть с палитрой, иначе не запакуется. Так же и с 16bpp и 24bpp, они должны быть строго в RGB, без палитры.
Я пока что не разбирался с квантованием цветов, но в будущем планирую

Greengh0st

Вот же блин, как народ в этом разбирается?)))) Ттемма как твои проекты?

TTEMMA