Fixed view with transparence. Fixed Another bit mode view. All extractable PNGs are paletted if TIM is such one. Preparing to Tim<->Png converting.

This commit is contained in:
meffi@lab313.ru
2014-04-24 17:24:09 +00:00
parent e2f38ea43d
commit b954de5b12
11 changed files with 262 additions and 195 deletions

View File

@@ -24,7 +24,7 @@
<AutoIncrementBuild Value="True"/> <AutoIncrementBuild Value="True"/>
<MajorVersionNr Value="1"/> <MajorVersionNr Value="1"/>
<RevisionNr Value="67"/> <RevisionNr Value="67"/>
<BuildNr Value="2"/> <BuildNr Value="4"/>
<StringTable CompanyName="Lab 313" FileDescription="The best TIMs tool ever!:)" ProductVersion=""/> <StringTable CompanyName="Lab 313" FileDescription="The best TIMs tool ever!:)" ProductVersion=""/>
</VersionInfo> </VersionInfo>
<BuildModes Count="1"> <BuildModes Count="1">
@@ -43,7 +43,7 @@
<PackageName Value="LCL"/> <PackageName Value="LCL"/>
</Item1> </Item1>
</RequiredPackages> </RequiredPackages>
<Units Count="14"> <Units Count="15">
<Unit0> <Unit0>
<Filename Value="tim2view.lpr"/> <Filename Value="tim2view.lpr"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
@@ -116,6 +116,11 @@
<Filename Value="todos.inc"/> <Filename Value="todos.inc"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
</Unit13> </Unit13>
<Unit14>
<Filename Value="uexportimport.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="uexportimport"/>
</Unit14>
</Units> </Units>
</ProjectOptions> </ProjectOptions>
<CompilerOptions> <CompilerOptions>

View File

@@ -8,7 +8,7 @@ uses
{$ENDIF} {$ENDIF}
Interfaces, // this includes the LCL widgetset Interfaces, // this includes the LCL widgetset
Forms, umain, edc, ucommon, ecc, ucdimage, utim, usettings, uscanresult, Forms, umain, edc, ucommon, ecc, ucdimage, utim, usettings, uscanresult,
uscanthread, ucpucount, udrawtim, BGRABitmap; uscanthread, ucpucount, udrawtim, BGRABitmap, uexportimport;
{$R *.res} {$R *.res}

View File

