Fully implemented TIM<->PNG converting. But it should be checked! Some other fixes.

This commit is contained in:
meffi@lab313.ru
2014-04-27 13:25:37 +00:00
parent 59bdb04762
commit 7ec4a64bc5
12 changed files with 421 additions and 314 deletions

View File

@@ -23,12 +23,188 @@
<UseVersionInfo Value="True"/>
<AutoIncrementBuild Value="True"/>
<MajorVersionNr Value="1"/>
<RevisionNr Value="67"/>
<BuildNr Value="5"/>
<RevisionNr Value="74"/>
<BuildNr Value="2"/>
<StringTable CompanyName="Lab 313" FileDescription="The best TIMs tool ever!:)" ProductVersion=""/>
</VersionInfo>
<BuildModes Count="1">
<Item1 Name="Default" Default="True"/>
<BuildModes Count="5">
<Item1 Name="Debug" Default="True"/>
<Item2 Name="Win Release x86">
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<Target>
<Filename Value="output\tim2view_$(TargetOS)"/>
</Target>
<SearchPaths>
<IncludeFiles Value="$(ProjOutDir);bgrabitmap"/>
<OtherUnitFiles Value="bgrabitmap"/>
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
</SearchPaths>
<Parsing>
<SyntaxOptions>
<UseAnsiStrings Value="False"/>
</SyntaxOptions>
</Parsing>
<CodeGeneration>
<SmartLinkUnit Value="True"/>
<TargetCPU Value="i386"/>
<TargetOS Value="win32"/>
<Optimizations>
<OptimizationLevel Value="3"/>
</Optimizations>
</CodeGeneration>
<Linking>
<Debugging>
<GenerateDebugInfo Value="False"/>
</Debugging>
<LinkSmart Value="True"/>
<Options>
<Win32>
<GraphicApplication Value="True"/>
</Win32>
</Options>
</Linking>
<Other>
<CompilerMessages>
<MsgFileName Value=""/>
</CompilerMessages>
<CompilerPath Value="$(CompPath)"/>
</Other>
</CompilerOptions>
</Item2>
<Item3 Name="Win Release x64">
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<Target>
<Filename Value="output\tim2view_$(TargetOS)"/>
</Target>
<SearchPaths>
<IncludeFiles Value="$(ProjOutDir);bgrabitmap"/>
<OtherUnitFiles Value="bgrabitmap"/>
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
</SearchPaths>
<Parsing>
<SyntaxOptions>
<UseAnsiStrings Value="False"/>
</SyntaxOptions>
</Parsing>
<CodeGeneration>
<SmartLinkUnit Value="True"/>
<TargetCPU Value="x86_64"/>
<TargetOS Value="win64"/>
<Optimizations>
<OptimizationLevel Value="3"/>
</Optimizations>
</CodeGeneration>
<Linking>
<Debugging>
<GenerateDebugInfo Value="False"/>
</Debugging>
<LinkSmart Value="True"/>
<Options>
<Win32>
<GraphicApplication Value="True"/>
</Win32>
</Options>
</Linking>
<Other>
<CompilerMessages>
<MsgFileName Value=""/>
</CompilerMessages>
<CompilerPath Value="$(CompPath)"/>
</Other>
</CompilerOptions>
</Item3>
<Item4 Name="Linux Release x86">
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<Target>
<Filename Value="output\tim2view_$(TargetOS)"/>
</Target>
<SearchPaths>
<IncludeFiles Value="$(ProjOutDir);bgrabitmap"/>
<OtherUnitFiles Value="bgrabitmap"/>
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
</SearchPaths>
<Parsing>
<SyntaxOptions>
<UseAnsiStrings Value="False"/>
</SyntaxOptions>
</Parsing>
<CodeGeneration>
<SmartLinkUnit Value="True"/>
<TargetCPU Value="i386"/>
<TargetOS Value="linux"/>
<Optimizations>
<OptimizationLevel Value="3"/>
</Optimizations>
</CodeGeneration>
<Linking>
<Debugging>
<GenerateDebugInfo Value="False"/>
</Debugging>
<LinkSmart Value="True"/>
<Options>
<Win32>
<GraphicApplication Value="True"/>
</Win32>
</Options>
</Linking>
<Other>
<CompilerMessages>
<MsgFileName Value=""/>
</CompilerMessages>
<CompilerPath Value="$(CompPath)"/>
</Other>
</CompilerOptions>
</Item4>
<Item5 Name="Linux Release x64">
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<Target>
<Filename Value="output\tim2view_$(TargetOS)"/>
</Target>
<SearchPaths>
<IncludeFiles Value="$(ProjOutDir);bgrabitmap"/>
<OtherUnitFiles Value="bgrabitmap"/>
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
</SearchPaths>
<Parsing>
<SyntaxOptions>
<UseAnsiStrings Value="False"/>
</SyntaxOptions>
</Parsing>
<CodeGeneration>
<SmartLinkUnit Value="True"/>
<TargetCPU Value="x86_64"/>
<TargetOS Value="linux"/>
<Optimizations>
<OptimizationLevel Value="3"/>
</Optimizations>
</CodeGeneration>
<Linking>
<Debugging>
<GenerateDebugInfo Value="False"/>
</Debugging>
<LinkSmart Value="True"/>
<Options>
<Win32>
<GraphicApplication Value="True"/>
</Win32>
</Options>
</Linking>
<Other>
<CompilerMessages>
<MsgFileName Value=""/>
</CompilerMessages>
<CompilerPath Value="$(CompPath)"/>
</Other>
</CompilerOptions>
</Item5>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
@@ -143,12 +319,14 @@
<Checks>
<RangeChecks Value="True"/>
<OverflowChecks Value="True"/>
<StackChecks Value="True"/>
</Checks>
<VerifyObjMethodCallValidity Value="True"/>
</CodeGeneration>
<Linking>
<Debugging>
<DebugInfoType Value="dsDwarf2Set"/>
<UseHeaptrc Value="True"/>
<UseExternalDbgSyms Value="True"/>
</Debugging>
<Options>
<Win32>

