По быстрому накидал код для извлечения изображений из 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;
Может кому пригодится