@@ -4,16 +4,16 @@
<PathDelim Value="\"/> <PathDelim Value="\"/>
<Version Value="9"/> <Version Value="9"/>
<BuildModes Active="Default"/> <BuildModes Active="Default"/>
<Units Count="14"> <Units Count="15">
<Unit0> <Unit0>
<Filename Value="tim2view.lpr"/> <Filename Value="tim2view.lpr"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="tim2view"/> <UnitName Value="tim2view"/>
<EditorIndex Value="8"/> <EditorIndex Value="11"/>
<WindowIndex Value="0"/> <WindowIndex Value="0"/>
<TopLine Value="1"/> <TopLine Value="1"/>
<CursorPos X="52" Y="16"/> <CursorPos X="46" Y="14"/>
<UsageCount Value="40"/> <UsageCount Value="816"/>
<Loaded Value="True"/> <Loaded Value="True"/>
</Unit0> </Unit0>
<Unit1> <Unit1>
@@ -23,11 +23,12 @@
<HasResources Value="True"/> <HasResources Value="True"/>
<ResourceBaseClass Value="Form"/> <ResourceBaseClass Value="Form"/>
<UnitName Value="umain"/> <UnitName Value="umain"/>
<IsVisibleTab Value="True"/>
<EditorIndex Value="0"/> <EditorIndex Value="0"/>
<WindowIndex Value="0"/> <WindowIndex Value="0"/>
<TopLine Value="427"/> <TopLine Value="384"/>
<CursorPos X="9" Y="450"/> <CursorPos X="28" Y="384"/>
<UsageCount Value="40"/> <UsageCount Value="816"/>
<Loaded Value="True"/> <Loaded Value="True"/>
<LoadedDesigner Value="True"/> <LoadedDesigner Value="True"/>
</Unit1> </Unit1>
@@ -35,121 +36,149 @@
<Filename Value="edc.pas"/> <Filename Value="edc.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="edc"/> <UnitName Value="edc"/>
<UsageCount Value="40"/> <UsageCount Value="816"/>
</Unit2> </Unit2>
<Unit3> <Unit3>
<Filename Value="ecc.pas"/> <Filename Value="ecc.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="ecc"/> <UnitName Value="ecc"/>
<EditorIndex Value="1"/> <EditorIndex Value="3"/>
<WindowIndex Value="0"/> <WindowIndex Value="0"/>
<TopLine Value="13"/> <TopLine Value="13"/>
<CursorPos X="1" Y="1"/> <CursorPos X="1" Y="1"/>
<UsageCount Value="40"/> <UsageCount Value="816"/>
<Loaded Value="True"/> <Loaded Value="True"/>
</Unit3> </Unit3>
<Unit4> <Unit4>
<Filename Value="ucommon.pas"/> <Filename Value="ucommon.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="ucommon"/> <UnitName Value="ucommon"/>
<IsVisibleTab Value="True"/> <EditorIndex Value="4"/>
<EditorIndex Value="2"/>
<WindowIndex Value="0"/> <WindowIndex Value="0"/>
<TopLine Value="1"/> <TopLine Value="14"/>
<CursorPos X="35" Y="6"/> <CursorPos X="15" Y="35"/>
<UsageCount Value="40"/> <UsageCount Value="816"/>
<Loaded Value="True"/> <Loaded Value="True"/>
</Unit4> </Unit4>
<Unit5> <Unit5>
<Filename Value="utim.pas"/> <Filename Value="utim.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="utim"/> <UnitName Value="utim"/>
<EditorIndex Value="5"/> <EditorIndex Value="7"/>
<WindowIndex Value="0"/> <WindowIndex Value="0"/>
<TopLine Value="431"/> <TopLine Value="193"/>
<CursorPos X="65" Y="447"/> <CursorPos X="67" Y="195"/>
<UsageCount Value="40"/> <UsageCount Value="816"/>
<Loaded Value="True"/> <Loaded Value="True"/>
</Unit5> </Unit5>
<Unit6> <Unit6>
<Filename Value="ucdimage.pas"/> <Filename Value="ucdimage.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="ucdimage"/> <UnitName Value="ucdimage"/>
<EditorIndex Value="1"/>
<WindowIndex Value="0"/> <WindowIndex Value="0"/>
<TopLine Value="81"/> <TopLine Value="129"/>
<CursorPos X="95" Y="89"/> <CursorPos X="74" Y="143"/>
<UsageCount Value="40"/> <UsageCount Value="816"/>
<Loaded Value="True"/>
</Unit6> </Unit6>
<Unit7> <Unit7>
<Filename Value="usettings.pas"/> <Filename Value="usettings.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="usettings"/> <UnitName Value="usettings"/>
<EditorIndex Value="3"/> <EditorIndex Value="5"/>
<WindowIndex Value="0"/> <WindowIndex Value="0"/>
<TopLine Value="81"/> <TopLine Value="81"/>
<CursorPos X="55" Y="92"/> <CursorPos X="55" Y="92"/>
<UsageCount Value="40"/> <UsageCount Value="816"/>
<Loaded Value="True"/> <Loaded Value="True"/>
</Unit7> </Unit7>
<Unit8> <Unit8>
<Filename Value="uscanresult.pas"/> <Filename Value="uscanresult.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="uscanresult"/> <UnitName Value="uscanresult"/>
<EditorIndex Value="9"/> <EditorIndex Value="12"/>
<WindowIndex Value="0"/> <WindowIndex Value="0"/>
<TopLine Value="16"/> <TopLine Value="16"/>
<CursorPos X="64" Y="25"/> <CursorPos X="64" Y="25"/>
<UsageCount Value="40"/> <UsageCount Value="816"/>
<Loaded Value="True"/> <Loaded Value="True"/>
</Unit8> </Unit8>
<Unit9> <Unit9>
<Filename Value="uscanthread.pas"/> <Filename Value="uscanthread.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="uscanthread"/> <UnitName Value="uscanthread"/>
<EditorIndex Value="4"/> <EditorIndex Value="6"/>
<WindowIndex Value="0"/> <WindowIndex Value="0"/>
<TopLine Value="1"/> <TopLine Value="1"/>
<CursorPos X="53" Y="88"/> <CursorPos X="53" Y="88"/>
<UsageCount Value="40"/> <UsageCount Value="816"/>
<Loaded Value="True"/> <Loaded Value="True"/>
</Unit9> </Unit9>
<Unit10> <Unit10>
<Filename Value="ucpucount.pas"/> <Filename Value="ucpucount.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="ucpucount"/> <UnitName Value="ucpucount"/>
<UsageCount Value="40"/> <EditorIndex Value="2"/>
<WindowIndex Value="0"/>
<TopLine Value="19"/>
<CursorPos X="87" Y="34"/>
<UsageCount Value="816"/>
<Loaded Value="True"/>
</Unit10> </Unit10>
<Unit11> <Unit11>
<Filename Value="udrawtim.pas"/> <Filename Value="udrawtim.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="udrawtim"/> <UnitName Value="udrawtim"/>
<EditorIndex Value="6"/> <EditorIndex Value="8"/>
<WindowIndex Value="0"/> <WindowIndex Value="0"/>
<TopLine Value="76"/> <TopLine Value="91"/>
<CursorPos X="62" Y="41"/> <CursorPos X="36" Y="23"/>
<UsageCount Value="40"/> <UsageCount Value="816"/>
<Loaded Value="True"/> <Loaded Value="True"/>
</Unit11> </Unit11>
<Unit12> <Unit12>
<Filename Value="bgrabitmap\bgrabitmap.pas"/> <Filename Value="bgrabitmap\bgrabitmap.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="BGRABitmap"/> <UnitName Value="BGRABitmap"/>
<UsageCount Value="40"/> <UsageCount Value="816"/>
</Unit12> </Unit12>
<Unit13> <Unit13>
<Filename Value="todos.inc"/> <Filename Value="todos.inc"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<EditorIndex Value="7"/> <EditorIndex Value="10"/>
<WindowIndex Value="0"/> <WindowIndex Value="0"/>
<TopLine Value="1"/> <TopLine Value="1"/>
<CursorPos X="94" Y="2"/> <CursorPos X="31" Y="2"/>
<UsageCount Value="26"/> <UsageCount Value="802"/>
<Loaded Value="True"/> <Loaded Value="True"/>
</Unit13> </Unit13>
<Unit14>
<Filename Value="uexportimport.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="uexportimport"/>
<EditorIndex Value="9"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="26" Y="12"/>
<UsageCount Value="29"/>
<Loaded Value="True"/>
</Unit14>
</Units> </Units>
<General> <General>
<ActiveWindowIndexAtStart Value="0"/> <ActiveWindowIndexAtStart Value="0"/>
</General> </General>
</ProjectSession> </ProjectSession>
<Debugging>
<BreakPoints Count="1">
<Item1>
<Kind Value="bpkSource"/>
<WatchScope Value="wpsLocal"/>
<WatchKind Value="wpkWrite"/>
<Source Value="c:\Lazarus\fpc\2.6.2\source\packages\fcl-image\src\fpimage.inc"/>
<Line Value="350"/>
</Item1>
</BreakPoints>
</Debugging>
<EditorMacros Count="0"/> <EditorMacros Count="0"/>
</CONFIG> </CONFIG>