View File

@@ -3,13 +3,13 @@
<ProjectSession>
<PathDelim Value="\"/>
<Version Value="9"/>
<BuildModes Active="Default"/>
<Units Count="19">
<BuildModes Active="Win Release x86"/>
<Units Count="15">
<Unit0>
<Filename Value="tim2view.lpr"/>
<IsPartOfProject Value="True"/>
<UnitName Value="tim2view"/>
<EditorIndex Value="15"/>
<EditorIndex Value="11"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="46" Y="15"/>
@@ -25,8 +25,8 @@
<UnitName Value="umain"/>
<EditorIndex Value="0"/>
<WindowIndex Value="0"/>
<TopLine Value="912"/>
<CursorPos X="48" Y="918"/>
<TopLine Value="489"/>
<CursorPos X="63" Y="499"/>
<UsageCount Value="816"/>
<Loaded Value="True"/>
<LoadedDesigner Value="True"/>
@@ -55,7 +55,7 @@
<EditorIndex Value="4"/>
<WindowIndex Value="0"/>
<TopLine Value="14"/>
<CursorPos X="15" Y="35"/>
<CursorPos X="35" Y="6"/>
<UsageCount Value="816"/>
<Loaded Value="True"/>
</Unit4>
@@ -65,8 +65,8 @@
<UnitName Value="utim"/>
<EditorIndex Value="7"/>
<WindowIndex Value="0"/>
<TopLine Value="130"/>
<CursorPos X="1" Y="148"/>
<TopLine Value="185"/>
<CursorPos X="1" Y="204"/>
<UsageCount Value="816"/>
<Loaded Value="True"/>
</Unit5>
@@ -76,8 +76,8 @@
<UnitName Value="ucdimage"/>
<EditorIndex Value="1"/>
<WindowIndex Value="0"/>
<TopLine Value="189"/>
<CursorPos X="1" Y="204"/>
<TopLine Value="112"/>
<CursorPos X="50" Y="117"/>
<UsageCount Value="816"/>
<Loaded Value="True"/>
</Unit6>
@@ -96,7 +96,7 @@
<Filename Value="uscanresult.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="uscanresult"/>
<EditorIndex Value="16"/>
<EditorIndex Value="12"/>
<WindowIndex Value="0"/>
<TopLine Value="51"/>
<CursorPos X="1" Y="67"/>
@@ -109,8 +109,8 @@
<UnitName Value="uscanthread"/>
<EditorIndex Value="6"/>
<WindowIndex Value="0"/>
<TopLine Value="79"/>
<CursorPos X="76" Y="98"/>
<TopLine Value="155"/>
<CursorPos X="36" Y="168"/>
<UsageCount Value="816"/>
<Loaded Value="True"/>
</Unit9>
@@ -132,8 +132,8 @@
<IsVisibleTab Value="True"/>
<EditorIndex Value="8"/>
<WindowIndex Value="0"/>
<TopLine Value="177"/>
<CursorPos X="51" Y="198"/>
<TopLine Value="234"/>
<CursorPos X="61" Y="245"/>
<UsageCount Value="816"/>
<Loaded Value="True"/>
</Unit11>
@@ -149,10 +149,10 @@
<Unit13>
<Filename Value="todos.inc"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="14"/>
<EditorIndex Value="10"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="31" Y="2"/>
<CursorPos X="20" Y="1"/>
<UsageCount Value="802"/>
<Loaded Value="True"/>
</Unit13>
@@ -160,53 +160,13 @@
<Filename Value="uexportimport.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="uexportimport"/>
<EditorIndex Value="10"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="76" Y="22"/>
<UsageCount Value="41"/>
<Loaded Value="True"/>
</Unit14>
<Unit15>
<Filename Value="bgrabitmap\bgrabitmaptypes.pas"/>
<UnitName Value="BGRABitmapTypes"/>
<EditorIndex Value="12"/>
<WindowIndex Value="0"/>
<TopLine Value="1336"/>
<CursorPos X="1" Y="1343"/>
<UsageCount Value="16"/>
<Loaded Value="True"/>
</Unit15>
<Unit16>
<Filename Value="bgrabitmap\bgradefaultbitmap.pas"/>
<UnitName Value="BGRADefaultBitmap"/>
<EditorIndex Value="9"/>
<WindowIndex Value="0"/>
<TopLine Value="548"/>
<CursorPos X="1" Y="570"/>
<UsageCount Value="12"/>
<TopLine Value="13"/>
<CursorPos X="52" Y="19"/>
<UsageCount Value="53"/>
<Loaded Value="True"/>
</Unit16>
<Unit17>
<Filename Value="C:\Lazarus\fpc\2.6.4\source\packages\fcl-image\src\fpreadpng.pp"/>
<UnitName Value="FPReadPNG"/>
<EditorIndex Value="11"/>
<WindowIndex Value="0"/>
<TopLine Value="241"/>
<CursorPos X="46" Y="17"/>
<UsageCount Value="11"/>
<Loaded Value="True"/>
</Unit17>
<Unit18>
<Filename Value="bgrabitmap\bgrareadpng.pas"/>
<UnitName Value="BGRAReadPng"/>
<EditorIndex Value="13"/>
<WindowIndex Value="0"/>
<TopLine Value="141"/>
<CursorPos X="1" Y="161"/>
<UsageCount Value="10"/>
<Loaded Value="True"/>
</Unit18>
</Unit14>
</Units>
<General>
<ActiveWindowIndexAtStart Value="0"/>
@@ -225,24 +185,38 @@
<Kind Value="bpkSource"/>
<WatchScope Value="wpsLocal"/>
<WatchKind Value="wpkWrite"/>
<Source Value="umain.pas"/>
<Line Value="503"/>
<Source Value="c:\Lazarus\fpc\2.6.2\source\packages\fcl-image\src\fppalette.inc"/>
<Line Value="159"/>
</Item2>
<Item3>
<Kind Value="bpkSource"/>
<WatchScope Value="wpsLocal"/>
<WatchKind Value="wpkWrite"/>
<Source Value="c:\Lazarus\fpc\2.6.2\source\packages\fcl-image\src\fppalette.inc"/>
<Line Value="159"/>
<Source Value="umain.pas"/>
<Line Value="361"/>
</Item3>
<Item4>
<Kind Value="bpkSource"/>
<WatchScope Value="wpsLocal"/>
<WatchKind Value="wpkWrite"/>
<Source Value="udrawtim.pas"/>
<Line Value="258"/>
<Source Value="umain.pas"/>
<Line Value="767"/>
</Item4>
</BreakPoints>
<Watches Count="3">
<Item1>
<Expression Value="IDX"/>
<DisplayStyle Value="wdfHex"/>
</Item1>
<Item2>
<Expression Value="TData^[POS]"/>
<DisplayStyle Value="wdfHex"/>
</Item2>
<Item3>
<Expression Value="IDX_INT"/>
<DisplayStyle Value="wdfHex"/>
</Item3>
</Watches>
</Debugging>
<EditorMacros Count="0"/>
</CONFIG>

Binary file not shown.

View File

@@ -1,2 +1 @@
{ TODO : Zooming? }
{ TODO 1 : Export: save as paletted PNG. Import: find matched colors in CLUT when importing }

View File

@@ -78,14 +78,12 @@ begin
pFile := GetMemory(cSectorHeaderSize);
try
tmp := TFileStream.Create(Utf8ToSys(FileName), fmOpenRead or fmShareDenyWrite);
tmp.Read(pFile^[0], cSectorHeaderSize);
Result := ((Sz mod cSectorSize) = 0) and (CompareMem(@cSectorHeader, pFile, cSectorHeaderSize));
finally
tmp.free;
FreeMemory(pFile);
end;
tmp := TFileStream.Create(Utf8ToSys(FileName), fmOpenRead or fmShareDenyWrite);
tmp.Read(pFile^[0], cSectorHeaderSize);
Result := ((Sz mod cSectorSize) = 0) and (CompareMem(@cSectorHeader, pFile, cSectorHeaderSize));
tmp.free;
FreeMemory(pFile);
end;
procedure ReplaceTimInFileFromMemory(const FileName: string; TIM: PTIM;
@@ -124,7 +122,7 @@ begin
FillChar(Sector, cSectorSize, 0);
sImageStream.Read(Sector, cSectorSize);
sImageStream.Seek(TimStartSectorPos + cSectorHeaderSize, soBeginning);
sImageStream.Seek(Int64(TimStartSectorPos) + Int64(cSectorHeaderSize), soBeginning);
Move(Sector.dwAddress[0], SecAddrAndMode[0], cSectorAddressSize + cSectorModeSize);
FillChar(Sector.dwAddress[0], cSectorAddressSize + cSectorModeSize, 0);
@@ -140,7 +138,7 @@ begin
sImageStream.Seek(TimStartSectorPos, soBeginning);
sImageStream.Write(Sector, cSectorSize);
sImageStream.Seek(TimStartSectorPos + cSectorHeaderSize, soBeginning);
sImageStream.Seek(Int64(TimStartSectorPos) + Int64(cSectorHeaderSize), soBeginning);
sImageStream.Write(SecAddrAndMode[0], cSectorAddressSize + cSectorModeSize);
Inc(TimStartSectorPos, cSectorSize);
@@ -167,7 +165,7 @@ begin
sImageStream.Seek(TimStartSectorPos, soBeginning);
sImageStream.Write(Sector, cSectorSize);
sImageStream.Seek(TimStartSectorPos + cSectorHeaderSize, soBeginning);
sImageStream.Seek(Int64(TimStartSectorPos) + Int64(cSectorHeaderSize), soBeginning);
sImageStream.Write(SecAddrAndMode[0], cSectorAddressSize + cSectorModeSize);
Inc(TimStartSectorPos, cSectorSize);
@@ -195,7 +193,7 @@ begin
sImageStream.Seek(TimStartSectorPos, soBeginning);
sImageStream.Write(Sector, cSectorSize);
sImageStream.Seek(TimStartSectorPos + cSectorHeaderSize, soBeginning);
sImageStream.Seek(Int64(TimStartSectorPos) + Int64(cSectorHeaderSize), soBeginning);
sImageStream.Write(SecAddrAndMode[0], cSectorAddressSize + cSectorModeSize);
end;
end;

View File

@@ -3,7 +3,7 @@ unit ucommon;
interface
const
cProgramName = 'Tim2View SVN.r70 by [Lab 313] (for ' +
cProgramName = 'Tim2View SVN.r74 by [Lab 313] (for ' +
{$IFDEF Linux}'Linux' + {$IFEND}
{$IFDEF Darwin}'Mac OS X' + {$IFEND}
{$IFDEF Windows}'Windows' + {$IFEND}

View File

@@ -92,17 +92,17 @@ begin
CC := GetCLUTColor(TIM, CLUT_NUM, I - 1);
if I <= COUNT then
begin
R := CC.R;
G := CC.G;
B := CC.B;
R := CC.R + ((I - 1) and %00000011) shl 1 + CC.STP;
G := CC.G + ((I - 1) and %00011100) shr 2;
B := CC.B + ((I - 1) and %11100000) shr 5;
A := CC.STP;
end
else
begin
R := 0;
G := 0;
B := 0;
A := 1;
R := ((I - 1) and %00000011) shl 1 + CC.STP;
G := ((I - 1) and %00011100) shr 2;
B := ((I - 1) and %11100000) shr 5;
A := 0;
end;
FC := BGRAToFPColor(BGRA(R, G, B, A));
@@ -209,7 +209,8 @@ begin
for X := 1 to RW do
begin
case TIM^.HEAD^.bBPP of
cTIM4C, cTIM4NC, cTIM8C, cTIM8NC: Surf^.Pixels[X - 1, Y - 1] := INDEXES^[IDX] mod COLORS;
cTIM4C, cTIM4NC, cTIM8C, cTIM8NC:
Surf^.Pixels[X - 1, Y - 1] := INDEXES^[IDX] mod COLORS;
cTIM16C, cTIM16NC, cTIMMix:
begin
CW := 0;
@@ -243,7 +244,7 @@ procedure Png2Tim(Image: PDrawSurf; Dest: PTIM);
var
IW, IH, X, Y, CW: Word;
TData: PTIMDataArray;
IDX, POS, C: Integer;
POS: Integer;
CC: TCLUT_COLOR;
PC: TBGRAPixel;
FC: TFPColor;
@@ -253,33 +254,29 @@ begin
IH := Image^.Height;
TData := @Dest^.DATA^[SizeOf(TTIMHeader) + GetTIMCLUTSize(Dest) + SizeOf(TIMAGEHeader)];
{ TODO : Fix colors finding. }
POS := 0;
for Y := 1 to IH do
for Y := 0 to IH-1 do
case Dest^.HEAD^.bBPP of
cTIM4C, cTIM4NC:
for X := 1 to (IW div 2) do
for X := 0 to (IW div 2)-1 do
begin
IDX := Image^.Pixels[X - 1, Y - 1];
TData^[POS] := (IDX and $F);
IDX := Image^.Pixels[X, Y - 1];
TData^[POS] := TData^[0] + (IDX and $F0);
TData^[POS] := Byte(Image^.Pixels[X * 2, Y]);
TData^[POS] := (Byte(Image^.Pixels[X * 2 + 1, Y]) shl 4) and $F0 + TData^[POS];
Inc(POS);
end;
cTIM8C, cTIM8NC:
for X := 1 to IW do
for X := 0 to IW-1 do
begin
C := Image^.Pixels[X - 1, Y - 1];
TData^[POS] := Byte(C);
TData^[POS] := Byte(Image^.Pixels[X, Y]);
Inc(POS);
end;
cTIM16C, cTIM16NC:
for X := 1 to IW do
for X := 0 to IW-1 do
begin
FC := Image^.Colors[X - 1, Y - 1];
FC := Image^.Colors[X, Y];
CC.STP := StpFromAlpha(@FC);
PC := FPColorToBGRA(FC);
CC.R := PC.red;
@@ -293,16 +290,16 @@ begin
end;
cTIM24C, cTIM24NC:
for X := 1 to IW do
for X := 0 to IW-1 do
begin
FC := Image^.Colors[X - 1, Y - 1];
FC := Image^.Colors[X, Y];
PC := FPColorToBGRA(FC);
CD := (PC.blue shl 16) + (PC.green shl 8) + PC.red;
Move(CD, TData^[POS], 3);
Inc(POS, 3);
if Odd(IW) and ((IW - X) = 0) then
if Odd(IW) and ((IW - X + 1) = 0) then
begin
TData^[POS] := 0;
Inc(POS);

View File

@@ -3,55 +3,44 @@ unit uexportimport;
interface
uses
FPWritePNG, zstream, udrawtim;
udrawtim;
procedure SaveImage(Surf: PDrawSurf; Indexed: Boolean; const FileName: string; PngWriter: TFPWriterPNG);
function LoadImage(const FileName: string; var Surf: PDrawSurf): Boolean;
function CreatePngWriter(ForExport: Boolean): TFPWriterPNG;
procedure SaveImage(const FileName: string; Surf: PDrawSurf; Indexed: Boolean);
function LoadImage(const FileName: string): PDrawSurf;
implementation
uses
FPReadPNG, Classes, BGRABitmap, FileUtil, sysutils;
FPReadPNG, Classes, BGRABitmap, FileUtil, sysutils, zstream, FPWritePNG;
function CreatePngWriter(ForExport: Boolean): TFPWriterPNG;
procedure SaveImage(const FileName: string; Surf: PDrawSurf; Indexed: Boolean);
var
Writer: TFPWriterPNG;
begin
Result := TFPWriterPNG.Create;
Result.CompressionLevel := clnone;
Result.WordSized := False;
Result.UseAlpha := (not ForExport);
Writer := TFPWriterPNG.Create;
Writer.CompressionLevel := clnone;
Writer.UseAlpha := True;
Writer.Indexed := Indexed;
Surf^.SaveToFileUTF8(FileName, Writer);
Writer.Free;
end;
procedure SaveImage(Surf: PDrawSurf; Indexed: Boolean; const FileName: string; PngWriter: TFPWriterPNG);
begin
PngWriter.Indexed := Indexed;
Surf^.SaveToFileUTF8(FileName, PngWriter);
end;
function LoadImage(const FileName: string; var Surf: PDrawSurf): Boolean;
function LoadImage(const FileName: string): PDrawSurf;
var
Reader: TFPReaderPNG;
Image: TFileStream;
Stream: TFileStream;
begin
Result := False;
try
Reader := TFPReaderPNG.Create;
Image := TFileStream.Create(UTF8ToSys(FileName), fmOpenRead or fmShareDenyWrite);
Result := Reader.CheckContents(Image);
Stream := TFileStream.Create(UTF8ToSys(FileName), fmOpenRead or fmShareDenyWrite);
Stream.Position := 0;
if Result then
begin
New(Surf);
Surf^ := TBGRABitmap.Create;
Image.Position := 0;
Surf^.LoadFromStream(Image);
end;
finally
Image.Free;
Reader.Free;
end;
New(Result);
Result^ := TBGRABitmap.Create;
Result^.UsePalette := True;
Reader.ImageRead(Stream, Result^);
Stream.Free;
Reader.Free;
end;
end.

View File

@@ -828,12 +828,12 @@ object frmMain: TfrmMain
DefaultExt = '.bin'
Filter = 'All Files (*.*)|*.*'
Options = [ofHideReadOnly, ofNoChangeDir, ofAllowMultiSelect, ofNoNetworkButton, ofEnableSizing, ofForceShowHidden]
left = 576
top = 448
left = 560
top = 112
end
object mmMain: TMainMenu
left = 352
top = 448
left = 336
top = 112
object mnFile: TMenuItem
Caption = '&File'
object mnScanFile: TMenuItem
@@ -863,16 +863,13 @@ object frmMain: TfrmMain
object mnReplaceIn: TMenuItem
Action = actReplaceTim
end
object mnSaveToPNG: TMenuItem
Action = actTim2Png
object MenuItem1: TMenuItem
Caption = '-'
end
end
object mnEdit: TMenuItem
Caption = '&Edit'
object mnExportTim: TMenuItem
object mnSaveToPNG: TMenuItem
Action = actPngExport
end
object mnImport: TMenuItem
object mnImportPng: TMenuItem
Action = actPngImport
end
end
@@ -912,17 +909,17 @@ object frmMain: TfrmMain
Title = 'Please, select filename for PNG...'
DefaultExt = '.png'
Filter = 'Portable Network Graphics (*.png)|*.png'
Options = [ofHideReadOnly, ofNoChangeDir, ofNoNetworkButton, ofEnableSizing]
left = 688
top = 448
Options = [ofOverwritePrompt, ofHideReadOnly, ofNoChangeDir, ofNoNetworkButton, ofEnableSizing]
left = 672
top = 112
end
object dlgSaveTIM: TSaveDialog
Title = 'Please, select where to save TIM file...'
DefaultExt = '.tim'
Filter = 'PSX TIM Files (*.tim)|*.tim|All Files (*.*)|*.*'
Options = [ofOverwritePrompt, ofHideReadOnly, ofNoChangeDir, ofNoNetworkButton, ofEnableSizing]
left = 608
top = 448
left = 592
top = 112
end
object dlgColor: TColorDialog
Color = clBlack
@@ -948,12 +945,12 @@ object frmMain: TfrmMain
'ColorS=F0FBFF'
'ColorT=A4A0A0'
)
left = 496
top = 448
left = 480
top = 112
end
object actList: TActionList
left = 416
top = 448
left = 400
top = 112
object actScanFile: TAction
Caption = 'Scan &File...'
OnExecute = actScanFileExecute
@@ -984,14 +981,18 @@ object frmMain: TfrmMain
OnExecute = actExtractTimExecute
ShortCut = 113
end
object actPngImport: TAction
Caption = '&Import PNG...'
OnExecute = actPngImportExecute
end
object actReplaceTim: TAction
Caption = '&Replace TIM...'
OnExecute = actReplaceTimExecute
ShortCut = 114
end
object actTim2Png: TAction
Caption = 'Save as &PNG...'
OnExecute = actTim2PngExecute
object actPngExport: TAction
Caption = 'Export &PNG...'
OnExecute = actPngExportExecute
ShortCut = 115
end
object actOpenRepo: TAction
@@ -1043,18 +1044,10 @@ object frmMain: TfrmMain
Caption = '&Background Color'
OnExecute = actChangeBackColorExecute
end
object actPngImport: TAction
Caption = '&Import PNG to TIM...'
OnExecute = actPngImportExecute
end
object actPngExport: TAction
Caption = '&Export TIM to PNG...'
OnExecute = actTim2PngExecute
end
end
object pmList: TPopupMenu
left = 448
top = 448
left = 432
top = 112
object ExtractTIM1: TMenuItem
Action = actExtractTim
end
@@ -1062,7 +1055,7 @@ object frmMain: TfrmMain
Action = actReplaceTim
end
object SaveasPNG1: TMenuItem
Action = actTim2Png
Action = actPngExport
end
object N7: TMenuItem
Caption = '-'
@@ -1075,10 +1068,10 @@ object frmMain: TfrmMain
end
end
object pmImage: TPopupMenu
left = 384
top = 448
left = 368
top = 112
object mnSaveAsPng: TMenuItem
Action = actTim2Png
Action = actPngExport
end
object mnSaveAsTim: TMenuItem
Action = actExtractTim
@@ -1096,15 +1089,15 @@ object frmMain: TfrmMain
end
object dlgSelectDir: TSelectDirectoryDialog
Options = [ofNoChangeDir, ofNoNetworkButton, ofEnableSizing, ofViewDetail]
left = 528
top = 448
left = 512
top = 112
end
object dlgOpenPNG: TOpenPictureDialog
Title = 'Please, select PNG...'
DefaultExt = '.png'
Filter = 'Portable Network Graphics (*.png)|*.png'
Options = [ofHideReadOnly, ofNoChangeDir, ofNoNetworkButton, ofEnableSizing]
left = 656
top = 448
left = 640
top = 112
end
end