Binary file not shown.

2
todos.inc Normal file
View File

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

View File

@@ -29,29 +29,11 @@ type
PBytesArray = ^TBytesArray; PBytesArray = ^TBytesArray;
function ExtractJustName(const Path: string): string; function ExtractJustName(const Path: string): string;
function Min(A, B: Integer): Integer;
function Max(A, B: Integer): Integer;
implementation implementation
uses sysutils; uses sysutils;
function Min(A, B: Integer): Integer;
begin
if A < B then
Result := A
else
Result := B;
end;
function Max(A, B: Integer): Integer;
begin
if A >= B then
Result := A
else
Result := B;
end;
function ExtractJustName(const Path: string): string; function ExtractJustName(const Path: string): string;
begin begin
Result := ExtractFileName(Path); Result := ExtractFileName(Path);

View File

@@ -10,41 +10,99 @@ type
PDrawSurf = ^TBGRABitmap; PDrawSurf = ^TBGRABitmap;
PDrawGrid = ^TDrawGrid; PDrawGrid = ^TDrawGrid;
procedure TimToPNG(TIM: PTIM; CLUT_NUM: Integer; var Surf: PDrawSurf; TranspMode: Byte);
procedure Tim2Png(TIM: PTIM; CLUT_NUM: Integer; Surf: PDrawSurf; TranspMode: Byte; ForExport: Boolean);
procedure DrawClutCell(TIM: PTIM; CLUT_NUM: Integer; Grid: PDrawGrid; X, Y: Integer); procedure DrawClutCell(TIM: PTIM; CLUT_NUM: Integer; Grid: PDrawGrid; X, Y: Integer);
procedure DrawCLUT(TIM: PTIM; CLUT_NUM: Integer; Grid: PDrawGrid); procedure DrawClut(TIM: PTIM; CLUT_NUM: Integer; Grid: PDrawGrid);
procedure ClearCanvas(ACanvas: PCanvas; Rect: TRect); procedure ClearCanvas(ACanvas: PCanvas; Rect: TRect);
procedure ClearGrid(Grid: PDrawGrid); procedure ClearGrid(Grid: PDrawGrid);
implementation implementation
uses uses
ucommon, BGRABitmapTypes, Math; BGRABitmapTypes, Math, FPimage;
function PrepareCLUT(TIM: PTIM; CLUT_NUM: Integer): PCLUT_COLORS; type
PFPPalette = ^TFPPalette;
procedure AlphaForMode(C: PFPColor; TranspMode: Integer);
var var
I: Integer; BT, CT: Boolean;
begin begin
Result := nil; BT := TranspMode in [0, 1];
if (not TIMHasCLUT(TIM)) and (not(TIM^.HEAD^.bBPP in [cTIM4NC, cTIM8NC])) then CT := TranspMode in [0, 2];
Exit;
New(Result); if not (BT or CT) then
C^.alpha := $FFFF
else
begin
if (C^.red + C^.green + C^.blue) = 0 then
case (C^.alpha and 1) of
0: C^.alpha := Word(ifthen(BT, 0, $FFFF));
1: C^.alpha := $FFFF;
end
else
if CT then
case (C^.alpha and 1) of
0: C^.alpha := $FFFF;
1: C^.alpha := Word(ifthen(CT, $8080, $FFFF));
end
else
C^.alpha := $FFFF;
end;
end;
procedure PrepareClut(TIM: PTIM; CLUT_NUM: Integer; Pal: PFPPalette; TranspMode: Integer; ForExport: Boolean);
var
I, COUNT: Integer;
CC: TCLUT_COLOR;
R, G, B, A: Byte;
FC: TFPColor;
begin
if (TIM^.HEAD^.bBPP in [cTIM16NC, cTIM24NC]) then Exit;
if (TIM^.HEAD^.bBPP in [cTIM4NC, cTIM8NC]) then if (TIM^.HEAD^.bBPP in [cTIM4NC, cTIM8NC]) then
begin begin
Randomize; Randomize;
for I := 1 to $100 do COUNT := 256;
Result^[I - 1] := GetCLUTColor(TIM, CLUT_NUM, I - 1); end
else
COUNT := GetTimColorsCount(TIM);
Exit; Pal^.Clear;
for I := 1 to 256 do
begin
CC := GetCLUTColor(TIM, CLUT_NUM, I - 1);
if I <= COUNT then
begin
R := CC.R;
G := CC.G;
B := CC.B;
A := CC.STP;
end
else
begin
R := 0;
G := 0;
B := 0;
A := 1;
end; end;
for I := 1 to GetTimColorsCount(TIM) do if ForExport then
Result^[I - 1] := GetCLUTColor(TIM, CLUT_NUM, I - 1); begin
R := R + (((I - 1) and $03) shl 1) + A;
G := G + (((I - 1) and $1C) shr 2);
B := B + (((I - 1) and $E0) shr 5);
A := 255;
end;
FC := BGRAToFPColor(BGRA(R, G, B, A));
AlphaForMode(@FC, TranspMode);
Pal^.Add(FC);
end;
end; end;
function PrepareIMAGE(TIM: PTIM): PIMAGE_INDEXES; function PrepareImage(TIM: PTIM): PIMAGE_INDEXES;
var var
I, OFFSET: Integer; I, OFFSET: Integer;
RW: Word; RW: Word;
@@ -107,17 +165,15 @@ begin
ClearCanvas(@Grid^.Canvas, Grid^.CellRect(X - 1, Y - 1)); ClearCanvas(@Grid^.Canvas, Grid^.CellRect(X - 1, Y - 1));
end; end;
procedure TimToPNG(TIM: PTIM; CLUT_NUM: Integer; var Surf: PDrawSurf; TranspMode: Byte); procedure Tim2Png(TIM: PTIM; CLUT_NUM: Integer; Surf: PDrawSurf; TranspMode: Byte; ForExport: Boolean);
var var
RW, RH, CW: Word; RW, RH, CW: Word;
CLUT_DATA: PCLUT_COLORS; INDEXES: PIMAGE_INDEXES;
IMAGE_DATA: PIMAGE_INDEXES; X, Y, INDEX, IDX, COLORS: Integer;
X, Y, INDEX, IMAGE_DATA_POS: Integer; R, G, B: Byte;
R, G, B, STP, ALPHA: Byte; CC: TCLUT_COLOR;
COLOR: TCLUT_COLOR; PAL: PFPPalette;
CL: Integer; FC: TFPColor;
P: PBGRAPixel;
Transparent, SemiTransparent: boolean;
begin begin
RW := GetTimRealWidth(TIM); RW := GetTimRealWidth(TIM);
RH := GetTimHeight(TIM); RH := GetTimHeight(TIM);
@@ -125,106 +181,60 @@ begin
if (Surf^ <> nil) then Surf^.Free; if (Surf^ <> nil) then Surf^.Free;
Surf^ := TBGRABitmap.Create(RW, RH); Surf^ := TBGRABitmap.Create(RW, RH);
Surf^.UsePalette := not(TIM^.HEAD^.bBPP in [cTIM16NC, cTIM24NC]);
CLUT_DATA := PrepareCLUT(TIM, CLUT_NUM); PAL := @(Surf^.Palette);
IMAGE_DATA := PrepareIMAGE(TIM);
IMAGE_DATA_POS := 0; PrepareClut(TIM, CLUT_NUM, PAL, TranspMode, ForExport);
INDEXES := PrepareIMAGE(TIM);
Transparent := TranspMode in [0, 1]; COLORS := GetTimColorsCount(TIM);
SemiTransparent := TranspMode in [0, 2]; IDX := 0;
R := 0; R := 0;
G := 0; G := 0;
B := 0; B := 0;
STP := 0;
for Y := 1 to RH do for Y := 1 to RH do
begin
P := Surf^.ScanLine[Y - 1];
for X := 1 to RW do for X := 1 to RW do
begin begin
case TIM^.HEAD^.bBPP of case TIM^.HEAD^.bBPP of
cTIM4C, cTIM4NC, cTIM8C, cTIM8NC: cTIM4C, cTIM4NC, cTIM8C, cTIM8NC: Surf^.Pixels[X - 1, Y - 1] := INDEXES^[IDX] mod COLORS;
begin
INDEX := IMAGE_DATA^[IMAGE_DATA_POS];
R := CLUT_DATA^[INDEX].R;
G := CLUT_DATA^[INDEX].G;
B := CLUT_DATA^[INDEX].B;
STP := CLUT_DATA^[INDEX].STP;
end;
cTIM16C, cTIM16NC, cTIMMix: cTIM16C, cTIM16NC, cTIMMix:
begin begin
Move(IMAGE_DATA^[IMAGE_DATA_POS], CW, 2); Move(INDEXES^[IDX], CW, 2);
COLOR := ConvertTIMColor(CW); CC := ConvertTIMColor(CW);
R := COLOR.R; FC := BGRAToFPColor(BGRA(CC.R + CC.STP, CC.G, CC.B));
G := COLOR.G; if (not ForExport) then AlphaForMode(@FC, TranspMode);
B := COLOR.B;
STP := COLOR.STP; Surf^.Colors[X - 1, Y - 1] := FC;
end; end;
cTIM24C, cTIM24NC: cTIM24C, cTIM24NC:
begin begin
CL := IMAGE_DATA^[IMAGE_DATA_POS]; INDEX := INDEXES^[IDX];
R := (CL and $FF); R := (INDEX and $FF);
G := ((CL and $FF00) shr 8); G := ((INDEX and $FF00) shr 8);
B := ((CL and $FF0000) shr 16); B := ((INDEX and $FF0000) shr 16);
STP := 0; Surf^.Colors[X - 1, Y - 1] := BGRAToFPColor(BGRA(R, G, B, 255));
end; end;
else else
Break; Break;
end; end;
Inc(IDX);
if (TIM^.HEAD^.bBPP in cTIM24) or (not(Transparent or SemiTransparent))
then
ALPHA := 255
else
begin
if (R + G + B) = 0 then
ALPHA := 0
else
begin
if (STP = 0) then
ALPHA := 255
else
ALPHA := 128;
if (not SemiTransparent) and (ALPHA = 128) then
ALPHA := 255;
end;
end; end;
if ALPHA = 0 then Dispose(INDEXES);
begin
B := 0;
G := 0;
R := 0;
end;
P^.alpha:=ALPHA;
P^.blue := B;
P^.green := G;
P^.red := R;
Inc(P);
Inc(IMAGE_DATA_POS);
end;
end;
Surf^.InvalidateBitmap;
Dispose(CLUT_DATA);
Dispose(IMAGE_DATA);
end; end;
procedure DrawClutCell(TIM: PTIM; CLUT_NUM: Integer; Grid: PDrawGrid; procedure DrawClutCell(TIM: PTIM; CLUT_NUM: Integer; Grid: PDrawGrid; X, Y: Integer);
X, Y: Integer);
var var
CLUT_COLOR: PCLUT_COLOR; CLUT_COLOR: PCLUT_COLOR;
R, G, B, STP, ALPHA: Byte; R, G, B, STP: Byte;
Rect: TRect; Rect: TRect;
COLS, Colors: Integer; COLS, Colors: Integer;
FC: TFPColor;
begin begin
Colors := GetTimColorsCount(TIM); Colors := GetTimColorsCount(TIM);
COLS := Min(Colors, 32); COLS := Min(Colors, 32);
@@ -248,20 +258,13 @@ begin
Grid^.Canvas.FillRect(Rect); Grid^.Canvas.FillRect(Rect);
if (R + G + B) = 0 then FC := BGRAToFPColor(BGRA(R, G, B, STP));
ALPHA := 0 AlphaForMode(@FC, 0);
else
begin
if STP = 0 then
ALPHA := 255
else
ALPHA := 128;
end;
if ALPHA in [0, 128] then if (FC.alpha = 0) or (FC.alpha = $8080) then
begin begin
Grid^.Canvas.Brush.COLOR := clWhite; Grid^.Canvas.Brush.COLOR := clWhite;
if ALPHA = 0 then if FC.ALPHA = 0 then
Rect.Bottom := Rect.Top + ((Rect.Bottom - Rect.Top) div 2) Rect.Bottom := Rect.Top + ((Rect.Bottom - Rect.Top) div 2)
else else
Rect.Right := Rect.Left + ((Rect.Right - Rect.Left) div 2); Rect.Right := Rect.Left + ((Rect.Right - Rect.Left) div 2);

27
uexportimport.pas Normal file
View File

@@ -0,0 +1,27 @@
unit uexportimport;
interface
uses FPWritePNG, zstream, udrawtim;
procedure SaveImage(Surf: PDrawSurf; Indexed: Boolean; const FileName: string; PngWriter: TFPWriterPNG);
function CreatePngWriter(ForExport: Boolean): TFPWriterPNG;
implementation
function CreatePngWriter(ForExport: Boolean): TFPWriterPNG;
begin
Result := TFPWriterPNG.Create;
Result.CompressionLevel := clnone;
Result.WordSized := False;
Result.UseAlpha := (not ForExport);
end;
procedure SaveImage(Surf: PDrawSurf; Indexed: Boolean; const FileName: string; PngWriter: TFPWriterPNG);
begin
PngWriter.Indexed := Indexed;
Surf^.SaveToFileUTF8(FileName, PngWriter);
end;
end.

View File

@@ -494,7 +494,7 @@ object frmMain: TfrmMain
OnCreate = FormCreate OnCreate = FormCreate
OnDropFiles = FormDropFiles OnDropFiles = FormDropFiles
Position = poScreenCenter Position = poScreenCenter
LCLVersion = '1.3' LCLVersion = '1.2.0.3'
object pnlStatus: TPanel object pnlStatus: TPanel
Left = 0 Left = 0
Height = 30 Height = 30
@@ -741,12 +741,12 @@ object frmMain: TfrmMain
end end
object pnlClut: TPanel object pnlClut: TPanel
Left = 1 Left = 1
Height = 116 Height = 129
Top = 352 Top = 339
Width = 520 Width = 520
Align = alBottom Align = alBottom
BevelOuter = bvLowered BevelOuter = bvLowered
ClientHeight = 116 ClientHeight = 129
ClientWidth = 520 ClientWidth = 520
Color = clBtnFace Color = clBtnFace
ParentColor = False ParentColor = False
@@ -754,7 +754,7 @@ object frmMain: TfrmMain
Visible = False Visible = False
object grdClut: TDrawGrid object grdClut: TDrawGrid
Left = 1 Left = 1
Height = 114 Height = 127
Top = 1 Top = 1
Width = 518 Width = 518
Align = alClient Align = alClient
@@ -773,14 +773,13 @@ object frmMain: TfrmMain
TitleFont.Color = clWindowText TitleFont.Color = clWindowText
TitleFont.Height = -11 TitleFont.Height = -11
TitleFont.Name = 'Tahoma' TitleFont.Name = 'Tahoma'
UseXORFeatures = True
OnDblClick = grdClutDblClick OnDblClick = grdClutDblClick
OnDrawCell = grdClutDrawCell OnDrawCell = grdClutDrawCell
end end
end end
object imgTim: TImage object imgTim: TImage
Left = 1 Left = 1
Height = 351 Height = 338
Top = 1 Top = 1
Width = 520 Width = 520
AntialiasingMode = amOff AntialiasingMode = amOff