105
umain.pas
View File

@@ -28,7 +28,6 @@ type
actExtractTIMs: TAction;
actChangeFile: TAction;
actChangeBackColor: TAction;
actPngExport: TAction;
actPngImport: TAction;
actStopScan: TAction;
actOpenLab: TAction;
@@ -39,7 +38,7 @@ type
actScanFile: TAction;
actList: TActionList;
actStretch: TAction;
actTim2Png: TAction;
actPngExport: TAction;
btnExtractAllTims: TButton;
btnExtractPNGs: TButton;
btnShowClut: TButton;
@@ -57,9 +56,8 @@ type
imgTim: TImage;
lblStatus: TLabel;
lvList: TListView;
mnImport: TMenuItem;
mnExportTim: TMenuItem;
mnEdit: TMenuItem;
MenuItem1: TMenuItem;
mnImportPng: TMenuItem;
mnChangeBackColor2: TMenuItem;
N8: TMenuItem;
mnChangeBackColor: TMenuItem;
@@ -126,7 +124,7 @@ type
procedure actScanFileExecute(Sender: TObject);
procedure actStopScanExecute(Sender: TObject);
procedure actStretchExecute(Sender: TObject);
procedure actTim2PngExecute(Sender: TObject);
procedure actPngExportExecute(Sender: TObject);
procedure btnShowClutClick(Sender: TObject);
procedure cbbBitModeChange(Sender: TObject);
procedure cbbTranspModeChange(Sender: TObject);
@@ -156,9 +154,8 @@ type
function FGetTimInfoByIdx(Index: Integer): TTimInfo;
property TimInfoByIdx[Index: Integer]: TTimInfo read FGetTimInfoByIdx; //Info about tim by index
function FGetSelectedTim(NewBitMode: Integer): PTIM;
property SelectedTim: PTIM Index $FF read FGetSelectedTim; //Tim, selected in list
property SelectedTimInMode[NewBitMode: Integer]: PTIM read FGetSelectedTim; //Tim, selected in list
function FGetSelectedTim: PTIM;
property SelectedTimInMode: PTIM read FGetSelectedTim; //Tim, selected in list
procedure ScanPath(const Path: string);
procedure ScanFile(const FileName: string);
@@ -188,7 +185,7 @@ var
implementation
uses ucdimage, ucpucount, lcltype, ucommon, LCLIntf, uexportimport, FPWritePNG
uses ucdimage, ucpucount, lcltype, ucommon, LCLIntf, uexportimport
{$IFDEF windows}
,registry
@@ -237,21 +234,18 @@ begin
UpdateTim(True, False, False);
end;
procedure TfrmMain.actTim2PngExecute(Sender: TObject);
procedure TfrmMain.actPngExportExecute(Sender: TObject);
var
TIM: PTIM;
Writer: TFPWriterPNG;
begin
TIM := SelectedTim;
TIM := SelectedTimInMode;
if TIM = nil then Exit;
dlgSavePNG.FileName := FormatPngName(SelectedScanResult.ScanFile, TIM^.dwTimNumber, SelectedTimInfo.BitMode, cbbCLUT.ItemIndex);
if not dlgSavePNG.Execute then Exit;
Writer := CreatePngWriter((Sender as TAction) = actPngExport);
SaveImage(Surf, TIMisIndexed(TIM), dlgSavePNG.FileName, Writer);
Writer.Free;
SaveImage(dlgSavePNG.FileName, Surf, TIMisIndexed(TIM));
FreeTIM(TIM);
{$IFDEF Linux}FpChmod(dlgSavePNG.FileName, &777){$IFEND}
end;
@@ -265,6 +259,17 @@ end;
procedure TfrmMain.cbbBitModeChange(Sender: TObject);
begin
case cbbBitMode.ItemIndex of
1: cbbBitMode.Tag := NativeInt(cTIM4C);
2: cbbBitMode.Tag := NativeInt(cTIM4NC);
3: cbbBitMode.Tag := NativeInt(cTIM8C);
4: cbbBitMode.Tag := NativeInt(cTIM8NC);
5: cbbBitMode.Tag := NativeInt(cTIM16NC);
6: cbbBitMode.Tag := NativeInt(cTIM24NC);
else
cbbBitMode.Tag := NativeInt($FF);
end;
UpdateTim(True, False, False);
end;
@@ -284,7 +289,7 @@ begin
lvList.Items[0].Focused := True;
lvList.Items[0].Selected := True;
ShowTim;
//ShowTim;
end;
procedure TfrmMain.actAboutExecute(Sender: TObject);
@@ -377,18 +382,15 @@ var
IsImage: Boolean;
ScanTim: TTimInfo;
TIM: PTIM;
Surf_: PDrawSurf;
Writer: TFPWriterPNG;
PNG: PDrawSurf;
begin
lblStatus.Caption := sStatusBarPngsExtracting;
FName := SelectedScanResult.ScanFile;
IsImage := SelectedScanResult.IsImage;
New(Surf_);
Surf_^ := nil;
Writer := CreatePngWriter(False);
New(PNG);
PNG^ := nil;
pbProgress.Position := 0;
pbProgress.Max := SelectedScanResult.Count;
@@ -405,21 +407,20 @@ begin
CreateDirUTF8(Path);
TIM := LoadTimFromFile(FName, OFFSET, IsImage, SIZE);
Tim2Png(TIM, cbbCLUT.ItemIndex, Surf_, cbbTranspMode.ItemIndex);
Tim2Png(TIM, cbbCLUT.ItemIndex, PNG, cbbTranspMode.ItemIndex);
Path := Path + FormatPngName(FName, I - 1, BIT_MODE, 0);
SaveImage(Surf_, TIMisIndexed(TIM), Path, Writer);
SaveImage(Path, PNG, TIMisIndexed(TIM));
{$IFDEF Linux}FpChmod(Path, &777){$IFEND}
Surf_^.Free;
Surf_^ := nil;
PNG^.Free;
PNG^ := nil;
FreeTIM(TIM);
pbProgress.Position := I;
Application.ProcessMessages;
end;
Dispose(Surf_);
Writer.Free;
Dispose(PNG);
lblStatus.Caption := sStatusBarExtracted;
pbProgress.Position := 0;
end;
@@ -432,7 +433,7 @@ begin
if not dlgSaveTIM.Execute then Exit;
TIM := SelectedTim;
TIM := SelectedTimInMode;
SaveTimToFile(dlgSaveTIM.FileName, TIM);
{$IFDEF Linux}FpChmod(dlgSaveTIM.FileName, &777){$IFEND}
FreeTIM(TIM);
@@ -495,13 +496,12 @@ var
ScanRes: TScanResult;
begin
if not dlgOpenPNG.Execute then Exit;
if not LoadImage(dlgOpenPNG.FileName, Image) then Exit;
TIM := SelectedTim;
TIM := SelectedTimInMode;
if TIM = nil then Exit;
Image := LoadImage(dlgOpenPNG.FileName);
Png2Tim(Image, TIM);
SaveTimToFile('test.tim', TIM);
ScanRes := SelectedScanResult;
ReplaceTimInFileFromMemory(ScanRes.ScanFile, TIM, SelectedTimInfo.Position, ScanRes.IsImage);
ShowTim;
@@ -561,6 +561,8 @@ procedure TfrmMain.FormCreate(Sender: TObject);
begin
Settings := TSettings.Create(ExtractFilePath(ParamStrUTF8(0)));
cbbBitMode.Tag := NativeInt($FF);
actStretch.Checked := Settings.StretchMode;
cbbTranspMode.ItemIndex := Settings.TranspMode;
LastDir := Settings.LastDir;
@@ -598,7 +600,7 @@ var
R, G, B: Byte;
CLUT_COLOR: TCLUT_COLOR;
begin
TIM := SelectedTim;
TIM := SelectedTimInMode;
if TIM = nil then Exit;
SELECTED_CELL := grdClut.Row * grdClut.ColCount + grdClut.Col;
@@ -654,7 +656,7 @@ procedure TfrmMain.grdClutDrawCell(Sender: TObject; aCol, aRow: Integer;
var
TIM: PTIM;
begin
TIM := SelectedTim;
TIM := SelectedTimInMode;
if TIM = nil then Exit;
if not TIMHasCLUT(TIM) then
@@ -712,7 +714,7 @@ begin
Result := SelectedScanResult.ScanTim[Index];
end;
function TfrmMain.FGetSelectedTim(NewBitMode: Integer): PTIM;
function TfrmMain.FGetSelectedTim: PTIM;
var
P: Integer;
begin
@@ -723,8 +725,8 @@ begin
P := SelectedTimInfo.Position;
Result := LoadTimFromFile(SelectedScanResult.ScanFile, P, SelectedScanResult.IsImage, SelectedTimInfo.Size);
if NewBitMode = $FF then Exit;
Result^.HEAD^.bBPP := NewBitMode;
if Integer(cbbBitMode.Tag) = $FF then Exit;
Result^.HEAD^.bBPP := Integer(cbbBitMode.Tag);
end;
function TfrmMain.CheckForFileOpened(const FileName: string): boolean;
@@ -818,7 +820,7 @@ begin
actCloseFiles.Enabled := cbbFiles.Enabled;
actReplaceTim.Enabled := (lvList.Selected <> nil) and (lvList.Selected.Index <> -1);
actTim2Png.Enabled := (Surf^ <> nil) and actReplaceTim.Enabled;
actPngExport.Enabled := (Surf^ <> nil) and actReplaceTim.Enabled;
actExtractTim.Enabled := actReplaceTim.Enabled;
pnlImageOptions.Enabled := actReplaceTim.Enabled;
@@ -871,7 +873,7 @@ var
TIM: PTIM;
I, CLUTS: Word;
begin
TIM := SelectedTim;
TIM := SelectedTimInMode;
if TIM = nil then Exit;
CLUTS := GetTIMClutsCount(TIM);
@@ -892,28 +894,13 @@ end;
procedure TfrmMain.DrawSelTim;
var
TIM: PTIM;
Index: Integer;
mode: Byte;
begin
imgTim.Picture.Bitmap := nil;
case cbbBitMode.ItemIndex of
1: mode := cTIM4C;
2: mode := cTIM4NC;
3: mode := cTIM8C;
4: mode := cTIM8NC;
5: mode := cTIM16NC;
6: mode := cTIM24NC;
else
mode := $FF;
end;
TIM := SelectedTimInMode[mode];
TIM := SelectedTimInMode;
if TIM = nil then Exit;
Index := cbbCLUT.ItemIndex;
Tim2Png(TIM, Index, Surf, cbbTranspMode.ItemIndex);
Tim2Png(TIM, cbbCLUT.ItemIndex, Surf, cbbTranspMode.ItemIndex);
imgTim.Picture.Bitmap := Surf^.Bitmap;
FreeTIM(TIM);
@@ -928,7 +915,7 @@ begin
ClearGrid(@grdClut);
TIM := SelectedTim;
TIM := SelectedTimInMode;
if TIM = nil then
begin
grdClut.ColCount := 1;
@@ -995,7 +982,7 @@ begin
if not ShowInfo then Exit;
TimInfo := SelectedTimInfo;
TIM := SelectedTim;
TIM := SelectedTimInMode;
I := 0;

View File

@@ -89,11 +89,10 @@ var
begin
Synchronize(@StartScan);
try
if pScanResult.IsImage then
pSectorBufferSize := cSectorBufferSize
else
pSectorBufferSize := cClearBufferSize;
if pScanResult.IsImage then
pSectorBufferSize := cSectorBufferSize
else
pSectorBufferSize := cClearBufferSize;
pClearBufferSize := cClearBufferSize;
@@ -122,8 +121,8 @@ begin
begin
if pScanResult.IsImage then
pTimPosition := pFilePos - pRealBufSize +
((pClearBufferPosition - 1) div cSectorDataSize) * cSectorSize +
((pClearBufferPosition - 1) mod cSectorDataSize) + cSectorInfoSize
((pClearBufferPosition - 1) div cSectorDataSize) * cSectorSize +
((pClearBufferPosition - 1) mod cSectorDataSize) + cSectorInfoSize
else
pTimPosition := pFilePos - pRealBufSize + (pClearBufferPosition - 1);
@@ -147,7 +146,7 @@ begin
begin
if pRealBufSize >= (pSectorBufferSize div 2) then
// Need to check file size
pRealBufSize := pRealBufSize - (pSectorBufferSize div 2);
pRealBufSize := pRealBufSize - (pSectorBufferSize div 2);
end
else
begin
@@ -161,18 +160,17 @@ begin
ClearSectorBuffer(SectorBuffer, ClearBuffer);
end;
end;
finally
FreeTIM(TIM);
FreeMemory(SectorBuffer);
FreeMemory(ClearBuffer);
pSrcFileStream.Free;
pStopScan := True;
pFilePos := 0;
pStatusText := '';
FreeTIM(TIM);
FreeMemory(SectorBuffer);
FreeMemory(ClearBuffer);
Synchronize(@FinishScan);
end;
pSrcFileStream.Free;
pStopScan := True;
pFilePos := 0;
pStatusText := '';
Synchronize(@FinishScan);
end;
procedure TScanThread.FinishScan;

View File

@@ -149,7 +149,7 @@ end;
function ConvertCLUTColor(COLOR: TCLUT_COLOR): word;
begin
Result := (COLOR.STP shl 15) or ((COLOR.B div 8) shl 10) or ((COLOR.G div 8) shl 5) or (COLOR.R div 8);
Result := Word(COLOR.STP shl 15) or Word((COLOR.B div 8) shl 10) or Word((COLOR.G div 8) shl 5) or Word(COLOR.R div 8);
end;
function GetCLUTColor(TIM: PTIM; CLUT_NUM, COLOR_NUM: Integer): TCLUT_COLOR;
@@ -353,57 +353,55 @@ var
Sector: TCDSector;
P, TIM_FULL_SECTORS: Integer;
begin
try
sImageStream := TFileStream.Create(UTF8ToSys(FileName), fmOpenRead or fmShareDenyWrite);
sImageStream := TFileStream.Create(UTF8ToSys(FileName), fmOpenRead or fmShareDenyWrite);
TimSectorNumber := Position div cSectorSize + 1;
TimOffsetInSector := Position mod cSectorSize - cSectorInfoSize;
TimStartSectorPos := (TimSectorNumber - 1) * cSectorSize;
FirstPartSize := cSectorDataSize - TimOffsetInSector;
TimSectorNumber := Position div cSectorSize + 1;
TimOffsetInSector := Position mod cSectorSize - cSectorInfoSize;
TimStartSectorPos := (TimSectorNumber - 1) * cSectorSize;
FirstPartSize := cSectorDataSize - TimOffsetInSector;
New(TIM_BUF);
P := 0;
New(TIM_BUF);
P := 0;
if SIZE < FirstPartSize then FirstPartSize := SIZE;
if SIZE < FirstPartSize then FirstPartSize := SIZE;
sImageStream.Seek(TimStartSectorPos, soBeginning);
sImageStream.Seek(TimStartSectorPos, soBeginning);
sImageStream.Read(Sector, cSectorSize);
Move(Sector.dwData[TimOffsetInSector], TIM_BUF^[P], FirstPartSize);
Inc(P, FirstPartSize);
Inc(TimStartSectorPos, cSectorSize);
sImageStream.Seek(TimStartSectorPos, soBeginning);
TIM_FULL_SECTORS := (SIZE - P) div cSectorDataSize;
while TIM_FULL_SECTORS > 0 do
begin
sImageStream.Read(Sector, cSectorSize);
Move(Sector.dwData[TimOffsetInSector], TIM_BUF^[P], FirstPartSize);
Inc(P, FirstPartSize);
Move(Sector.dwData[0], TIM_BUF^[P], cSectorDataSize);
Inc(P, cSectorDataSize);
Inc(TimStartSectorPos, cSectorSize);
sImageStream.Seek(TimStartSectorPos, soBeginning);
TIM_FULL_SECTORS := (SIZE - P) div cSectorDataSize;
while TIM_FULL_SECTORS > 0 do
begin
sImageStream.Read(Sector, cSectorSize);
Move(Sector.dwData[0], TIM_BUF^[P], cSectorDataSize);
Inc(P, cSectorDataSize);
Inc(TimStartSectorPos, cSectorSize);
sImageStream.Seek(TimStartSectorPos, soBeginning);
Dec(TIM_FULL_SECTORS);
end;
sImageStream.Read(Sector, cSectorSize);
if SIZE > P then
begin
LastPartSize := SIZE - P;
Move(Sector.dwData[0], TIM_BUF^[P], LastPartSize);
end;
finally
P := 0;
Result := nil;
LoadTimFromBuf(TIM_BUF, Result, P);
sImageStream.Free;
Dispose(TIM_BUF);
Dec(TIM_FULL_SECTORS);
end;
sImageStream.Read(Sector, cSectorSize);
if SIZE > P then
begin
LastPartSize := SIZE - P;
Move(Sector.dwData[0], TIM_BUF^[P], LastPartSize);
end;
P := 0;
Result := nil;
LoadTimFromBuf(TIM_BUF, Result, P);
sImageStream.Free;
Dispose(TIM_BUF);
end;
function LoadTimFromStream(Stream: TStream; var Position: Integer;
@@ -433,18 +431,14 @@ function LoadTimFromFile(const FileName: string; var Position: Integer;
var
sTIM: TFileStream;
begin
if not ImageScan then
if ImageScan then
Result := LoadTimFromCDFile(FileName, Position, dwSize)
else
begin
try
sTIM := TFileStream.Create(UTF8ToSys(FileName), fmOpenRead or fmShareDenyWrite);
Result := LoadTimFromStream(sTIM, Position, dwSize);
finally
sTIM.Free;
end;
Exit;
sTIM := TFileStream.Create(UTF8ToSys(FileName), fmOpenRead or fmShareDenyWrite);
Result := LoadTimFromStream(sTIM, Position, dwSize);
sTIM.Free;
end;
Result := LoadTimFromCDFile(FileName, Position, dwSize);
end;
procedure SaveTimToFile(const FileName: string; TIM: PTIM);