View File

@@ -168,6 +168,7 @@ type
procedure ShowTim; procedure ShowTim;
procedure ShowTimInfo(ShowInfo: Boolean); procedure ShowTimInfo(ShowInfo: Boolean);
procedure RemoveGridSelection; procedure RemoveGridSelection;
procedure Update(Tim, Clut, ClutInfo: Boolean);
public public
{ public declarations } { public declarations }
ScanResults: TScanResultList; //List of finished scan results ScanResults: TScanResultList; //List of finished scan results
@@ -180,7 +181,7 @@ var
implementation implementation
uses ucdimage, ucpucount, lcltype, ucommon, LCLIntf uses ucdimage, ucpucount, lcltype, ucommon, LCLIntf, uexportimport, FPWritePNG
{$IFDEF windows} {$IFDEF windows}
,registry ,registry
@@ -226,35 +227,44 @@ end;
procedure TfrmMain.actStretchExecute(Sender: TObject); procedure TfrmMain.actStretchExecute(Sender: TObject);
begin begin
Settings.StretchMode := actStretch.Checked; Settings.StretchMode := actStretch.Checked;
DrawSelTim; Update(True, False, False);
end; end;
procedure TfrmMain.actTim2PngExecute(Sender: TObject); procedure TfrmMain.actTim2PngExecute(Sender: TObject);
var
TIM: PTIM;
Writer: TFPWriterPNG;
begin begin
dlgSavePNG.FileName := FormatPngName(SelectedScanResult.ScanFile, SelectedTimIdx, SelectedTimInfo.BitMode, cbbCLUT.ItemIndex); TIM := SelectedTim;
if TIM = nil then Exit;
dlgSavePNG.FileName := FormatPngName(SelectedScanResult.ScanFile, TIM^.dwTimNumber, SelectedTimInfo.BitMode, cbbCLUT.ItemIndex);
if not dlgSavePNG.Execute then Exit; if not dlgSavePNG.Execute then Exit;
Surf^.SaveToFile(UTF8ToSys(dlgSavePNG.FileName)); Writer := CreatePngWriter(False);
SaveImage(Surf, TIMisIndexed(TIM), dlgSavePNG.FileName, Writer);
Writer.Free;
FreeTIM(TIM);
{$IFDEF Linux}FpChmod(dlgSavePNG.FileName, &777){$IFEND} {$IFDEF Linux}FpChmod(dlgSavePNG.FileName, &777){$IFEND}
end; end;
procedure TfrmMain.btnShowClutClick(Sender: TObject); procedure TfrmMain.btnShowClutClick(Sender: TObject);
begin begin
pnlClut.Visible := not pnlClut.Visible; pnlClut.Visible := not pnlClut.Visible;
DrawSelClut; Update(False, True, False);
actReturnFocus.Execute; actReturnFocus.Execute;
end; end;
procedure TfrmMain.cbbBitModeChange(Sender: TObject); procedure TfrmMain.cbbBitModeChange(Sender: TObject);
begin begin
DrawSelTim; Update(True, False, False);
end; end;
procedure TfrmMain.cbbTranspModeChange(Sender: TObject); procedure TfrmMain.cbbTranspModeChange(Sender: TObject);
begin begin
Settings.TranspMode := cbbTranspMode.ItemIndex; Settings.TranspMode := cbbTranspMode.ItemIndex;
DrawSelTim; Update(True, False, False);
end; end;
procedure TfrmMain.actChangeFileExecute(Sender: TObject); procedure TfrmMain.actChangeFileExecute(Sender: TObject);
@@ -266,6 +276,8 @@ begin
lvList.ItemIndex := 0; lvList.ItemIndex := 0;
lvList.Items[0].Focused := True; lvList.Items[0].Focused := True;
lvList.Items[0].Selected := True; lvList.Items[0].Selected := True;
ShowTim;
end; end;
procedure TfrmMain.actAboutExecute(Sender: TObject); procedure TfrmMain.actAboutExecute(Sender: TObject);
@@ -313,8 +325,7 @@ end;
procedure TfrmMain.actChangeClutIdxExecute(Sender: TObject); procedure TfrmMain.actChangeClutIdxExecute(Sender: TObject);
begin begin
DrawSelTim; Update(True, True, False);
DrawSelClut;
end; end;
procedure TfrmMain.actCloseFileExecute(Sender: TObject); procedure TfrmMain.actCloseFileExecute(Sender: TObject);
@@ -326,9 +337,7 @@ begin
ShowTimInfo(False); ShowTimInfo(False);
SetTimsListCount(0); SetTimsListCount(0);
UpdateCLUTInfo; Update(True, True, True);
DrawSelTim;
DrawSelClut;
cbbFiles.Items.Delete(cbbFiles.ItemIndex); cbbFiles.Items.Delete(cbbFiles.ItemIndex);
@@ -362,6 +371,7 @@ var
ScanTim: TTimInfo; ScanTim: TTimInfo;
TIM: PTIM; TIM: PTIM;
Surf_: PDrawSurf; Surf_: PDrawSurf;
Writer: TFPWriterPNG;
begin begin
lblStatus.Caption := sStatusBarPngsExtracting; lblStatus.Caption := sStatusBarPngsExtracting;
@@ -371,6 +381,8 @@ begin
New(Surf_); New(Surf_);
Surf_^ := nil; Surf_^ := nil;
Writer := CreatePngWriter(False);
pbProgress.Position := 0; pbProgress.Position := 0;
pbProgress.Max := SelectedScanResult.Count; pbProgress.Max := SelectedScanResult.Count;
for I := 1 to SelectedScanResult.Count do for I := 1 to SelectedScanResult.Count do
@@ -386,10 +398,10 @@ begin
CreateDirUTF8(Path); CreateDirUTF8(Path);
TIM := LoadTimFromFile(FName, OFFSET, IsImage, SIZE); TIM := LoadTimFromFile(FName, OFFSET, IsImage, SIZE);
TimToPNG(TIM, cbbCLUT.ItemIndex, Surf_, cbbTranspMode.ItemIndex); Tim2Png(TIM, cbbCLUT.ItemIndex, Surf_, cbbTranspMode.ItemIndex, False);
Path := Path + FormatPngName(FName, I - 1, BIT_MODE, 0); Path := Path + FormatPngName(FName, I - 1, BIT_MODE, 0);
Surf_^.SaveToFile(UTF8ToSys(Path)); SaveImage(Surf_, TIMisIndexed(TIM), Path, Writer);
{$IFDEF Linux}FpChmod(Path, &777){$IFEND} {$IFDEF Linux}FpChmod(Path, &777){$IFEND}
Surf_^.Free; Surf_^.Free;
Surf_^ := nil; Surf_^ := nil;
@@ -400,6 +412,7 @@ begin
Application.ProcessMessages; Application.ProcessMessages;
end; end;
Dispose(Surf_); Dispose(Surf_);
Writer.Free;
lblStatus.Caption := sStatusBarExtracted; lblStatus.Caption := sStatusBarExtracted;
pbProgress.Position := 0; pbProgress.Position := 0;
end; end;
@@ -602,9 +615,7 @@ begin
FreeTIM(TIM); FreeTIM(TIM);
DrawSelTim; Update(True, True, False);
DrawSelClut;
end; end;
procedure TfrmMain.grdClutDrawCell(Sender: TObject; aCol, aRow: Integer; procedure TfrmMain.grdClutDrawCell(Sender: TObject; aCol, aRow: Integer;
@@ -833,12 +844,10 @@ begin
if TIM = nil then Exit; if TIM = nil then Exit;
CLUTS := GetTIMClutsCount(TIM); CLUTS := GetTIMClutsCount(TIM);
cbbCLUT.Items.Clear;
cbbCLUT.Items.BeginUpdate; cbbCLUT.Items.BeginUpdate;
for I := 0 to cbbCLUT.Items.Count -1 do for I := 1 to CLUTS do
cbbCLUT.Items[i] := Format('CLUT [%.2d/%.2d]', [I + 1, CLUTS]);
for I := cbbCLUT.Items.Count + 1 to CLUTS do
cbbCLUT.Items.Add(Format('CLUT [%.2d/%.2d]', [I, CLUTS])); cbbCLUT.Items.Add(Format('CLUT [%.2d/%.2d]', [I, CLUTS]));
cbbCLUT.Items.EndUpdate; cbbCLUT.Items.EndUpdate;
@@ -873,7 +882,7 @@ begin
Index := cbbCLUT.ItemIndex; Index := cbbCLUT.ItemIndex;
TimToPNG(TIM, Index, Surf, cbbTranspMode.ItemIndex); Tim2Png(TIM, Index, Surf, cbbTranspMode.ItemIndex, False);
imgTim.Picture.Bitmap := TBitmap.Create; imgTim.Picture.Bitmap := TBitmap.Create;
imgTim.Picture.Bitmap := Surf^.Bitmap; imgTim.Picture.Bitmap := Surf^.Bitmap;
FreeTIM(TIM); FreeTIM(TIM);
@@ -937,9 +946,7 @@ begin
{ TODO : Reset bitmode or not? } { TODO : Reset bitmode or not? }
//cbbBitMode.ItemIndex := 0; //cbbBitMode.ItemIndex := 0;
UpdateCLUTInfo; Update(True, True, True);
DrawSelTim;
DrawSelClut;
ShowTimInfo(True); ShowTimInfo(True);
@@ -1000,5 +1007,12 @@ begin
grdClut.Selection := hGrid; grdClut.Selection := hGrid;
end; end;
procedure TfrmMain.Update(Tim, Clut, ClutInfo: Boolean);
begin
if ClutInfo then UpdateCLUTInfo;
if Tim then DrawSelTim;
if Clut then DrawSelClut;
end;
end. end.

View File

@@ -104,6 +104,7 @@ type
PTIM = ^TTIM; PTIM = ^TTIM;
function TIMHasCLUT(TIM: PTIM): Boolean; function TIMHasCLUT(TIM: PTIM): Boolean;
function TIMisIndexed(TIM: PTIM): Boolean;
function GetTIMCLUTSize(TIM: PTIM): Integer; function GetTIMCLUTSize(TIM: PTIM): Integer;
function GetTIMSize(TIM: PTIM): Integer; function GetTIMSize(TIM: PTIM): Integer;
function GetTimWidth(TIM: PTIM): word; function GetTimWidth(TIM: PTIM): word;
@@ -189,6 +190,11 @@ begin
Result := TIM^.IMAGE^.wHeight; Result := TIM^.IMAGE^.wHeight;
end; end;
function TIMisIndexed(TIM: PTIM): Boolean;
begin
Result := TIM^.HEAD^.bBPP in [cTIM4C, cTIM4NC, cTIM8C, cTIM8NC];
end;
function GetTIMCLUTSize(TIM: PTIM): Integer; function GetTIMCLUTSize(TIM: PTIM): Integer;
begin begin
Result := 0; Result := 0;